summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/utils/esm
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /shared/logger/node_modules/@sentry/utils/esm
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/utils/esm')
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/baggage.js145
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/browser.js152
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/buildPolyfills/_optionalChain.js59
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/clientreport.js25
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/dsn.js126
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/env.js34
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/envelope.js232
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/error.js17
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/instrument.js631
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/is.js179
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/logger.js83
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/memo.js45
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/misc.js197
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/node.js66
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/normalize.js263
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/object.js279
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/promisebuffer.js102
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/ratelimit.js97
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/severity.js36
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/stacktrace.js136
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/string.js132
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/supports.js161
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/syncpromise.js191
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/time.js183
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/tracing.js39
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/url.js72
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/vendor/supportsHistory.js29
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/worldwide.js70
28 files changed, 3781 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/utils/esm/baggage.js b/shared/logger/node_modules/@sentry/utils/esm/baggage.js
new file mode 100644
index 0000000..88297b4
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/baggage.js
@@ -0,0 +1,145 @@
+import { isString } from './is.js';
+import { logger } from './logger.js';
+
+const BAGGAGE_HEADER_NAME = 'baggage';
+
+const SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';
+
+const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;
+
+/**
+ * Max length of a serialized baggage string
+ *
+ * https://www.w3.org/TR/baggage/#limits
+ */
+const MAX_BAGGAGE_STRING_LENGTH = 8192;
+
+/**
+ * Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the "sentry-" prefixed values
+ * from it.
+ *
+ * @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.
+ * @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.
+ */
+function baggageHeaderToDynamicSamplingContext(
+ // Very liberal definition of what any incoming header might look like
+ baggageHeader,
+) {
+ if (!isString(baggageHeader) && !Array.isArray(baggageHeader)) {
+ return undefined;
+ }
+
+ // Intermediary object to store baggage key value pairs of incoming baggage headers on.
+ // It is later used to read Sentry-DSC-values from.
+ let baggageObject = {};
+
+ if (Array.isArray(baggageHeader)) {
+ // Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it
+ baggageObject = baggageHeader.reduce((acc, curr) => {
+ const currBaggageObject = baggageHeaderToObject(curr);
+ return {
+ ...acc,
+ ...currBaggageObject,
+ };
+ }, {});
+ } else {
+ // Return undefined if baggage header is an empty string (technically an empty baggage header is not spec conform but
+ // this is how we choose to handle it)
+ if (!baggageHeader) {
+ return undefined;
+ }
+
+ baggageObject = baggageHeaderToObject(baggageHeader);
+ }
+
+ // Read all "sentry-" prefixed values out of the baggage object and put it onto a dynamic sampling context object.
+ const dynamicSamplingContext = Object.entries(baggageObject).reduce((acc, [key, value]) => {
+ if (key.match(SENTRY_BAGGAGE_KEY_PREFIX_REGEX)) {
+ const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);
+ acc[nonPrefixedKey] = value;
+ }
+ return acc;
+ }, {});
+
+ // Only return a dynamic sampling context object if there are keys in it.
+ // A keyless object means there were no sentry values on the header, which means that there is no DSC.
+ if (Object.keys(dynamicSamplingContext).length > 0) {
+ return dynamicSamplingContext ;
+ } else {
+ return undefined;
+ }
+}
+
+/**
+ * Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with "sentry-".
+ *
+ * @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility
+ * with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is
+ * `undefined` the function will return `undefined`.
+ * @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`
+ * was `undefined`, or if `dynamicSamplingContext` didn't contain any values.
+ */
+function dynamicSamplingContextToSentryBaggageHeader(
+ // this also takes undefined for convenience and bundle size in other places
+ dynamicSamplingContext,
+) {
+ // Prefix all DSC keys with "sentry-" and put them into a new object
+ const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce(
+ (acc, [dscKey, dscValue]) => {
+ if (dscValue) {
+ acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;
+ }
+ return acc;
+ },
+ {},
+ );
+
+ return objectToBaggageHeader(sentryPrefixedDSC);
+}
+
+/**
+ * Will parse a baggage header, which is a simple key-value map, into a flat object.
+ *
+ * @param baggageHeader The baggage header to parse.
+ * @returns a flat object containing all the key-value pairs from `baggageHeader`.
+ */
+function baggageHeaderToObject(baggageHeader) {
+ return baggageHeader
+ .split(',')
+ .map(baggageEntry => baggageEntry.split('=').map(keyOrValue => decodeURIComponent(keyOrValue.trim())))
+ .reduce((acc, [key, value]) => {
+ acc[key] = value;
+ return acc;
+ }, {});
+}
+
+/**
+ * Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.
+ *
+ * @param object The object to turn into a baggage header.
+ * @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header
+ * is not spec compliant.
+ */
+function objectToBaggageHeader(object) {
+ if (Object.keys(object).length === 0) {
+ // An empty baggage header is not spec compliant: We return undefined.
+ return undefined;
+ }
+
+ return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {
+ const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;
+ const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;
+ if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn(
+ `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,
+ );
+ return baggageHeader;
+ } else {
+ return newBaggageHeader;
+ }
+ }, '');
+}
+
+export { BAGGAGE_HEADER_NAME, MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader };
+//# sourceMappingURL=baggage.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/browser.js b/shared/logger/node_modules/@sentry/utils/esm/browser.js
new file mode 100644
index 0000000..aef06de
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/browser.js
@@ -0,0 +1,152 @@
+import { isString } from './is.js';
+import { getGlobalObject } from './worldwide.js';
+
+// eslint-disable-next-line deprecation/deprecation
+const WINDOW = getGlobalObject();
+
+const DEFAULT_MAX_STRING_LENGTH = 80;
+
+/**
+ * Given a child DOM element, returns a query-selector statement describing that
+ * and its ancestors
+ * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
+ * @returns generated DOM path
+ */
+function htmlTreeAsString(
+ elem,
+ options = {},
+) {
+
+ // try/catch both:
+ // - accessing event.target (see getsentry/raven-js#838, #768)
+ // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
+ // - can throw an exception in some circumstances.
+ try {
+ let currentElem = elem ;
+ const MAX_TRAVERSE_HEIGHT = 5;
+ const out = [];
+ let height = 0;
+ let len = 0;
+ const separator = ' > ';
+ const sepLength = separator.length;
+ let nextStr;
+ const keyAttrs = Array.isArray(options) ? options : options.keyAttrs;
+ const maxStringLength = (!Array.isArray(options) && options.maxStringLength) || DEFAULT_MAX_STRING_LENGTH;
+
+ while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {
+ nextStr = _htmlElementAsString(currentElem, keyAttrs);
+ // bail out if
+ // - nextStr is the 'html' element
+ // - the length of the string that would be created exceeds maxStringLength
+ // (ignore this limit if we are on the first iteration)
+ if (nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= maxStringLength)) {
+ break;
+ }
+
+ out.push(nextStr);
+
+ len += nextStr.length;
+ currentElem = currentElem.parentNode;
+ }
+
+ return out.reverse().join(separator);
+ } catch (_oO) {
+ return '<unknown>';
+ }
+}
+
+/**
+ * Returns a simple, query-selector representation of a DOM element
+ * e.g. [HTMLElement] => input#foo.btn[name=baz]
+ * @returns generated DOM path
+ */
+function _htmlElementAsString(el, keyAttrs) {
+ const elem = el
+
+;
+
+ const out = [];
+ let className;
+ let classes;
+ let key;
+ let attr;
+ let i;
+
+ if (!elem || !elem.tagName) {
+ return '';
+ }
+
+ out.push(elem.tagName.toLowerCase());
+
+ // Pairs of attribute keys defined in `serializeAttribute` and their values on element.
+ const keyAttrPairs =
+ keyAttrs && keyAttrs.length
+ ? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])
+ : null;
+
+ if (keyAttrPairs && keyAttrPairs.length) {
+ keyAttrPairs.forEach(keyAttrPair => {
+ out.push(`[${keyAttrPair[0]}="${keyAttrPair[1]}"]`);
+ });
+ } else {
+ if (elem.id) {
+ out.push(`#${elem.id}`);
+ }
+
+ // eslint-disable-next-line prefer-const
+ className = elem.className;
+ if (className && isString(className)) {
+ classes = className.split(/\s+/);
+ for (i = 0; i < classes.length; i++) {
+ out.push(`.${classes[i]}`);
+ }
+ }
+ }
+ const allowedAttrs = ['aria-label', 'type', 'name', 'title', 'alt'];
+ for (i = 0; i < allowedAttrs.length; i++) {
+ key = allowedAttrs[i];
+ attr = elem.getAttribute(key);
+ if (attr) {
+ out.push(`[${key}="${attr}"]`);
+ }
+ }
+ return out.join('');
+}
+
+/**
+ * A safe form of location.href
+ */
+function getLocationHref() {
+ try {
+ return WINDOW.document.location.href;
+ } catch (oO) {
+ return '';
+ }
+}
+
+/**
+ * Gets a DOM element by using document.querySelector.
+ *
+ * This wrapper will first check for the existance of the function before
+ * actually calling it so that we don't have to take care of this check,
+ * every time we want to access the DOM.
+ *
+ * Reason: DOM/querySelector is not available in all environments.
+ *
+ * We have to cast to any because utils can be consumed by a variety of environments,
+ * and we don't want to break TS users. If you know what element will be selected by
+ * `document.querySelector`, specify it as part of the generic call. For example,
+ * `const element = getDomElement<Element>('selector');`
+ *
+ * @param selector the selector string passed on to document.querySelector
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function getDomElement(selector) {
+ if (WINDOW.document && WINDOW.document.querySelector) {
+ return WINDOW.document.querySelector(selector) ;
+ }
+ return null;
+}
+
+export { getDomElement, getLocationHref, htmlTreeAsString };
+//# sourceMappingURL=browser.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/buildPolyfills/_optionalChain.js b/shared/logger/node_modules/@sentry/utils/esm/buildPolyfills/_optionalChain.js
new file mode 100644
index 0000000..6b4f012
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/buildPolyfills/_optionalChain.js
@@ -0,0 +1,59 @@
+/**
+ * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,
+ * descriptors, and functions.
+ *
+ * Adapted from Sucrase (https://github.com/alangpierce/sucrase)
+ * See https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15
+ *
+ * @param ops Array result of expression conversion
+ * @returns The value of the expression
+ */
+function _optionalChain(ops) {
+ let lastAccessLHS = undefined;
+ let value = ops[0];
+ let i = 1;
+ while (i < ops.length) {
+ const op = ops[i] ;
+ const fn = ops[i + 1] ;
+ i += 2;
+ // by checking for loose equality to `null`, we catch both `null` and `undefined`
+ if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
+ // really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it
+ return;
+ }
+ if (op === 'access' || op === 'optionalAccess') {
+ lastAccessLHS = value;
+ value = fn(value);
+ } else if (op === 'call' || op === 'optionalCall') {
+ value = fn((...args) => (value ).call(lastAccessLHS, ...args));
+ lastAccessLHS = undefined;
+ }
+ }
+ return value;
+}
+
+// Sucrase version
+// function _optionalChain(ops) {
+// let lastAccessLHS = undefined;
+// let value = ops[0];
+// let i = 1;
+// while (i < ops.length) {
+// const op = ops[i];
+// const fn = ops[i + 1];
+// i += 2;
+// if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
+// return undefined;
+// }
+// if (op === 'access' || op === 'optionalAccess') {
+// lastAccessLHS = value;
+// value = fn(value);
+// } else if (op === 'call' || op === 'optionalCall') {
+// value = fn((...args) => value.call(lastAccessLHS, ...args));
+// lastAccessLHS = undefined;
+// }
+// }
+// return value;
+// }
+
+export { _optionalChain };
+//# sourceMappingURL=_optionalChain.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/clientreport.js b/shared/logger/node_modules/@sentry/utils/esm/clientreport.js
new file mode 100644
index 0000000..22c1c30
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/clientreport.js
@@ -0,0 +1,25 @@
+import { createEnvelope } from './envelope.js';
+import { dateTimestampInSeconds } from './time.js';
+
+/**
+ * Creates client report envelope
+ * @param discarded_events An array of discard events
+ * @param dsn A DSN that can be set on the header. Optional.
+ */
+function createClientReportEnvelope(
+ discarded_events,
+ dsn,
+ timestamp,
+) {
+ const clientReportItem = [
+ { type: 'client_report' },
+ {
+ timestamp: timestamp || dateTimestampInSeconds(),
+ discarded_events,
+ },
+ ];
+ return createEnvelope(dsn ? { dsn } : {}, [clientReportItem]);
+}
+
+export { createClientReportEnvelope };
+//# sourceMappingURL=clientreport.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/dsn.js b/shared/logger/node_modules/@sentry/utils/esm/dsn.js
new file mode 100644
index 0000000..4fe84be
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/dsn.js
@@ -0,0 +1,126 @@
+import { logger } from './logger.js';
+
+/** Regular expression used to parse a Dsn. */
+const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)([\w.-]+)(?::(\d+))?\/(.+)/;
+
+function isValidProtocol(protocol) {
+ return protocol === 'http' || protocol === 'https';
+}
+
+/**
+ * Renders the string representation of this Dsn.
+ *
+ * By default, this will render the public representation without the password
+ * component. To get the deprecated private representation, set `withPassword`
+ * to true.
+ *
+ * @param withPassword When set to true, the password will be included.
+ */
+function dsnToString(dsn, withPassword = false) {
+ const { host, path, pass, port, projectId, protocol, publicKey } = dsn;
+ return (
+ `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
+ `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`
+ );
+}
+
+/**
+ * Parses a Dsn from a given string.
+ *
+ * @param str A Dsn as string
+ * @returns Dsn as DsnComponents or undefined if @param str is not a valid DSN string
+ */
+function dsnFromString(str) {
+ const match = DSN_REGEX.exec(str);
+
+ if (!match) {
+ // This should be logged to the console
+ // eslint-disable-next-line no-console
+ console.error(`Invalid Sentry Dsn: ${str}`);
+ return undefined;
+ }
+
+ const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
+ let path = '';
+ let projectId = lastPath;
+
+ const split = projectId.split('/');
+ if (split.length > 1) {
+ path = split.slice(0, -1).join('/');
+ projectId = split.pop() ;
+ }
+
+ if (projectId) {
+ const projectMatch = projectId.match(/^\d+/);
+ if (projectMatch) {
+ projectId = projectMatch[0];
+ }
+ }
+
+ return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol , publicKey });
+}
+
+function dsnFromComponents(components) {
+ return {
+ protocol: components.protocol,
+ publicKey: components.publicKey || '',
+ pass: components.pass || '',
+ host: components.host,
+ port: components.port || '',
+ path: components.path || '',
+ projectId: components.projectId,
+ };
+}
+
+function validateDsn(dsn) {
+ if (!(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
+ return true;
+ }
+
+ const { port, projectId, protocol } = dsn;
+
+ const requiredComponents = ['protocol', 'publicKey', 'host', 'projectId'];
+ const hasMissingRequiredComponent = requiredComponents.find(component => {
+ if (!dsn[component]) {
+ logger.error(`Invalid Sentry Dsn: ${component} missing`);
+ return true;
+ }
+ return false;
+ });
+
+ if (hasMissingRequiredComponent) {
+ return false;
+ }
+
+ if (!projectId.match(/^\d+$/)) {
+ logger.error(`Invalid Sentry Dsn: Invalid projectId ${projectId}`);
+ return false;
+ }
+
+ if (!isValidProtocol(protocol)) {
+ logger.error(`Invalid Sentry Dsn: Invalid protocol ${protocol}`);
+ return false;
+ }
+
+ if (port && isNaN(parseInt(port, 10))) {
+ logger.error(`Invalid Sentry Dsn: Invalid port ${port}`);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Creates a valid Sentry Dsn object, identifying a Sentry instance and project.
+ * @returns a valid DsnComponents object or `undefined` if @param from is an invalid DSN source
+ */
+function makeDsn(from) {
+ const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
+ if (!components || !validateDsn(components)) {
+ return undefined;
+ }
+ return components;
+}
+
+export { dsnFromString, dsnToString, makeDsn };
+//# sourceMappingURL=dsn.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/env.js b/shared/logger/node_modules/@sentry/utils/esm/env.js
new file mode 100644
index 0000000..dacd2f1
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/env.js
@@ -0,0 +1,34 @@
+/*
+ * This module exists for optimizations in the build process through rollup and terser. We define some global
+ * constants, which can be overridden during build. By guarding certain pieces of code with functions that return these
+ * constants, we can control whether or not they appear in the final bundle. (Any code guarded by a false condition will
+ * never run, and will hence be dropped during treeshaking.) The two primary uses for this are stripping out calls to
+ * `logger` and preventing node-related code from appearing in browser bundles.
+ *
+ * Attention:
+ * This file should not be used to define constants/flags that are intended to be used for tree-shaking conducted by
+ * users. These flags should live in their respective packages, as we identified user tooling (specifically webpack)
+ * having issues tree-shaking these constants across package boundaries.
+ * An example for this is the __SENTRY_DEBUG__ constant. It is declared in each package individually because we want
+ * users to be able to shake away expressions that it guards.
+ */
+
+/**
+ * Figures out if we're building a browser bundle.
+ *
+ * @returns true if this is a browser bundle build.
+ */
+function isBrowserBundle() {
+ return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;
+}
+
+/**
+ * Get source of SDK.
+ */
+function getSDKSource() {
+ // @ts-ignore "npm" is injected by rollup during build process
+ return "npm";
+}
+
+export { getSDKSource, isBrowserBundle };
+//# sourceMappingURL=env.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/envelope.js b/shared/logger/node_modules/@sentry/utils/esm/envelope.js
new file mode 100644
index 0000000..a2cc042
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/envelope.js
@@ -0,0 +1,232 @@
+import { dsnToString } from './dsn.js';
+import { normalize } from './normalize.js';
+import { dropUndefinedKeys } from './object.js';
+
+/**
+ * Creates an envelope.
+ * Make sure to always explicitly provide the generic to this function
+ * so that the envelope types resolve correctly.
+ */
+function createEnvelope(headers, items = []) {
+ return [headers, items] ;
+}
+
+/**
+ * Add an item to an envelope.
+ * Make sure to always explicitly provide the generic to this function
+ * so that the envelope types resolve correctly.
+ */
+function addItemToEnvelope(envelope, newItem) {
+ const [headers, items] = envelope;
+ return [headers, [...items, newItem]] ;
+}
+
+/**
+ * Convenience function to loop through the items and item types of an envelope.
+ * (This function was mostly created because working with envelope types is painful at the moment)
+ *
+ * If the callback returns true, the rest of the items will be skipped.
+ */
+function forEachEnvelopeItem(
+ envelope,
+ callback,
+) {
+ const envelopeItems = envelope[1];
+
+ for (const envelopeItem of envelopeItems) {
+ const envelopeItemType = envelopeItem[0].type;
+ const result = callback(envelopeItem, envelopeItemType);
+
+ if (result) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Returns true if the envelope contains any of the given envelope item types
+ */
+function envelopeContainsItemType(envelope, types) {
+ return forEachEnvelopeItem(envelope, (_, type) => types.includes(type));
+}
+
+/**
+ * Encode a string to UTF8.
+ */
+function encodeUTF8(input, textEncoder) {
+ const utf8 = textEncoder || new TextEncoder();
+ return utf8.encode(input);
+}
+
+/**
+ * Serializes an envelope.
+ */
+function serializeEnvelope(envelope, textEncoder) {
+ const [envHeaders, items] = envelope;
+
+ // Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data
+ let parts = JSON.stringify(envHeaders);
+
+ function append(next) {
+ if (typeof parts === 'string') {
+ parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts, textEncoder), next];
+ } else {
+ parts.push(typeof next === 'string' ? encodeUTF8(next, textEncoder) : next);
+ }
+ }
+
+ for (const item of items) {
+ const [itemHeaders, payload] = item;
+
+ append(`\n${JSON.stringify(itemHeaders)}\n`);
+
+ if (typeof payload === 'string' || payload instanceof Uint8Array) {
+ append(payload);
+ } else {
+ let stringifiedPayload;
+ try {
+ stringifiedPayload = JSON.stringify(payload);
+ } catch (e) {
+ // In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.strinify()` still
+ // fails, we try again after normalizing it again with infinite normalization depth. This of course has a
+ // performance impact but in this case a performance hit is better than throwing.
+ stringifiedPayload = JSON.stringify(normalize(payload));
+ }
+ append(stringifiedPayload);
+ }
+ }
+
+ return typeof parts === 'string' ? parts : concatBuffers(parts);
+}
+
+function concatBuffers(buffers) {
+ const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0);
+
+ const merged = new Uint8Array(totalLength);
+ let offset = 0;
+ for (const buffer of buffers) {
+ merged.set(buffer, offset);
+ offset += buffer.length;
+ }
+
+ return merged;
+}
+
+/**
+ * Parses an envelope
+ */
+function parseEnvelope(
+ env,
+ textEncoder,
+ textDecoder,
+) {
+ let buffer = typeof env === 'string' ? textEncoder.encode(env) : env;
+
+ function readBinary(length) {
+ const bin = buffer.subarray(0, length);
+ // Replace the buffer with the remaining data excluding trailing newline
+ buffer = buffer.subarray(length + 1);
+ return bin;
+ }
+
+ function readJson() {
+ let i = buffer.indexOf(0xa);
+ // If we couldn't find a newline, we must have found the end of the buffer
+ if (i < 0) {
+ i = buffer.length;
+ }
+
+ return JSON.parse(textDecoder.decode(readBinary(i))) ;
+ }
+
+ const envelopeHeader = readJson();
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const items = [];
+
+ while (buffer.length) {
+ const itemHeader = readJson();
+ const binaryLength = typeof itemHeader.length === 'number' ? itemHeader.length : undefined;
+
+ items.push([itemHeader, binaryLength ? readBinary(binaryLength) : readJson()]);
+ }
+
+ return [envelopeHeader, items];
+}
+
+/**
+ * Creates attachment envelope items
+ */
+function createAttachmentEnvelopeItem(
+ attachment,
+ textEncoder,
+) {
+ const buffer = typeof attachment.data === 'string' ? encodeUTF8(attachment.data, textEncoder) : attachment.data;
+
+ return [
+ dropUndefinedKeys({
+ type: 'attachment',
+ length: buffer.length,
+ filename: attachment.filename,
+ content_type: attachment.contentType,
+ attachment_type: attachment.attachmentType,
+ }),
+ buffer,
+ ];
+}
+
+const ITEM_TYPE_TO_DATA_CATEGORY_MAP = {
+ session: 'session',
+ sessions: 'session',
+ attachment: 'attachment',
+ transaction: 'transaction',
+ event: 'error',
+ client_report: 'internal',
+ user_report: 'default',
+ profile: 'profile',
+ replay_event: 'replay',
+ replay_recording: 'replay',
+ check_in: 'monitor',
+};
+
+/**
+ * Maps the type of an envelope item to a data category.
+ */
+function envelopeItemTypeToDataCategory(type) {
+ return ITEM_TYPE_TO_DATA_CATEGORY_MAP[type];
+}
+
+/** Extracts the minimal SDK info from from the metadata or an events */
+function getSdkMetadataForEnvelopeHeader(metadataOrEvent) {
+ if (!metadataOrEvent || !metadataOrEvent.sdk) {
+ return;
+ }
+ const { name, version } = metadataOrEvent.sdk;
+ return { name, version };
+}
+
+/**
+ * Creates event envelope headers, based on event, sdk info and tunnel
+ * Note: This function was extracted from the core package to make it available in Replay
+ */
+function createEventEnvelopeHeaders(
+ event,
+ sdkInfo,
+ tunnel,
+ dsn,
+) {
+ const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;
+ return {
+ event_id: event.event_id ,
+ sent_at: new Date().toISOString(),
+ ...(sdkInfo && { sdk: sdkInfo }),
+ ...(!!tunnel && { dsn: dsnToString(dsn) }),
+ ...(dynamicSamplingContext && {
+ trace: dropUndefinedKeys({ ...dynamicSamplingContext }),
+ }),
+ };
+}
+
+export { addItemToEnvelope, createAttachmentEnvelopeItem, createEnvelope, createEventEnvelopeHeaders, envelopeContainsItemType, envelopeItemTypeToDataCategory, forEachEnvelopeItem, getSdkMetadataForEnvelopeHeader, parseEnvelope, serializeEnvelope };
+//# sourceMappingURL=envelope.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/error.js b/shared/logger/node_modules/@sentry/utils/esm/error.js
new file mode 100644
index 0000000..5266404
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/error.js
@@ -0,0 +1,17 @@
+/** An error emitted by Sentry SDKs and related utilities. */
+class SentryError extends Error {
+ /** Display name of this error instance. */
+
+ constructor( message, logLevel = 'warn') {
+ super(message);this.message = message;
+ this.name = new.target.prototype.constructor.name;
+ // This sets the prototype to be `Error`, not `SentryError`. It's unclear why we do this, but commenting this line
+ // out causes various (seemingly totally unrelated) playwright tests consistently time out. FYI, this makes
+ // instances of `SentryError` fail `obj instanceof SentryError` checks.
+ Object.setPrototypeOf(this, new.target.prototype);
+ this.logLevel = logLevel;
+ }
+}
+
+export { SentryError };
+//# sourceMappingURL=error.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/instrument.js b/shared/logger/node_modules/@sentry/utils/esm/instrument.js
new file mode 100644
index 0000000..618cf3c
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/instrument.js
@@ -0,0 +1,631 @@
+import { isString } from './is.js';
+import { logger, CONSOLE_LEVELS } from './logger.js';
+import { fill } from './object.js';
+import { getFunctionName } from './stacktrace.js';
+import { supportsNativeFetch } from './supports.js';
+import { getGlobalObject } from './worldwide.js';
+import { supportsHistory } from './vendor/supportsHistory.js';
+
+// eslint-disable-next-line deprecation/deprecation
+const WINDOW = getGlobalObject();
+
+const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v2__';
+
+/**
+ * Instrument native APIs to call handlers that can be used to create breadcrumbs, APM spans etc.
+ * - Console API
+ * - Fetch API
+ * - XHR API
+ * - History API
+ * - DOM API (click/typing)
+ * - Error API
+ * - UnhandledRejection API
+ */
+
+const handlers = {};
+const instrumented = {};
+
+/** Instruments given API */
+function instrument(type) {
+ if (instrumented[type]) {
+ return;
+ }
+
+ instrumented[type] = true;
+
+ switch (type) {
+ case 'console':
+ instrumentConsole();
+ break;
+ case 'dom':
+ instrumentDOM();
+ break;
+ case 'xhr':
+ instrumentXHR();
+ break;
+ case 'fetch':
+ instrumentFetch();
+ break;
+ case 'history':
+ instrumentHistory();
+ break;
+ case 'error':
+ instrumentError();
+ break;
+ case 'unhandledrejection':
+ instrumentUnhandledRejection();
+ break;
+ default:
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('unknown instrumentation type:', type);
+ return;
+ }
+}
+
+/**
+ * Add handler that will be called when given type of instrumentation triggers.
+ * Use at your own risk, this might break without changelog notice, only used internally.
+ * @hidden
+ */
+function addInstrumentationHandler(type, callback) {
+ handlers[type] = handlers[type] || [];
+ (handlers[type] ).push(callback);
+ instrument(type);
+}
+
+/** JSDoc */
+function triggerHandlers(type, data) {
+ if (!type || !handlers[type]) {
+ return;
+ }
+
+ for (const handler of handlers[type] || []) {
+ try {
+ handler(data);
+ } catch (e) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.error(
+ `Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError:`,
+ e,
+ );
+ }
+ }
+}
+
+/** JSDoc */
+function instrumentConsole() {
+ if (!('console' in WINDOW)) {
+ return;
+ }
+
+ CONSOLE_LEVELS.forEach(function (level) {
+ if (!(level in WINDOW.console)) {
+ return;
+ }
+
+ fill(WINDOW.console, level, function (originalConsoleMethod) {
+ return function (...args) {
+ triggerHandlers('console', { args, level });
+
+ // this fails for some browsers. :(
+ if (originalConsoleMethod) {
+ originalConsoleMethod.apply(WINDOW.console, args);
+ }
+ };
+ });
+ });
+}
+
+/** JSDoc */
+function instrumentFetch() {
+ if (!supportsNativeFetch()) {
+ return;
+ }
+
+ fill(WINDOW, 'fetch', function (originalFetch) {
+ return function (...args) {
+ const { method, url } = parseFetchArgs(args);
+
+ const handlerData = {
+ args,
+ fetchData: {
+ method,
+ url,
+ },
+ startTimestamp: Date.now(),
+ };
+
+ triggerHandlers('fetch', {
+ ...handlerData,
+ });
+
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ return originalFetch.apply(WINDOW, args).then(
+ (response) => {
+ triggerHandlers('fetch', {
+ ...handlerData,
+ endTimestamp: Date.now(),
+ response,
+ });
+ return response;
+ },
+ (error) => {
+ triggerHandlers('fetch', {
+ ...handlerData,
+ endTimestamp: Date.now(),
+ error,
+ });
+ // NOTE: If you are a Sentry user, and you are seeing this stack frame,
+ // it means the sentry.javascript SDK caught an error invoking your application code.
+ // This is expected behavior and NOT indicative of a bug with sentry.javascript.
+ throw error;
+ },
+ );
+ };
+ });
+}
+
+function hasProp(obj, prop) {
+ return !!obj && typeof obj === 'object' && !!(obj )[prop];
+}
+
+function getUrlFromResource(resource) {
+ if (typeof resource === 'string') {
+ return resource;
+ }
+
+ if (!resource) {
+ return '';
+ }
+
+ if (hasProp(resource, 'url')) {
+ return resource.url;
+ }
+
+ if (resource.toString) {
+ return resource.toString();
+ }
+
+ return '';
+}
+
+/**
+ * Parses the fetch arguments to find the used Http method and the url of the request
+ */
+function parseFetchArgs(fetchArgs) {
+ if (fetchArgs.length === 0) {
+ return { method: 'GET', url: '' };
+ }
+
+ if (fetchArgs.length === 2) {
+ const [url, options] = fetchArgs ;
+
+ return {
+ url: getUrlFromResource(url),
+ method: hasProp(options, 'method') ? String(options.method).toUpperCase() : 'GET',
+ };
+ }
+
+ const arg = fetchArgs[0];
+ return {
+ url: getUrlFromResource(arg ),
+ method: hasProp(arg, 'method') ? String(arg.method).toUpperCase() : 'GET',
+ };
+}
+
+/** JSDoc */
+function instrumentXHR() {
+ if (!('XMLHttpRequest' in WINDOW)) {
+ return;
+ }
+
+ const xhrproto = XMLHttpRequest.prototype;
+
+ fill(xhrproto, 'open', function (originalOpen) {
+ return function ( ...args) {
+ const url = args[1];
+ const xhrInfo = (this[SENTRY_XHR_DATA_KEY] = {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ method: isString(args[0]) ? args[0].toUpperCase() : args[0],
+ url: args[1],
+ request_headers: {},
+ });
+
+ // if Sentry key appears in URL, don't capture it as a request
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ if (isString(url) && xhrInfo.method === 'POST' && url.match(/sentry_key/)) {
+ this.__sentry_own_request__ = true;
+ }
+
+ const onreadystatechangeHandler = () => {
+ // For whatever reason, this is not the same instance here as from the outer method
+ const xhrInfo = this[SENTRY_XHR_DATA_KEY];
+
+ if (!xhrInfo) {
+ return;
+ }
+
+ if (this.readyState === 4) {
+ try {
+ // touching statusCode in some platforms throws
+ // an exception
+ xhrInfo.status_code = this.status;
+ } catch (e) {
+ /* do nothing */
+ }
+
+ triggerHandlers('xhr', {
+ args: args ,
+ endTimestamp: Date.now(),
+ startTimestamp: Date.now(),
+ xhr: this,
+ } );
+ }
+ };
+
+ if ('onreadystatechange' in this && typeof this.onreadystatechange === 'function') {
+ fill(this, 'onreadystatechange', function (original) {
+ return function ( ...readyStateArgs) {
+ onreadystatechangeHandler();
+ return original.apply(this, readyStateArgs);
+ };
+ });
+ } else {
+ this.addEventListener('readystatechange', onreadystatechangeHandler);
+ }
+
+ // Intercepting `setRequestHeader` to access the request headers of XHR instance.
+ // This will only work for user/library defined headers, not for the default/browser-assigned headers.
+ // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.
+ fill(this, 'setRequestHeader', function (original) {
+ return function ( ...setRequestHeaderArgs) {
+ const [header, value] = setRequestHeaderArgs ;
+
+ const xhrInfo = this[SENTRY_XHR_DATA_KEY];
+
+ if (xhrInfo) {
+ xhrInfo.request_headers[header.toLowerCase()] = value;
+ }
+
+ return original.apply(this, setRequestHeaderArgs);
+ };
+ });
+
+ return originalOpen.apply(this, args);
+ };
+ });
+
+ fill(xhrproto, 'send', function (originalSend) {
+ return function ( ...args) {
+ const sentryXhrData = this[SENTRY_XHR_DATA_KEY];
+ if (sentryXhrData && args[0] !== undefined) {
+ sentryXhrData.body = args[0];
+ }
+
+ triggerHandlers('xhr', {
+ args,
+ startTimestamp: Date.now(),
+ xhr: this,
+ });
+
+ return originalSend.apply(this, args);
+ };
+ });
+}
+
+let lastHref;
+
+/** JSDoc */
+function instrumentHistory() {
+ if (!supportsHistory()) {
+ return;
+ }
+
+ const oldOnPopState = WINDOW.onpopstate;
+ WINDOW.onpopstate = function ( ...args) {
+ const to = WINDOW.location.href;
+ // keep track of the current URL state, as we always receive only the updated state
+ const from = lastHref;
+ lastHref = to;
+ triggerHandlers('history', {
+ from,
+ to,
+ });
+ if (oldOnPopState) {
+ // Apparently this can throw in Firefox when incorrectly implemented plugin is installed.
+ // https://github.com/getsentry/sentry-javascript/issues/3344
+ // https://github.com/bugsnag/bugsnag-js/issues/469
+ try {
+ return oldOnPopState.apply(this, args);
+ } catch (_oO) {
+ // no-empty
+ }
+ }
+ };
+
+ /** @hidden */
+ function historyReplacementFunction(originalHistoryFunction) {
+ return function ( ...args) {
+ const url = args.length > 2 ? args[2] : undefined;
+ if (url) {
+ // coerce to string (this is what pushState does)
+ const from = lastHref;
+ const to = String(url);
+ // keep track of the current URL state, as we always receive only the updated state
+ lastHref = to;
+ triggerHandlers('history', {
+ from,
+ to,
+ });
+ }
+ return originalHistoryFunction.apply(this, args);
+ };
+ }
+
+ fill(WINDOW.history, 'pushState', historyReplacementFunction);
+ fill(WINDOW.history, 'replaceState', historyReplacementFunction);
+}
+
+const debounceDuration = 1000;
+let debounceTimerID;
+let lastCapturedEvent;
+
+/**
+ * Decide whether the current event should finish the debounce of previously captured one.
+ * @param previous previously captured event
+ * @param current event to be captured
+ */
+function shouldShortcircuitPreviousDebounce(previous, current) {
+ // If there was no previous event, it should always be swapped for the new one.
+ if (!previous) {
+ return true;
+ }
+
+ // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.
+ if (previous.type !== current.type) {
+ return true;
+ }
+
+ try {
+ // If both events have the same type, it's still possible that actions were performed on different targets.
+ // e.g. 2 clicks on different buttons.
+ if (previous.target !== current.target) {
+ return true;
+ }
+ } catch (e) {
+ // just accessing `target` property can throw an exception in some rare circumstances
+ // see: https://github.com/getsentry/sentry-javascript/issues/838
+ }
+
+ // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_
+ // to which an event listener was attached), we treat them as the same action, as we want to capture
+ // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.
+ return false;
+}
+
+/**
+ * Decide whether an event should be captured.
+ * @param event event to be captured
+ */
+function shouldSkipDOMEvent(event) {
+ // We are only interested in filtering `keypress` events for now.
+ if (event.type !== 'keypress') {
+ return false;
+ }
+
+ try {
+ const target = event.target ;
+
+ if (!target || !target.tagName) {
+ return true;
+ }
+
+ // Only consider keypress events on actual input elements. This will disregard keypresses targeting body
+ // e.g.tabbing through elements, hotkeys, etc.
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
+ return false;
+ }
+ } catch (e) {
+ // just accessing `target` property can throw an exception in some rare circumstances
+ // see: https://github.com/getsentry/sentry-javascript/issues/838
+ }
+
+ return true;
+}
+
+/**
+ * Wraps addEventListener to capture UI breadcrumbs
+ * @param handler function that will be triggered
+ * @param globalListener indicates whether event was captured by the global event listener
+ * @returns wrapped breadcrumb events handler
+ * @hidden
+ */
+function makeDOMEventHandler(handler, globalListener = false) {
+ return (event) => {
+ // It's possible this handler might trigger multiple times for the same
+ // event (e.g. event propagation through node ancestors).
+ // Ignore if we've already captured that event.
+ if (!event || lastCapturedEvent === event) {
+ return;
+ }
+
+ // We always want to skip _some_ events.
+ if (shouldSkipDOMEvent(event)) {
+ return;
+ }
+
+ const name = event.type === 'keypress' ? 'input' : event.type;
+
+ // If there is no debounce timer, it means that we can safely capture the new event and store it for future comparisons.
+ if (debounceTimerID === undefined) {
+ handler({
+ event: event,
+ name,
+ global: globalListener,
+ });
+ lastCapturedEvent = event;
+ }
+ // If there is a debounce awaiting, see if the new event is different enough to treat it as a unique one.
+ // If that's the case, emit the previous event and store locally the newly-captured DOM event.
+ else if (shouldShortcircuitPreviousDebounce(lastCapturedEvent, event)) {
+ handler({
+ event: event,
+ name,
+ global: globalListener,
+ });
+ lastCapturedEvent = event;
+ }
+
+ // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.
+ clearTimeout(debounceTimerID);
+ debounceTimerID = WINDOW.setTimeout(() => {
+ debounceTimerID = undefined;
+ }, debounceDuration);
+ };
+}
+
+/** JSDoc */
+function instrumentDOM() {
+ if (!('document' in WINDOW)) {
+ return;
+ }
+
+ // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom
+ // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before
+ // we instrument `addEventListener` so that we don't end up attaching this handler twice.
+ const triggerDOMHandler = triggerHandlers.bind(null, 'dom');
+ const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);
+ WINDOW.document.addEventListener('click', globalDOMEventHandler, false);
+ WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);
+
+ // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled
+ // clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That
+ // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler
+ // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still
+ // guaranteed to fire at least once.)
+ ['EventTarget', 'Node'].forEach((target) => {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ const proto = (WINDOW )[target] && (WINDOW )[target].prototype;
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
+ if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {
+ return;
+ }
+
+ fill(proto, 'addEventListener', function (originalAddEventListener) {
+ return function (
+
+ type,
+ listener,
+ options,
+ ) {
+ if (type === 'click' || type == 'keypress') {
+ try {
+ const el = this ;
+ const handlers = (el.__sentry_instrumentation_handlers__ = el.__sentry_instrumentation_handlers__ || {});
+ const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });
+
+ if (!handlerForType.handler) {
+ const handler = makeDOMEventHandler(triggerDOMHandler);
+ handlerForType.handler = handler;
+ originalAddEventListener.call(this, type, handler, options);
+ }
+
+ handlerForType.refCount++;
+ } catch (e) {
+ // Accessing dom properties is always fragile.
+ // Also allows us to skip `addEventListenrs` calls with no proper `this` context.
+ }
+ }
+
+ return originalAddEventListener.call(this, type, listener, options);
+ };
+ });
+
+ fill(
+ proto,
+ 'removeEventListener',
+ function (originalRemoveEventListener) {
+ return function (
+
+ type,
+ listener,
+ options,
+ ) {
+ if (type === 'click' || type == 'keypress') {
+ try {
+ const el = this ;
+ const handlers = el.__sentry_instrumentation_handlers__ || {};
+ const handlerForType = handlers[type];
+
+ if (handlerForType) {
+ handlerForType.refCount--;
+ // If there are no longer any custom handlers of the current type on this element, we can remove ours, too.
+ if (handlerForType.refCount <= 0) {
+ originalRemoveEventListener.call(this, type, handlerForType.handler, options);
+ handlerForType.handler = undefined;
+ delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete
+ }
+
+ // If there are no longer any custom handlers of any type on this element, cleanup everything.
+ if (Object.keys(handlers).length === 0) {
+ delete el.__sentry_instrumentation_handlers__;
+ }
+ }
+ } catch (e) {
+ // Accessing dom properties is always fragile.
+ // Also allows us to skip `addEventListenrs` calls with no proper `this` context.
+ }
+ }
+
+ return originalRemoveEventListener.call(this, type, listener, options);
+ };
+ },
+ );
+ });
+}
+
+let _oldOnErrorHandler = null;
+/** JSDoc */
+function instrumentError() {
+ _oldOnErrorHandler = WINDOW.onerror;
+
+ WINDOW.onerror = function (msg, url, line, column, error) {
+ triggerHandlers('error', {
+ column,
+ error,
+ line,
+ msg,
+ url,
+ });
+
+ if (_oldOnErrorHandler && !_oldOnErrorHandler.__SENTRY_LOADER__) {
+ // eslint-disable-next-line prefer-rest-params
+ return _oldOnErrorHandler.apply(this, arguments);
+ }
+
+ return false;
+ };
+
+ WINDOW.onerror.__SENTRY_INSTRUMENTED__ = true;
+}
+
+let _oldOnUnhandledRejectionHandler = null;
+/** JSDoc */
+function instrumentUnhandledRejection() {
+ _oldOnUnhandledRejectionHandler = WINDOW.onunhandledrejection;
+
+ WINDOW.onunhandledrejection = function (e) {
+ triggerHandlers('unhandledrejection', e);
+
+ if (_oldOnUnhandledRejectionHandler && !_oldOnUnhandledRejectionHandler.__SENTRY_LOADER__) {
+ // eslint-disable-next-line prefer-rest-params
+ return _oldOnUnhandledRejectionHandler.apply(this, arguments);
+ }
+
+ return true;
+ };
+
+ WINDOW.onunhandledrejection.__SENTRY_INSTRUMENTED__ = true;
+}
+
+export { SENTRY_XHR_DATA_KEY, addInstrumentationHandler, parseFetchArgs };
+//# sourceMappingURL=instrument.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/is.js b/shared/logger/node_modules/@sentry/utils/esm/is.js
new file mode 100644
index 0000000..8b60633
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/is.js
@@ -0,0 +1,179 @@
+// eslint-disable-next-line @typescript-eslint/unbound-method
+const objectToString = Object.prototype.toString;
+
+/**
+ * Checks whether given value's type is one of a few Error or Error-like
+ * {@link isError}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isError(wat) {
+ switch (objectToString.call(wat)) {
+ case '[object Error]':
+ case '[object Exception]':
+ case '[object DOMException]':
+ return true;
+ default:
+ return isInstanceOf(wat, Error);
+ }
+}
+/**
+ * Checks whether given value is an instance of the given built-in class.
+ *
+ * @param wat The value to be checked
+ * @param className
+ * @returns A boolean representing the result.
+ */
+function isBuiltin(wat, className) {
+ return objectToString.call(wat) === `[object ${className}]`;
+}
+
+/**
+ * Checks whether given value's type is ErrorEvent
+ * {@link isErrorEvent}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isErrorEvent(wat) {
+ return isBuiltin(wat, 'ErrorEvent');
+}
+
+/**
+ * Checks whether given value's type is DOMError
+ * {@link isDOMError}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isDOMError(wat) {
+ return isBuiltin(wat, 'DOMError');
+}
+
+/**
+ * Checks whether given value's type is DOMException
+ * {@link isDOMException}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isDOMException(wat) {
+ return isBuiltin(wat, 'DOMException');
+}
+
+/**
+ * Checks whether given value's type is a string
+ * {@link isString}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isString(wat) {
+ return isBuiltin(wat, 'String');
+}
+
+/**
+ * Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol)
+ * {@link isPrimitive}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isPrimitive(wat) {
+ return wat === null || (typeof wat !== 'object' && typeof wat !== 'function');
+}
+
+/**
+ * Checks whether given value's type is an object literal
+ * {@link isPlainObject}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isPlainObject(wat) {
+ return isBuiltin(wat, 'Object');
+}
+
+/**
+ * Checks whether given value's type is an Event instance
+ * {@link isEvent}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isEvent(wat) {
+ return typeof Event !== 'undefined' && isInstanceOf(wat, Event);
+}
+
+/**
+ * Checks whether given value's type is an Element instance
+ * {@link isElement}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isElement(wat) {
+ return typeof Element !== 'undefined' && isInstanceOf(wat, Element);
+}
+
+/**
+ * Checks whether given value's type is an regexp
+ * {@link isRegExp}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isRegExp(wat) {
+ return isBuiltin(wat, 'RegExp');
+}
+
+/**
+ * Checks whether given value has a then function.
+ * @param wat A value to be checked.
+ */
+function isThenable(wat) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ return Boolean(wat && wat.then && typeof wat.then === 'function');
+}
+
+/**
+ * Checks whether given value's type is a SyntheticEvent
+ * {@link isSyntheticEvent}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isSyntheticEvent(wat) {
+ return isPlainObject(wat) && 'nativeEvent' in wat && 'preventDefault' in wat && 'stopPropagation' in wat;
+}
+
+/**
+ * Checks whether given value is NaN
+ * {@link isNaN}.
+ *
+ * @param wat A value to be checked.
+ * @returns A boolean representing the result.
+ */
+function isNaN(wat) {
+ return typeof wat === 'number' && wat !== wat;
+}
+
+/**
+ * Checks whether given value's type is an instance of provided constructor.
+ * {@link isInstanceOf}.
+ *
+ * @param wat A value to be checked.
+ * @param base A constructor to be used in a check.
+ * @returns A boolean representing the result.
+ */
+function isInstanceOf(wat, base) {
+ try {
+ return wat instanceof base;
+ } catch (_e) {
+ return false;
+ }
+}
+
+export { isDOMError, isDOMException, isElement, isError, isErrorEvent, isEvent, isInstanceOf, isNaN, isPlainObject, isPrimitive, isRegExp, isString, isSyntheticEvent, isThenable };
+//# sourceMappingURL=is.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/logger.js b/shared/logger/node_modules/@sentry/utils/esm/logger.js
new file mode 100644
index 0000000..6c8c644
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/logger.js
@@ -0,0 +1,83 @@
+import { getGlobalSingleton, GLOBAL_OBJ } from './worldwide.js';
+
+/** Prefix for logging strings */
+const PREFIX = 'Sentry Logger ';
+
+const CONSOLE_LEVELS = ['debug', 'info', 'warn', 'error', 'log', 'assert', 'trace'] ;
+
+/**
+ * Temporarily disable sentry console instrumentations.
+ *
+ * @param callback The function to run against the original `console` messages
+ * @returns The results of the callback
+ */
+function consoleSandbox(callback) {
+ if (!('console' in GLOBAL_OBJ)) {
+ return callback();
+ }
+
+ const originalConsole = GLOBAL_OBJ.console ;
+ const wrappedLevels = {};
+
+ // Restore all wrapped console methods
+ CONSOLE_LEVELS.forEach(level => {
+ // TODO(v7): Remove this check as it's only needed for Node 6
+ const originalWrappedFunc =
+ originalConsole[level] && (originalConsole[level] ).__sentry_original__;
+ if (level in originalConsole && originalWrappedFunc) {
+ wrappedLevels[level] = originalConsole[level] ;
+ originalConsole[level] = originalWrappedFunc ;
+ }
+ });
+
+ try {
+ return callback();
+ } finally {
+ // Revert restoration to wrapped state
+ Object.keys(wrappedLevels).forEach(level => {
+ originalConsole[level] = wrappedLevels[level ];
+ });
+ }
+}
+
+function makeLogger() {
+ let enabled = false;
+ const logger = {
+ enable: () => {
+ enabled = true;
+ },
+ disable: () => {
+ enabled = false;
+ },
+ };
+
+ if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
+ CONSOLE_LEVELS.forEach(name => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ logger[name] = (...args) => {
+ if (enabled) {
+ consoleSandbox(() => {
+ GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);
+ });
+ }
+ };
+ });
+ } else {
+ CONSOLE_LEVELS.forEach(name => {
+ logger[name] = () => undefined;
+ });
+ }
+
+ return logger ;
+}
+
+// Ensure we only have a single logger instance, even if multiple versions of @sentry/utils are being used
+let logger;
+if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)) {
+ logger = getGlobalSingleton('logger', makeLogger);
+} else {
+ logger = makeLogger();
+}
+
+export { CONSOLE_LEVELS, consoleSandbox, logger };
+//# sourceMappingURL=logger.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/memo.js b/shared/logger/node_modules/@sentry/utils/esm/memo.js
new file mode 100644
index 0000000..fe00c9c
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/memo.js
@@ -0,0 +1,45 @@
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+/**
+ * Helper to decycle json objects
+ */
+function memoBuilder() {
+ const hasWeakSet = typeof WeakSet === 'function';
+ const inner = hasWeakSet ? new WeakSet() : [];
+ function memoize(obj) {
+ if (hasWeakSet) {
+ if (inner.has(obj)) {
+ return true;
+ }
+ inner.add(obj);
+ return false;
+ }
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
+ for (let i = 0; i < inner.length; i++) {
+ const value = inner[i];
+ if (value === obj) {
+ return true;
+ }
+ }
+ inner.push(obj);
+ return false;
+ }
+
+ function unmemoize(obj) {
+ if (hasWeakSet) {
+ inner.delete(obj);
+ } else {
+ for (let i = 0; i < inner.length; i++) {
+ if (inner[i] === obj) {
+ inner.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+ return [memoize, unmemoize];
+}
+
+export { memoBuilder };
+//# sourceMappingURL=memo.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/misc.js b/shared/logger/node_modules/@sentry/utils/esm/misc.js
new file mode 100644
index 0000000..858f159
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/misc.js
@@ -0,0 +1,197 @@
+import { addNonEnumerableProperty } from './object.js';
+import { snipLine } from './string.js';
+import { GLOBAL_OBJ } from './worldwide.js';
+
+/**
+ * UUID4 generator
+ *
+ * @returns string Generated UUID4.
+ */
+function uuid4() {
+ const gbl = GLOBAL_OBJ ;
+ const crypto = gbl.crypto || gbl.msCrypto;
+
+ if (crypto && crypto.randomUUID) {
+ return crypto.randomUUID().replace(/-/g, '');
+ }
+
+ const getRandomByte =
+ crypto && crypto.getRandomValues ? () => crypto.getRandomValues(new Uint8Array(1))[0] : () => Math.random() * 16;
+
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
+ // Concatenating the following numbers as strings results in '10000000100040008000100000000000'
+ return (([1e7] ) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>
+ // eslint-disable-next-line no-bitwise
+ ((c ) ^ ((getRandomByte() & 15) >> ((c ) / 4))).toString(16),
+ );
+}
+
+function getFirstException(event) {
+ return event.exception && event.exception.values ? event.exception.values[0] : undefined;
+}
+
+/**
+ * Extracts either message or type+value from an event that can be used for user-facing logs
+ * @returns event's description
+ */
+function getEventDescription(event) {
+ const { message, event_id: eventId } = event;
+ if (message) {
+ return message;
+ }
+
+ const firstException = getFirstException(event);
+ if (firstException) {
+ if (firstException.type && firstException.value) {
+ return `${firstException.type}: ${firstException.value}`;
+ }
+ return firstException.type || firstException.value || eventId || '<unknown>';
+ }
+ return eventId || '<unknown>';
+}
+
+/**
+ * Adds exception values, type and value to an synthetic Exception.
+ * @param event The event to modify.
+ * @param value Value of the exception.
+ * @param type Type of the exception.
+ * @hidden
+ */
+function addExceptionTypeValue(event, value, type) {
+ const exception = (event.exception = event.exception || {});
+ const values = (exception.values = exception.values || []);
+ const firstException = (values[0] = values[0] || {});
+ if (!firstException.value) {
+ firstException.value = value || '';
+ }
+ if (!firstException.type) {
+ firstException.type = type || 'Error';
+ }
+}
+
+/**
+ * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
+ *
+ * @param event The event to modify.
+ * @param newMechanism Mechanism data to add to the event.
+ * @hidden
+ */
+function addExceptionMechanism(event, newMechanism) {
+ const firstException = getFirstException(event);
+ if (!firstException) {
+ return;
+ }
+
+ const defaultMechanism = { type: 'generic', handled: true };
+ const currentMechanism = firstException.mechanism;
+ firstException.mechanism = { ...defaultMechanism, ...currentMechanism, ...newMechanism };
+
+ if (newMechanism && 'data' in newMechanism) {
+ const mergedData = { ...(currentMechanism && currentMechanism.data), ...newMechanism.data };
+ firstException.mechanism.data = mergedData;
+ }
+}
+
+// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
+const SEMVER_REGEXP =
+ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
+
+/**
+ * Represents Semantic Versioning object
+ */
+
+/**
+ * Parses input into a SemVer interface
+ * @param input string representation of a semver version
+ */
+function parseSemver(input) {
+ const match = input.match(SEMVER_REGEXP) || [];
+ const major = parseInt(match[1], 10);
+ const minor = parseInt(match[2], 10);
+ const patch = parseInt(match[3], 10);
+ return {
+ buildmetadata: match[5],
+ major: isNaN(major) ? undefined : major,
+ minor: isNaN(minor) ? undefined : minor,
+ patch: isNaN(patch) ? undefined : patch,
+ prerelease: match[4],
+ };
+}
+
+/**
+ * This function adds context (pre/post/line) lines to the provided frame
+ *
+ * @param lines string[] containing all lines
+ * @param frame StackFrame that will be mutated
+ * @param linesOfContext number of context lines we want to add pre/post
+ */
+function addContextToFrame(lines, frame, linesOfContext = 5) {
+ // When there is no line number in the frame, attaching context is nonsensical and will even break grouping
+ if (frame.lineno === undefined) {
+ return;
+ }
+
+ const maxLines = lines.length;
+ const sourceLine = Math.max(Math.min(maxLines, frame.lineno - 1), 0);
+
+ frame.pre_context = lines
+ .slice(Math.max(0, sourceLine - linesOfContext), sourceLine)
+ .map((line) => snipLine(line, 0));
+
+ frame.context_line = snipLine(lines[Math.min(maxLines - 1, sourceLine)], frame.colno || 0);
+
+ frame.post_context = lines
+ .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext)
+ .map((line) => snipLine(line, 0));
+}
+
+/**
+ * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object
+ * in question), and marks it captured if not.
+ *
+ * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and
+ * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so
+ * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because
+ * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not
+ * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This
+ * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we
+ * see it.
+ *
+ * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on
+ * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent
+ * object wrapper forms so that this check will always work. However, because we need to flag the exact object which
+ * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification
+ * must be done before the exception captured.
+ *
+ * @param A thrown exception to check or flag as having been seen
+ * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)
+ */
+function checkOrSetAlreadyCaught(exception) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ if (exception && (exception ).__sentry_captured__) {
+ return true;
+ }
+
+ try {
+ // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the
+ // `ExtraErrorData` integration
+ addNonEnumerableProperty(exception , '__sentry_captured__', true);
+ } catch (err) {
+ // `exception` is a primitive, so we can't mark it seen
+ }
+
+ return false;
+}
+
+/**
+ * Checks whether the given input is already an array, and if it isn't, wraps it in one.
+ *
+ * @param maybeArray Input to turn into an array, if necessary
+ * @returns The input, if already an array, or an array with the input as the only element, if not
+ */
+function arrayify(maybeArray) {
+ return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
+}
+
+export { addContextToFrame, addExceptionMechanism, addExceptionTypeValue, arrayify, checkOrSetAlreadyCaught, getEventDescription, parseSemver, uuid4 };
+//# sourceMappingURL=misc.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/node.js b/shared/logger/node_modules/@sentry/utils/esm/node.js
new file mode 100644
index 0000000..49eb7d7
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/node.js
@@ -0,0 +1,66 @@
+import { isBrowserBundle } from './env.js';
+
+/**
+ * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,
+ * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.
+ */
+
+/**
+ * Checks whether we're in the Node.js or Browser environment
+ *
+ * @returns Answer to given question
+ */
+function isNodeEnv() {
+ // explicitly check for browser bundles as those can be optimized statically
+ // by terser/rollup.
+ return (
+ !isBrowserBundle() &&
+ Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'
+ );
+}
+
+/**
+ * Requires a module which is protected against bundler minification.
+ *
+ * @param request The module path to resolve
+ */
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
+function dynamicRequire(mod, request) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ return mod.require(request);
+}
+
+/**
+ * Helper for dynamically loading module that should work with linked dependencies.
+ * The problem is that we _should_ be using `require(require.resolve(moduleName, { paths: [cwd()] }))`
+ * However it's _not possible_ to do that with Webpack, as it has to know all the dependencies during
+ * build time. `require.resolve` is also not available in any other way, so we cannot create,
+ * a fake helper like we do with `dynamicRequire`.
+ *
+ * We always prefer to use local package, thus the value is not returned early from each `try/catch` block.
+ * That is to mimic the behavior of `require.resolve` exactly.
+ *
+ * @param moduleName module name to require
+ * @returns possibly required module
+ */
+function loadModule(moduleName) {
+ let mod;
+
+ try {
+ mod = dynamicRequire(module, moduleName);
+ } catch (e) {
+ // no-empty
+ }
+
+ try {
+ const { cwd } = dynamicRequire(module, 'process');
+ mod = dynamicRequire(module, `${cwd()}/node_modules/${moduleName}`) ;
+ } catch (e) {
+ // no-empty
+ }
+
+ return mod;
+}
+
+export { dynamicRequire, isNodeEnv, loadModule };
+//# sourceMappingURL=node.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/normalize.js b/shared/logger/node_modules/@sentry/utils/esm/normalize.js
new file mode 100644
index 0000000..5d52c58
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/normalize.js
@@ -0,0 +1,263 @@
+import { isNaN, isSyntheticEvent } from './is.js';
+import { memoBuilder } from './memo.js';
+import { convertToPlainObject } from './object.js';
+import { getFunctionName } from './stacktrace.js';
+
+/**
+ * Recursively normalizes the given object.
+ *
+ * - Creates a copy to prevent original input mutation
+ * - Skips non-enumerable properties
+ * - When stringifying, calls `toJSON` if implemented
+ * - Removes circular references
+ * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format
+ * - Translates known global objects/classes to a string representations
+ * - Takes care of `Error` object serialization
+ * - Optionally limits depth of final output
+ * - Optionally limits number of properties/elements included in any single object/array
+ *
+ * @param input The object to be normalized.
+ * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)
+ * @param maxProperties The max number of elements or properties to be included in any single array or
+ * object in the normallized output.
+ * @returns A normalized version of the object, or `"**non-serializable**"` if any errors are thrown during normalization.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function normalize(input, depth = 100, maxProperties = +Infinity) {
+ try {
+ // since we're at the outermost level, we don't provide a key
+ return visit('', input, depth, maxProperties);
+ } catch (err) {
+ return { ERROR: `**non-serializable** (${err})` };
+ }
+}
+
+/** JSDoc */
+function normalizeToSize(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ object,
+ // Default Node.js REPL depth
+ depth = 3,
+ // 100kB, as 200kB is max payload size, so half sounds reasonable
+ maxSize = 100 * 1024,
+) {
+ const normalized = normalize(object, depth);
+
+ if (jsonSize(normalized) > maxSize) {
+ return normalizeToSize(object, depth - 1, maxSize);
+ }
+
+ return normalized ;
+}
+
+/**
+ * Visits a node to perform normalization on it
+ *
+ * @param key The key corresponding to the given node
+ * @param value The node to be visited
+ * @param depth Optional number indicating the maximum recursion depth
+ * @param maxProperties Optional maximum number of properties/elements included in any single object/array
+ * @param memo Optional Memo class handling decycling
+ */
+function visit(
+ key,
+ value,
+ depth = +Infinity,
+ maxProperties = +Infinity,
+ memo = memoBuilder(),
+) {
+ const [memoize, unmemoize] = memo;
+
+ // Get the simple cases out of the way first
+ if (
+ value == null || // this matches null and undefined -> eqeq not eqeqeq
+ (['number', 'boolean', 'string'].includes(typeof value) && !isNaN(value))
+ ) {
+ return value ;
+ }
+
+ const stringified = stringifyValue(key, value);
+
+ // Anything we could potentially dig into more (objects or arrays) will have come back as `"[object XXXX]"`.
+ // Everything else will have already been serialized, so if we don't see that pattern, we're done.
+ if (!stringified.startsWith('[object ')) {
+ return stringified;
+ }
+
+ // From here on, we can assert that `value` is either an object or an array.
+
+ // Do not normalize objects that we know have already been normalized. As a general rule, the
+ // "__sentry_skip_normalization__" property should only be used sparingly and only should only be set on objects that
+ // have already been normalized.
+ if ((value )['__sentry_skip_normalization__']) {
+ return value ;
+ }
+
+ // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there
+ // We keep a certain amount of depth.
+ // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.
+ const remainingDepth =
+ typeof (value )['__sentry_override_normalization_depth__'] === 'number'
+ ? ((value )['__sentry_override_normalization_depth__'] )
+ : depth;
+
+ // We're also done if we've reached the max depth
+ if (remainingDepth === 0) {
+ // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
+ return stringified.replace('object ', '');
+ }
+
+ // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.
+ if (memoize(value)) {
+ return '[Circular ~]';
+ }
+
+ // If the value has a `toJSON` method, we call it to extract more information
+ const valueWithToJSON = value ;
+ if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') {
+ try {
+ const jsonValue = valueWithToJSON.toJSON();
+ // We need to normalize the return value of `.toJSON()` in case it has circular references
+ return visit('', jsonValue, remainingDepth - 1, maxProperties, memo);
+ } catch (err) {
+ // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)
+ }
+ }
+
+ // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse
+ // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each
+ // property/entry, and keep track of the number of items we add to it.
+ const normalized = (Array.isArray(value) ? [] : {}) ;
+ let numAdded = 0;
+
+ // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant
+ // properties are non-enumerable and otherwise would get missed.
+ const visitable = convertToPlainObject(value );
+
+ for (const visitKey in visitable) {
+ // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.
+ if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) {
+ continue;
+ }
+
+ if (numAdded >= maxProperties) {
+ normalized[visitKey] = '[MaxProperties ~]';
+ break;
+ }
+
+ // Recursively visit all the child nodes
+ const visitValue = visitable[visitKey];
+ normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo);
+
+ numAdded++;
+ }
+
+ // Once we've visited all the branches, remove the parent from memo storage
+ unmemoize(value);
+
+ // Return accumulated values
+ return normalized;
+}
+
+/* eslint-disable complexity */
+/**
+ * Stringify the given value. Handles various known special values and types.
+ *
+ * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn
+ * the number 1231 into "[Object Number]", nor on `null`, as it will throw.
+ *
+ * @param value The value to stringify
+ * @returns A stringified representation of the given value
+ */
+function stringifyValue(
+ key,
+ // this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for
+ // our internal use, it'll do
+ value,
+) {
+ try {
+ if (key === 'domain' && value && typeof value === 'object' && (value )._events) {
+ return '[Domain]';
+ }
+
+ if (key === 'domainEmitter') {
+ return '[DomainEmitter]';
+ }
+
+ // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first
+ // which won't throw if they are not present.
+
+ if (typeof global !== 'undefined' && value === global) {
+ return '[Global]';
+ }
+
+ // eslint-disable-next-line no-restricted-globals
+ if (typeof window !== 'undefined' && value === window) {
+ return '[Window]';
+ }
+
+ // eslint-disable-next-line no-restricted-globals
+ if (typeof document !== 'undefined' && value === document) {
+ return '[Document]';
+ }
+
+ // React's SyntheticEvent thingy
+ if (isSyntheticEvent(value)) {
+ return '[SyntheticEvent]';
+ }
+
+ if (typeof value === 'number' && value !== value) {
+ return '[NaN]';
+ }
+
+ if (typeof value === 'function') {
+ return `[Function: ${getFunctionName(value)}]`;
+ }
+
+ if (typeof value === 'symbol') {
+ return `[${String(value)}]`;
+ }
+
+ // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion
+ if (typeof value === 'bigint') {
+ return `[BigInt: ${String(value)}]`;
+ }
+
+ // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting
+ // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as
+ // `"[object Object]"`. If we instead look at the constructor's name (which is the same as the name of the class),
+ // we can make sure that only plain objects come out that way.
+ const objName = getConstructorName(value);
+
+ // Handle HTML Elements
+ if (/^HTML(\w*)Element$/.test(objName)) {
+ return `[HTMLElement: ${objName}]`;
+ }
+
+ return `[object ${objName}]`;
+ } catch (err) {
+ return `**non-serializable** (${err})`;
+ }
+}
+/* eslint-enable complexity */
+
+function getConstructorName(value) {
+ const prototype = Object.getPrototypeOf(value);
+
+ return prototype ? prototype.constructor.name : 'null prototype';
+}
+
+/** Calculates bytes size of input string */
+function utf8Length(value) {
+ // eslint-disable-next-line no-bitwise
+ return ~-encodeURI(value).split(/%..|./).length;
+}
+
+/** Calculates bytes size of input object */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function jsonSize(value) {
+ return utf8Length(JSON.stringify(value));
+}
+
+export { normalize, normalizeToSize, visit as walk };
+//# sourceMappingURL=normalize.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/object.js b/shared/logger/node_modules/@sentry/utils/esm/object.js
new file mode 100644
index 0000000..0f5c411
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/object.js
@@ -0,0 +1,279 @@
+import { htmlTreeAsString } from './browser.js';
+import { isError, isEvent, isInstanceOf, isElement, isPlainObject, isPrimitive } from './is.js';
+import { truncate } from './string.js';
+
+/**
+ * Replace a method in an object with a wrapped version of itself.
+ *
+ * @param source An object that contains a method to be wrapped.
+ * @param name The name of the method to be wrapped.
+ * @param replacementFactory A higher-order function that takes the original version of the given method and returns a
+ * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to
+ * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, <other
+ * args>)` or `origMethod.apply(this, [<other args>])` (rather than being called directly), again to preserve `this`.
+ * @returns void
+ */
+function fill(source, name, replacementFactory) {
+ if (!(name in source)) {
+ return;
+ }
+
+ const original = source[name] ;
+ const wrapped = replacementFactory(original) ;
+
+ // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work
+ // otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
+ if (typeof wrapped === 'function') {
+ try {
+ markFunctionWrapped(wrapped, original);
+ } catch (_Oo) {
+ // This can throw if multiple fill happens on a global object like XMLHttpRequest
+ // Fixes https://github.com/getsentry/sentry-javascript/issues/2043
+ }
+ }
+
+ source[name] = wrapped;
+}
+
+/**
+ * Defines a non-enumerable property on the given object.
+ *
+ * @param obj The object on which to set the property
+ * @param name The name of the property to be set
+ * @param value The value to which to set the property
+ */
+function addNonEnumerableProperty(obj, name, value) {
+ Object.defineProperty(obj, name, {
+ // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it
+ value: value,
+ writable: true,
+ configurable: true,
+ });
+}
+
+/**
+ * Remembers the original function on the wrapped function and
+ * patches up the prototype.
+ *
+ * @param wrapped the wrapper function
+ * @param original the original function that gets wrapped
+ */
+function markFunctionWrapped(wrapped, original) {
+ const proto = original.prototype || {};
+ wrapped.prototype = original.prototype = proto;
+ addNonEnumerableProperty(wrapped, '__sentry_original__', original);
+}
+
+/**
+ * This extracts the original function if available. See
+ * `markFunctionWrapped` for more information.
+ *
+ * @param func the function to unwrap
+ * @returns the unwrapped version of the function if available.
+ */
+function getOriginalFunction(func) {
+ return func.__sentry_original__;
+}
+
+/**
+ * Encodes given object into url-friendly format
+ *
+ * @param object An object that contains serializable values
+ * @returns string Encoded
+ */
+function urlEncode(object) {
+ return Object.keys(object)
+ .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`)
+ .join('&');
+}
+
+/**
+ * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their
+ * non-enumerable properties attached.
+ *
+ * @param value Initial source that we have to transform in order for it to be usable by the serializer
+ * @returns An Event or Error turned into an object - or the value argurment itself, when value is neither an Event nor
+ * an Error.
+ */
+function convertToPlainObject(value)
+
+ {
+ if (isError(value)) {
+ return {
+ message: value.message,
+ name: value.name,
+ stack: value.stack,
+ ...getOwnProperties(value),
+ };
+ } else if (isEvent(value)) {
+ const newObj
+
+ = {
+ type: value.type,
+ target: serializeEventTarget(value.target),
+ currentTarget: serializeEventTarget(value.currentTarget),
+ ...getOwnProperties(value),
+ };
+
+ if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {
+ newObj.detail = value.detail;
+ }
+
+ return newObj;
+ } else {
+ return value;
+ }
+}
+
+/** Creates a string representation of the target of an `Event` object */
+function serializeEventTarget(target) {
+ try {
+ return isElement(target) ? htmlTreeAsString(target) : Object.prototype.toString.call(target);
+ } catch (_oO) {
+ return '<unknown>';
+ }
+}
+
+/** Filters out all but an object's own properties */
+function getOwnProperties(obj) {
+ if (typeof obj === 'object' && obj !== null) {
+ const extractedProps = {};
+ for (const property in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, property)) {
+ extractedProps[property] = (obj )[property];
+ }
+ }
+ return extractedProps;
+ } else {
+ return {};
+ }
+}
+
+/**
+ * Given any captured exception, extract its keys and create a sorted
+ * and truncated list that will be used inside the event message.
+ * eg. `Non-error exception captured with keys: foo, bar, baz`
+ */
+function extractExceptionKeysForMessage(exception, maxLength = 40) {
+ const keys = Object.keys(convertToPlainObject(exception));
+ keys.sort();
+
+ if (!keys.length) {
+ return '[object has no keys]';
+ }
+
+ if (keys[0].length >= maxLength) {
+ return truncate(keys[0], maxLength);
+ }
+
+ for (let includedKeys = keys.length; includedKeys > 0; includedKeys--) {
+ const serialized = keys.slice(0, includedKeys).join(', ');
+ if (serialized.length > maxLength) {
+ continue;
+ }
+ if (includedKeys === keys.length) {
+ return serialized;
+ }
+ return truncate(serialized, maxLength);
+ }
+
+ return '';
+}
+
+/**
+ * Given any object, return a new object having removed all fields whose value was `undefined`.
+ * Works recursively on objects and arrays.
+ *
+ * Attention: This function keeps circular references in the returned object.
+ */
+function dropUndefinedKeys(inputValue) {
+ // This map keeps track of what already visited nodes map to.
+ // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular
+ // references as the input object.
+ const memoizationMap = new Map();
+
+ // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API
+ return _dropUndefinedKeys(inputValue, memoizationMap);
+}
+
+function _dropUndefinedKeys(inputValue, memoizationMap) {
+ if (isPlainObject(inputValue)) {
+ // If this node has already been visited due to a circular reference, return the object it was mapped to in the new object
+ const memoVal = memoizationMap.get(inputValue);
+ if (memoVal !== undefined) {
+ return memoVal ;
+ }
+
+ const returnValue = {};
+ // Store the mapping of this value in case we visit it again, in case of circular data
+ memoizationMap.set(inputValue, returnValue);
+
+ for (const key of Object.keys(inputValue)) {
+ if (typeof inputValue[key] !== 'undefined') {
+ returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);
+ }
+ }
+
+ return returnValue ;
+ }
+
+ if (Array.isArray(inputValue)) {
+ // If this node has already been visited due to a circular reference, return the array it was mapped to in the new object
+ const memoVal = memoizationMap.get(inputValue);
+ if (memoVal !== undefined) {
+ return memoVal ;
+ }
+
+ const returnValue = [];
+ // Store the mapping of this value in case we visit it again, in case of circular data
+ memoizationMap.set(inputValue, returnValue);
+
+ inputValue.forEach((item) => {
+ returnValue.push(_dropUndefinedKeys(item, memoizationMap));
+ });
+
+ return returnValue ;
+ }
+
+ return inputValue;
+}
+
+/**
+ * Ensure that something is an object.
+ *
+ * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper
+ * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives.
+ *
+ * @param wat The subject of the objectification
+ * @returns A version of `wat` which can safely be used with `Object` class methods
+ */
+function objectify(wat) {
+ let objectified;
+ switch (true) {
+ case wat === undefined || wat === null:
+ objectified = new String(wat);
+ break;
+
+ // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason
+ // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as
+ // an object in order to wrap it.
+ case typeof wat === 'symbol' || typeof wat === 'bigint':
+ objectified = Object(wat);
+ break;
+
+ // this will catch the remaining primitives: `String`, `Number`, and `Boolean`
+ case isPrimitive(wat):
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ objectified = new (wat ).constructor(wat);
+ break;
+
+ // by process of elimination, at this point we know that `wat` must already be an object
+ default:
+ objectified = wat;
+ break;
+ }
+ return objectified;
+}
+
+export { addNonEnumerableProperty, convertToPlainObject, dropUndefinedKeys, extractExceptionKeysForMessage, fill, getOriginalFunction, markFunctionWrapped, objectify, urlEncode };
+//# sourceMappingURL=object.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/promisebuffer.js b/shared/logger/node_modules/@sentry/utils/esm/promisebuffer.js
new file mode 100644
index 0000000..fea1ed0
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/promisebuffer.js
@@ -0,0 +1,102 @@
+import { SentryError } from './error.js';
+import { rejectedSyncPromise, SyncPromise, resolvedSyncPromise } from './syncpromise.js';
+
+/**
+ * Creates an new PromiseBuffer object with the specified limit
+ * @param limit max number of promises that can be stored in the buffer
+ */
+function makePromiseBuffer(limit) {
+ const buffer = [];
+
+ function isReady() {
+ return limit === undefined || buffer.length < limit;
+ }
+
+ /**
+ * Remove a promise from the queue.
+ *
+ * @param task Can be any PromiseLike<T>
+ * @returns Removed promise.
+ */
+ function remove(task) {
+ return buffer.splice(buffer.indexOf(task), 1)[0];
+ }
+
+ /**
+ * Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
+ *
+ * @param taskProducer A function producing any PromiseLike<T>; In previous versions this used to be `task:
+ * PromiseLike<T>`, but under that model, Promises were instantly created on the call-site and their executor
+ * functions therefore ran immediately. Thus, even if the buffer was full, the action still happened. By
+ * requiring the promise to be wrapped in a function, we can defer promise creation until after the buffer
+ * limit check.
+ * @returns The original promise.
+ */
+ function add(taskProducer) {
+ if (!isReady()) {
+ return rejectedSyncPromise(new SentryError('Not adding Promise because buffer limit was reached.'));
+ }
+
+ // start the task and add its promise to the queue
+ const task = taskProducer();
+ if (buffer.indexOf(task) === -1) {
+ buffer.push(task);
+ }
+ void task
+ .then(() => remove(task))
+ // Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
+ // rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
+ // have promises, so TS has to polyfill when down-compiling.)
+ .then(null, () =>
+ remove(task).then(null, () => {
+ // We have to add another catch here because `remove()` starts a new promise chain.
+ }),
+ );
+ return task;
+ }
+
+ /**
+ * Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
+ *
+ * @param timeout The time, in ms, after which to resolve to `false` if the queue is still non-empty. Passing `0` (or
+ * not passing anything) will make the promise wait as long as it takes for the queue to drain before resolving to
+ * `true`.
+ * @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
+ * `false` otherwise
+ */
+ function drain(timeout) {
+ return new SyncPromise((resolve, reject) => {
+ let counter = buffer.length;
+
+ if (!counter) {
+ return resolve(true);
+ }
+
+ // wait for `timeout` ms and then resolve to `false` (if not cancelled first)
+ const capturedSetTimeout = setTimeout(() => {
+ if (timeout && timeout > 0) {
+ resolve(false);
+ }
+ }, timeout);
+
+ // if all promises resolve in time, cancel the timer and resolve to `true`
+ buffer.forEach(item => {
+ void resolvedSyncPromise(item).then(() => {
+ if (!--counter) {
+ clearTimeout(capturedSetTimeout);
+ resolve(true);
+ }
+ }, reject);
+ });
+ });
+ }
+
+ return {
+ $: buffer,
+ add,
+ drain,
+ };
+}
+
+export { makePromiseBuffer };
+//# sourceMappingURL=promisebuffer.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/ratelimit.js b/shared/logger/node_modules/@sentry/utils/esm/ratelimit.js
new file mode 100644
index 0000000..becfdf0
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/ratelimit.js
@@ -0,0 +1,97 @@
+// Intentionally keeping the key broad, as we don't know for sure what rate limit headers get returned from backend
+
+const DEFAULT_RETRY_AFTER = 60 * 1000; // 60 seconds
+
+/**
+ * Extracts Retry-After value from the request header or returns default value
+ * @param header string representation of 'Retry-After' header
+ * @param now current unix timestamp
+ *
+ */
+function parseRetryAfterHeader(header, now = Date.now()) {
+ const headerDelay = parseInt(`${header}`, 10);
+ if (!isNaN(headerDelay)) {
+ return headerDelay * 1000;
+ }
+
+ const headerDate = Date.parse(`${header}`);
+ if (!isNaN(headerDate)) {
+ return headerDate - now;
+ }
+
+ return DEFAULT_RETRY_AFTER;
+}
+
+/**
+ * Gets the time that the given category is disabled until for rate limiting.
+ * In case no category-specific limit is set but a general rate limit across all categories is active,
+ * that time is returned.
+ *
+ * @return the time in ms that the category is disabled until or 0 if there's no active rate limit.
+ */
+function disabledUntil(limits, category) {
+ return limits[category] || limits.all || 0;
+}
+
+/**
+ * Checks if a category is rate limited
+ */
+function isRateLimited(limits, category, now = Date.now()) {
+ return disabledUntil(limits, category) > now;
+}
+
+/**
+ * Update ratelimits from incoming headers.
+ *
+ * @return the updated RateLimits object.
+ */
+function updateRateLimits(
+ limits,
+ { statusCode, headers },
+ now = Date.now(),
+) {
+ const updatedRateLimits = {
+ ...limits,
+ };
+
+ // "The name is case-insensitive."
+ // https://developer.mozilla.org/en-US/docs/Web/API/Headers/get
+ const rateLimitHeader = headers && headers['x-sentry-rate-limits'];
+ const retryAfterHeader = headers && headers['retry-after'];
+
+ if (rateLimitHeader) {
+ /**
+ * rate limit headers are of the form
+ * <header>,<header>,..
+ * where each <header> is of the form
+ * <retry_after>: <categories>: <scope>: <reason_code>
+ * where
+ * <retry_after> is a delay in seconds
+ * <categories> is the event type(s) (error, transaction, etc) being rate limited and is of the form
+ * <category>;<category>;...
+ * <scope> is what's being limited (org, project, or key) - ignored by SDK
+ * <reason_code> is an arbitrary string like "org_quota" - ignored by SDK
+ */
+ for (const limit of rateLimitHeader.trim().split(',')) {
+ const [retryAfter, categories] = limit.split(':', 2);
+ const headerDelay = parseInt(retryAfter, 10);
+ const delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default
+ if (!categories) {
+ updatedRateLimits.all = now + delay;
+ } else {
+ for (const category of categories.split(';')) {
+ updatedRateLimits[category] = now + delay;
+ }
+ }
+ }
+ } else if (retryAfterHeader) {
+ updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now);
+ } else if (statusCode === 429) {
+ updatedRateLimits.all = now + 60 * 1000;
+ }
+
+ return updatedRateLimits;
+}
+
+export { DEFAULT_RETRY_AFTER, disabledUntil, isRateLimited, parseRetryAfterHeader, updateRateLimits };
+//# sourceMappingURL=ratelimit.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/severity.js b/shared/logger/node_modules/@sentry/utils/esm/severity.js
new file mode 100644
index 0000000..3e5128e
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/severity.js
@@ -0,0 +1,36 @@
+// Note: Ideally the `SeverityLevel` type would be derived from `validSeverityLevels`, but that would mean either
+//
+// a) moving `validSeverityLevels` to `@sentry/types`,
+// b) moving the`SeverityLevel` type here, or
+// c) importing `validSeverityLevels` from here into `@sentry/types`.
+//
+// Option A would make `@sentry/types` a runtime dependency of `@sentry/utils` (not good), and options B and C would
+// create a circular dependency between `@sentry/types` and `@sentry/utils` (also not good). So a TODO accompanying the
+// type, reminding anyone who changes it to change this list also, will have to do.
+
+const validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];
+
+/**
+ * Converts a string-based level into a member of the deprecated {@link Severity} enum.
+ *
+ * @deprecated `severityFromString` is deprecated. Please use `severityLevelFromString` instead.
+ *
+ * @param level String representation of Severity
+ * @returns Severity
+ */
+function severityFromString(level) {
+ return severityLevelFromString(level) ;
+}
+
+/**
+ * Converts a string-based level into a `SeverityLevel`, normalizing it along the way.
+ *
+ * @param level String representation of desired `SeverityLevel`.
+ * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level.
+ */
+function severityLevelFromString(level) {
+ return (level === 'warn' ? 'warning' : validSeverityLevels.includes(level) ? level : 'log') ;
+}
+
+export { severityFromString, severityLevelFromString, validSeverityLevels };
+//# sourceMappingURL=severity.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js b/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
new file mode 100644
index 0000000..ffb3614
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/stacktrace.js
@@ -0,0 +1,136 @@
+import { node } from './node-stack-trace.js';
+
+const STACKTRACE_FRAME_LIMIT = 50;
+// Used to sanitize webpack (error: *) wrapped stack errors
+const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
+
+/**
+ * Creates a stack parser with the supplied line parsers
+ *
+ * StackFrames are returned in the correct order for Sentry Exception
+ * frames and with Sentry SDK internal frames removed from the top and bottom
+ *
+ */
+function createStackParser(...parsers) {
+ const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);
+
+ return (stack, skipFirst = 0) => {
+ const frames = [];
+ const lines = stack.split('\n');
+
+ for (let i = skipFirst; i < lines.length; i++) {
+ const line = lines[i];
+ // Ignore lines over 1kb as they are unlikely to be stack frames.
+ // Many of the regular expressions use backtracking which results in run time that increases exponentially with
+ // input size. Huge strings can result in hangs/Denial of Service:
+ // https://github.com/getsentry/sentry-javascript/issues/2286
+ if (line.length > 1024) {
+ continue;
+ }
+
+ // https://github.com/getsentry/sentry-javascript/issues/5459
+ // Remove webpack (error: *) wrappers
+ const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;
+
+ // https://github.com/getsentry/sentry-javascript/issues/7813
+ // Skip Error: lines
+ if (cleanedLine.match(/\S*Error: /)) {
+ continue;
+ }
+
+ for (const parser of sortedParsers) {
+ const frame = parser(cleanedLine);
+
+ if (frame) {
+ frames.push(frame);
+ break;
+ }
+ }
+
+ if (frames.length >= STACKTRACE_FRAME_LIMIT) {
+ break;
+ }
+ }
+
+ return stripSentryFramesAndReverse(frames);
+ };
+}
+
+/**
+ * Gets a stack parser implementation from Options.stackParser
+ * @see Options
+ *
+ * If options contains an array of line parsers, it is converted into a parser
+ */
+function stackParserFromStackParserOptions(stackParser) {
+ if (Array.isArray(stackParser)) {
+ return createStackParser(...stackParser);
+ }
+ return stackParser;
+}
+
+/**
+ * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.
+ * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the
+ * function that caused the crash is the last frame in the array.
+ * @hidden
+ */
+function stripSentryFramesAndReverse(stack) {
+ if (!stack.length) {
+ return [];
+ }
+
+ const localStack = stack.slice(0, STACKTRACE_FRAME_LIMIT);
+
+ const lastFrameFunction = localStack[localStack.length - 1].function;
+ // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)
+ if (lastFrameFunction && /sentryWrapped/.test(lastFrameFunction)) {
+ localStack.pop();
+ }
+
+ // Reversing in the middle of the procedure allows us to just pop the values off the stack
+ localStack.reverse();
+
+ const firstFrameFunction = localStack[localStack.length - 1].function;
+ // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)
+ if (firstFrameFunction && /captureMessage|captureException/.test(firstFrameFunction)) {
+ localStack.pop();
+ }
+
+ return localStack.map(frame => ({
+ ...frame,
+ filename: frame.filename || localStack[localStack.length - 1].filename,
+ function: frame.function || '?',
+ }));
+}
+
+const defaultFunctionName = '<anonymous>';
+
+/**
+ * Safely extract function name from itself
+ */
+function getFunctionName(fn) {
+ try {
+ if (!fn || typeof fn !== 'function') {
+ return defaultFunctionName;
+ }
+ return fn.name || defaultFunctionName;
+ } catch (e) {
+ // Just accessing custom props in some Selenium environments
+ // can cause a "Permission denied" exception (see raven-js#495).
+ return defaultFunctionName;
+ }
+}
+
+/**
+ * Node.js stack line parser
+ *
+ * This is in @sentry/utils so it can be used from the Electron SDK in the browser for when `nodeIntegration == true`.
+ * This allows it to be used without referencing or importing any node specific code which causes bundlers to complain
+ */
+function nodeStackLineParser(getModule) {
+ return [90, node(getModule)];
+}
+
+export { createStackParser, getFunctionName, nodeStackLineParser, stackParserFromStackParserOptions, stripSentryFramesAndReverse };
+//# sourceMappingURL=stacktrace.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/string.js b/shared/logger/node_modules/@sentry/utils/esm/string.js
new file mode 100644
index 0000000..3398545
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/string.js
@@ -0,0 +1,132 @@
+import { isString, isRegExp } from './is.js';
+
+/**
+ * Truncates given string to the maximum characters count
+ *
+ * @param str An object that contains serializable values
+ * @param max Maximum number of characters in truncated string (0 = unlimited)
+ * @returns string Encoded
+ */
+function truncate(str, max = 0) {
+ if (typeof str !== 'string' || max === 0) {
+ return str;
+ }
+ return str.length <= max ? str : `${str.slice(0, max)}...`;
+}
+
+/**
+ * This is basically just `trim_line` from
+ * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67
+ *
+ * @param str An object that contains serializable values
+ * @param max Maximum number of characters in truncated string
+ * @returns string Encoded
+ */
+function snipLine(line, colno) {
+ let newLine = line;
+ const lineLength = newLine.length;
+ if (lineLength <= 150) {
+ return newLine;
+ }
+ if (colno > lineLength) {
+ // eslint-disable-next-line no-param-reassign
+ colno = lineLength;
+ }
+
+ let start = Math.max(colno - 60, 0);
+ if (start < 5) {
+ start = 0;
+ }
+
+ let end = Math.min(start + 140, lineLength);
+ if (end > lineLength - 5) {
+ end = lineLength;
+ }
+ if (end === lineLength) {
+ start = Math.max(end - 140, 0);
+ }
+
+ newLine = newLine.slice(start, end);
+ if (start > 0) {
+ newLine = `'{snip} ${newLine}`;
+ }
+ if (end < lineLength) {
+ newLine += ' {snip}';
+ }
+
+ return newLine;
+}
+
+/**
+ * Join values in array
+ * @param input array of values to be joined together
+ * @param delimiter string to be placed in-between values
+ * @returns Joined values
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function safeJoin(input, delimiter) {
+ if (!Array.isArray(input)) {
+ return '';
+ }
+
+ const output = [];
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
+ for (let i = 0; i < input.length; i++) {
+ const value = input[i];
+ try {
+ output.push(String(value));
+ } catch (e) {
+ output.push('[value cannot be serialized]');
+ }
+ }
+
+ return output.join(delimiter);
+}
+
+/**
+ * Checks if the given value matches a regex or string
+ *
+ * @param value The string to test
+ * @param pattern Either a regex or a string against which `value` will be matched
+ * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match
+ * `pattern` if it contains `pattern`. Only applies to string-type patterns.
+ */
+function isMatchingPattern(
+ value,
+ pattern,
+ requireExactStringMatch = false,
+) {
+ if (!isString(value)) {
+ return false;
+ }
+
+ if (isRegExp(pattern)) {
+ return pattern.test(value);
+ }
+ if (isString(pattern)) {
+ return requireExactStringMatch ? value === pattern : value.includes(pattern);
+ }
+
+ return false;
+}
+
+/**
+ * Test the given string against an array of strings and regexes. By default, string matching is done on a
+ * substring-inclusion basis rather than a strict equality basis
+ *
+ * @param testString The string to test
+ * @param patterns The patterns against which to test the string
+ * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to
+ * count. If false, `testString` will match a string pattern if it contains that pattern.
+ * @returns
+ */
+function stringMatchesSomePattern(
+ testString,
+ patterns = [],
+ requireExactStringMatch = false,
+) {
+ return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));
+}
+
+export { isMatchingPattern, safeJoin, snipLine, stringMatchesSomePattern, truncate };
+//# sourceMappingURL=string.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/supports.js b/shared/logger/node_modules/@sentry/utils/esm/supports.js
new file mode 100644
index 0000000..7a560a3
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/supports.js
@@ -0,0 +1,161 @@
+import { logger } from './logger.js';
+import { getGlobalObject } from './worldwide.js';
+
+// eslint-disable-next-line deprecation/deprecation
+const WINDOW = getGlobalObject();
+
+/**
+ * Tells whether current environment supports ErrorEvent objects
+ * {@link supportsErrorEvent}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsErrorEvent() {
+ try {
+ new ErrorEvent('');
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+/**
+ * Tells whether current environment supports DOMError objects
+ * {@link supportsDOMError}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsDOMError() {
+ try {
+ // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError':
+ // 1 argument required, but only 0 present.
+ // @ts-ignore It really needs 1 argument, not 0.
+ new DOMError('');
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+/**
+ * Tells whether current environment supports DOMException objects
+ * {@link supportsDOMException}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsDOMException() {
+ try {
+ new DOMException('');
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+/**
+ * Tells whether current environment supports Fetch API
+ * {@link supportsFetch}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsFetch() {
+ if (!('fetch' in WINDOW)) {
+ return false;
+ }
+
+ try {
+ new Headers();
+ new Request('http://www.example.com');
+ new Response();
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+/**
+ * isNativeFetch checks if the given function is a native implementation of fetch()
+ */
+// eslint-disable-next-line @typescript-eslint/ban-types
+function isNativeFetch(func) {
+ return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString());
+}
+
+/**
+ * Tells whether current environment supports Fetch API natively
+ * {@link supportsNativeFetch}.
+ *
+ * @returns true if `window.fetch` is natively implemented, false otherwise
+ */
+function supportsNativeFetch() {
+ if (!supportsFetch()) {
+ return false;
+ }
+
+ // Fast path to avoid DOM I/O
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ if (isNativeFetch(WINDOW.fetch)) {
+ return true;
+ }
+
+ // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)
+ // so create a "pure" iframe to see if that has native fetch
+ let result = false;
+ const doc = WINDOW.document;
+ // eslint-disable-next-line deprecation/deprecation
+ if (doc && typeof (doc.createElement ) === 'function') {
+ try {
+ const sandbox = doc.createElement('iframe');
+ sandbox.hidden = true;
+ doc.head.appendChild(sandbox);
+ if (sandbox.contentWindow && sandbox.contentWindow.fetch) {
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ result = isNativeFetch(sandbox.contentWindow.fetch);
+ }
+ doc.head.removeChild(sandbox);
+ } catch (err) {
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
+ logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
+ }
+ }
+
+ return result;
+}
+
+/**
+ * Tells whether current environment supports ReportingObserver API
+ * {@link supportsReportingObserver}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsReportingObserver() {
+ return 'ReportingObserver' in WINDOW;
+}
+
+/**
+ * Tells whether current environment supports Referrer Policy API
+ * {@link supportsReferrerPolicy}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsReferrerPolicy() {
+ // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'
+ // (see https://caniuse.com/#feat=referrer-policy),
+ // it doesn't. And it throws an exception instead of ignoring this parameter...
+ // REF: https://github.com/getsentry/raven-js/issues/1233
+
+ if (!supportsFetch()) {
+ return false;
+ }
+
+ try {
+ new Request('_', {
+ referrerPolicy: 'origin' ,
+ });
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+
+export { isNativeFetch, supportsDOMError, supportsDOMException, supportsErrorEvent, supportsFetch, supportsNativeFetch, supportsReferrerPolicy, supportsReportingObserver };
+//# sourceMappingURL=supports.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/syncpromise.js b/shared/logger/node_modules/@sentry/utils/esm/syncpromise.js
new file mode 100644
index 0000000..ad04190
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/syncpromise.js
@@ -0,0 +1,191 @@
+import { isThenable } from './is.js';
+
+/* eslint-disable @typescript-eslint/explicit-function-return-type */
+
+/** SyncPromise internal states */
+var States; (function (States) {
+ /** Pending */
+ const PENDING = 0; States[States["PENDING"] = PENDING] = "PENDING";
+ /** Resolved / OK */
+ const RESOLVED = 1; States[States["RESOLVED"] = RESOLVED] = "RESOLVED";
+ /** Rejected / Error */
+ const REJECTED = 2; States[States["REJECTED"] = REJECTED] = "REJECTED";
+})(States || (States = {}));
+
+// Overloads so we can call resolvedSyncPromise without arguments and generic argument
+
+/**
+ * Creates a resolved sync promise.
+ *
+ * @param value the value to resolve the promise with
+ * @returns the resolved sync promise
+ */
+function resolvedSyncPromise(value) {
+ return new SyncPromise(resolve => {
+ resolve(value);
+ });
+}
+
+/**
+ * Creates a rejected sync promise.
+ *
+ * @param value the value to reject the promise with
+ * @returns the rejected sync promise
+ */
+function rejectedSyncPromise(reason) {
+ return new SyncPromise((_, reject) => {
+ reject(reason);
+ });
+}
+
+/**
+ * Thenable class that behaves like a Promise and follows it's interface
+ * but is not async internally
+ */
+class SyncPromise {
+ __init() {this._state = States.PENDING;}
+ __init2() {this._handlers = [];}
+
+ constructor(
+ executor,
+ ) {SyncPromise.prototype.__init.call(this);SyncPromise.prototype.__init2.call(this);SyncPromise.prototype.__init3.call(this);SyncPromise.prototype.__init4.call(this);SyncPromise.prototype.__init5.call(this);SyncPromise.prototype.__init6.call(this);
+ try {
+ executor(this._resolve, this._reject);
+ } catch (e) {
+ this._reject(e);
+ }
+ }
+
+ /** JSDoc */
+ then(
+ onfulfilled,
+ onrejected,
+ ) {
+ return new SyncPromise((resolve, reject) => {
+ this._handlers.push([
+ false,
+ result => {
+ if (!onfulfilled) {
+ // TODO: ¯\_(ツ)_/¯
+ // TODO: FIXME
+ resolve(result );
+ } else {
+ try {
+ resolve(onfulfilled(result));
+ } catch (e) {
+ reject(e);
+ }
+ }
+ },
+ reason => {
+ if (!onrejected) {
+ reject(reason);
+ } else {
+ try {
+ resolve(onrejected(reason));
+ } catch (e) {
+ reject(e);
+ }
+ }
+ },
+ ]);
+ this._executeHandlers();
+ });
+ }
+
+ /** JSDoc */
+ catch(
+ onrejected,
+ ) {
+ return this.then(val => val, onrejected);
+ }
+
+ /** JSDoc */
+ finally(onfinally) {
+ return new SyncPromise((resolve, reject) => {
+ let val;
+ let isRejected;
+
+ return this.then(
+ value => {
+ isRejected = false;
+ val = value;
+ if (onfinally) {
+ onfinally();
+ }
+ },
+ reason => {
+ isRejected = true;
+ val = reason;
+ if (onfinally) {
+ onfinally();
+ }
+ },
+ ).then(() => {
+ if (isRejected) {
+ reject(val);
+ return;
+ }
+
+ resolve(val );
+ });
+ });
+ }
+
+ /** JSDoc */
+ __init3() {this._resolve = (value) => {
+ this._setResult(States.RESOLVED, value);
+ };}
+
+ /** JSDoc */
+ __init4() {this._reject = (reason) => {
+ this._setResult(States.REJECTED, reason);
+ };}
+
+ /** JSDoc */
+ __init5() {this._setResult = (state, value) => {
+ if (this._state !== States.PENDING) {
+ return;
+ }
+
+ if (isThenable(value)) {
+ void (value ).then(this._resolve, this._reject);
+ return;
+ }
+
+ this._state = state;
+ this._value = value;
+
+ this._executeHandlers();
+ };}
+
+ /** JSDoc */
+ __init6() {this._executeHandlers = () => {
+ if (this._state === States.PENDING) {
+ return;
+ }
+
+ const cachedHandlers = this._handlers.slice();
+ this._handlers = [];
+
+ cachedHandlers.forEach(handler => {
+ if (handler[0]) {
+ return;
+ }
+
+ if (this._state === States.RESOLVED) {
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
+ handler[1](this._value );
+ }
+
+ if (this._state === States.REJECTED) {
+ handler[2](this._value);
+ }
+
+ handler[0] = true;
+ });
+ };}
+}
+
+export { SyncPromise, rejectedSyncPromise, resolvedSyncPromise };
+//# sourceMappingURL=syncpromise.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/time.js b/shared/logger/node_modules/@sentry/utils/esm/time.js
new file mode 100644
index 0000000..2703ed2
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/time.js
@@ -0,0 +1,183 @@
+import { isNodeEnv, dynamicRequire } from './node.js';
+import { getGlobalObject } from './worldwide.js';
+
+// eslint-disable-next-line deprecation/deprecation
+const WINDOW = getGlobalObject();
+
+/**
+ * An object that can return the current timestamp in seconds since the UNIX epoch.
+ */
+
+/**
+ * A TimestampSource implementation for environments that do not support the Performance Web API natively.
+ *
+ * Note that this TimestampSource does not use a monotonic clock. A call to `nowSeconds` may return a timestamp earlier
+ * than a previously returned value. We do not try to emulate a monotonic behavior in order to facilitate debugging. It
+ * is more obvious to explain "why does my span have negative duration" than "why my spans have zero duration".
+ */
+const dateTimestampSource = {
+ nowSeconds: () => Date.now() / 1000,
+};
+
+/**
+ * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}
+ * for accessing a high-resolution monotonic clock.
+ */
+
+/**
+ * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not
+ * support the API.
+ *
+ * Wrapping the native API works around differences in behavior from different browsers.
+ */
+function getBrowserPerformance() {
+ const { performance } = WINDOW;
+ if (!performance || !performance.now) {
+ return undefined;
+ }
+
+ // Replace performance.timeOrigin with our own timeOrigin based on Date.now().
+ //
+ // This is a partial workaround for browsers reporting performance.timeOrigin such that performance.timeOrigin +
+ // performance.now() gives a date arbitrarily in the past.
+ //
+ // Additionally, computing timeOrigin in this way fills the gap for browsers where performance.timeOrigin is
+ // undefined.
+ //
+ // The assumption that performance.timeOrigin + performance.now() ~= Date.now() is flawed, but we depend on it to
+ // interact with data coming out of performance entries.
+ //
+ // Note that despite recommendations against it in the spec, browsers implement the Performance API with a clock that
+ // might stop when the computer is asleep (and perhaps under other circumstances). Such behavior causes
+ // performance.timeOrigin + performance.now() to have an arbitrary skew over Date.now(). In laptop computers, we have
+ // observed skews that can be as long as days, weeks or months.
+ //
+ // See https://github.com/getsentry/sentry-javascript/issues/2590.
+ //
+ // BUG: despite our best intentions, this workaround has its limitations. It mostly addresses timings of pageload
+ // transactions, but ignores the skew built up over time that can aversely affect timestamps of navigation
+ // transactions of long-lived web pages.
+ const timeOrigin = Date.now() - performance.now();
+
+ return {
+ now: () => performance.now(),
+ timeOrigin,
+ };
+}
+
+/**
+ * Returns the native Performance API implementation from Node.js. Returns undefined in old Node.js versions that don't
+ * implement the API.
+ */
+function getNodePerformance() {
+ try {
+ const perfHooks = dynamicRequire(module, 'perf_hooks') ;
+ return perfHooks.performance;
+ } catch (_) {
+ return undefined;
+ }
+}
+
+/**
+ * The Performance API implementation for the current platform, if available.
+ */
+const platformPerformance = isNodeEnv() ? getNodePerformance() : getBrowserPerformance();
+
+const timestampSource =
+ platformPerformance === undefined
+ ? dateTimestampSource
+ : {
+ nowSeconds: () => (platformPerformance.timeOrigin + platformPerformance.now()) / 1000,
+ };
+
+/**
+ * Returns a timestamp in seconds since the UNIX epoch using the Date API.
+ */
+const dateTimestampInSeconds = dateTimestampSource.nowSeconds.bind(dateTimestampSource);
+
+/**
+ * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the
+ * availability of the Performance API.
+ *
+ * See `usingPerformanceAPI` to test whether the Performance API is used.
+ *
+ * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is
+ * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The
+ * skew can grow to arbitrary amounts like days, weeks or months.
+ * See https://github.com/getsentry/sentry-javascript/issues/2590.
+ */
+const timestampInSeconds = timestampSource.nowSeconds.bind(timestampSource);
+
+/**
+ * Re-exported with an old name for backwards-compatibility.
+ * TODO (v8): Remove this
+ *
+ * @deprecated Use `timestampInSeconds` instead.
+ */
+const timestampWithMs = timestampInSeconds;
+
+/**
+ * A boolean that is true when timestampInSeconds uses the Performance API to produce monotonic timestamps.
+ */
+const usingPerformanceAPI = platformPerformance !== undefined;
+
+/**
+ * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only.
+ */
+let _browserPerformanceTimeOriginMode;
+
+/**
+ * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the
+ * performance API is available.
+ */
+const browserPerformanceTimeOrigin = (() => {
+ // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or
+ // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin
+ // data as reliable if they are within a reasonable threshold of the current time.
+
+ const { performance } = WINDOW;
+ if (!performance || !performance.now) {
+ _browserPerformanceTimeOriginMode = 'none';
+ return undefined;
+ }
+
+ const threshold = 3600 * 1000;
+ const performanceNow = performance.now();
+ const dateNow = Date.now();
+
+ // if timeOrigin isn't available set delta to threshold so it isn't used
+ const timeOriginDelta = performance.timeOrigin
+ ? Math.abs(performance.timeOrigin + performanceNow - dateNow)
+ : threshold;
+ const timeOriginIsReliable = timeOriginDelta < threshold;
+
+ // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
+ // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
+ // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
+ // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
+ // Date API.
+ // eslint-disable-next-line deprecation/deprecation
+ const navigationStart = performance.timing && performance.timing.navigationStart;
+ const hasNavigationStart = typeof navigationStart === 'number';
+ // if navigationStart isn't available set delta to threshold so it isn't used
+ const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;
+ const navigationStartIsReliable = navigationStartDelta < threshold;
+
+ if (timeOriginIsReliable || navigationStartIsReliable) {
+ // Use the more reliable time origin
+ if (timeOriginDelta <= navigationStartDelta) {
+ _browserPerformanceTimeOriginMode = 'timeOrigin';
+ return performance.timeOrigin;
+ } else {
+ _browserPerformanceTimeOriginMode = 'navigationStart';
+ return navigationStart;
+ }
+ }
+
+ // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.
+ _browserPerformanceTimeOriginMode = 'dateNow';
+ return dateNow;
+})();
+
+export { _browserPerformanceTimeOriginMode, browserPerformanceTimeOrigin, dateTimestampInSeconds, timestampInSeconds, timestampWithMs, usingPerformanceAPI };
+//# sourceMappingURL=time.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/tracing.js b/shared/logger/node_modules/@sentry/utils/esm/tracing.js
new file mode 100644
index 0000000..546507c
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/tracing.js
@@ -0,0 +1,39 @@
+const TRACEPARENT_REGEXP = new RegExp(
+ '^[ \\t]*' + // whitespace
+ '([0-9a-f]{32})?' + // trace_id
+ '-?([0-9a-f]{16})?' + // span_id
+ '-?([01])?' + // sampled
+ '[ \\t]*$', // whitespace
+);
+
+/**
+ * Extract transaction context data from a `sentry-trace` header.
+ *
+ * @param traceparent Traceparent string
+ *
+ * @returns Object containing data from the header, or undefined if traceparent string is malformed
+ */
+function extractTraceparentData(traceparent) {
+ const matches = traceparent.match(TRACEPARENT_REGEXP);
+
+ if (!traceparent || !matches) {
+ // empty string or no matches is invalid traceparent data
+ return undefined;
+ }
+
+ let parentSampled;
+ if (matches[3] === '1') {
+ parentSampled = true;
+ } else if (matches[3] === '0') {
+ parentSampled = false;
+ }
+
+ return {
+ traceId: matches[1],
+ parentSampled,
+ parentSpanId: matches[2],
+ };
+}
+
+export { TRACEPARENT_REGEXP, extractTraceparentData };
+//# sourceMappingURL=tracing.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/url.js b/shared/logger/node_modules/@sentry/utils/esm/url.js
new file mode 100644
index 0000000..2e0bd40
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/url.js
@@ -0,0 +1,72 @@
+/**
+ * Parses string form of URL into an object
+ * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
+ * // intentionally using regex and not <a/> href parsing trick because React Native and other
+ * // environments where DOM might not be available
+ * @returns parsed URL object
+ */
+function parseUrl(url) {
+ if (!url) {
+ return {};
+ }
+
+ const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
+
+ if (!match) {
+ return {};
+ }
+
+ // coerce to undefined values to empty string so we don't get 'undefined'
+ const query = match[6] || '';
+ const fragment = match[8] || '';
+ return {
+ host: match[4],
+ path: match[5],
+ protocol: match[2],
+ search: query,
+ hash: fragment,
+ relative: match[5] + query + fragment, // everything minus origin
+ };
+}
+
+/**
+ * Strip the query string and fragment off of a given URL or path (if present)
+ *
+ * @param urlPath Full URL or path, including possible query string and/or fragment
+ * @returns URL or path without query string or fragment
+ */
+function stripUrlQueryAndFragment(urlPath) {
+ // eslint-disable-next-line no-useless-escape
+ return urlPath.split(/[\?#]/, 1)[0];
+}
+
+/**
+ * Returns number of URL segments of a passed string URL.
+ */
+function getNumberOfUrlSegments(url) {
+ // split at '/' or at '\/' to split regex urls correctly
+ return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length;
+}
+
+/**
+ * Takes a URL object and returns a sanitized string which is safe to use as span description
+ * see: https://develop.sentry.dev/sdk/data-handling/#structuring-data
+ */
+function getSanitizedUrlString(url) {
+ const { protocol, host, path } = url;
+
+ const filteredHost =
+ (host &&
+ host
+ // Always filter out authority
+ .replace(/^.*@/, '[filtered]:[filtered]@')
+ // Don't show standard :80 (http) and :443 (https) ports to reduce the noise
+ .replace(':80', '')
+ .replace(':443', '')) ||
+ '';
+
+ return `${protocol ? `${protocol}://` : ''}${filteredHost}${path}`;
+}
+
+export { getNumberOfUrlSegments, getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment };
+//# sourceMappingURL=url.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/vendor/supportsHistory.js b/shared/logger/node_modules/@sentry/utils/esm/vendor/supportsHistory.js
new file mode 100644
index 0000000..cf33d64
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/vendor/supportsHistory.js
@@ -0,0 +1,29 @@
+import { getGlobalObject } from '../worldwide.js';
+
+// Based on https://github.com/angular/angular.js/pull/13945/files
+
+// eslint-disable-next-line deprecation/deprecation
+const WINDOW = getGlobalObject();
+
+/**
+ * Tells whether current environment supports History API
+ * {@link supportsHistory}.
+ *
+ * @returns Answer to the given question.
+ */
+function supportsHistory() {
+ // NOTE: in Chrome App environment, touching history.pushState, *even inside
+ // a try/catch block*, will cause Chrome to output an error to console.error
+ // borrowed from: https://github.com/angular/angular.js/pull/13945/files
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const chrome = (WINDOW ).chrome;
+ const isChromePackagedApp = chrome && chrome.app && chrome.app.runtime;
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access */
+ const hasHistoryApi = 'history' in WINDOW && !!WINDOW.history.pushState && !!WINDOW.history.replaceState;
+
+ return !isChromePackagedApp && hasHistoryApi;
+}
+
+export { supportsHistory };
+//# sourceMappingURL=supportsHistory.js.map
diff --git a/shared/logger/node_modules/@sentry/utils/esm/worldwide.js b/shared/logger/node_modules/@sentry/utils/esm/worldwide.js
new file mode 100644
index 0000000..4c54705
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/worldwide.js
@@ -0,0 +1,70 @@
+/** Internal global with common properties and Sentry extensions */
+
+// The code below for 'isGlobalObj' and 'GLOBAL_OBJ' was copied from core-js before modification
+// https://github.com/zloirock/core-js/blob/1b944df55282cdc99c90db5f49eb0b6eda2cc0a3/packages/core-js/internals/global.js
+// core-js has the following licence:
+//
+// Copyright (c) 2014-2022 Denis Pushkarev
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+/** Returns 'obj' if it's the global object, otherwise returns undefined */
+function isGlobalObj(obj) {
+ return obj && obj.Math == Math ? obj : undefined;
+}
+
+/** Get's the global object for the current JavaScript runtime */
+const GLOBAL_OBJ =
+ (typeof globalThis == 'object' && isGlobalObj(globalThis)) ||
+ // eslint-disable-next-line no-restricted-globals
+ (typeof window == 'object' && isGlobalObj(window)) ||
+ (typeof self == 'object' && isGlobalObj(self)) ||
+ (typeof global == 'object' && isGlobalObj(global)) ||
+ (function () {
+ return this;
+ })() ||
+ {};
+
+/**
+ * @deprecated Use GLOBAL_OBJ instead or WINDOW from @sentry/browser. This will be removed in v8
+ */
+function getGlobalObject() {
+ return GLOBAL_OBJ ;
+}
+
+/**
+ * Returns a global singleton contained in the global `__SENTRY__` object.
+ *
+ * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
+ * function and added to the `__SENTRY__` object.
+ *
+ * @param name name of the global singleton on __SENTRY__
+ * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
+ * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value
+ * @returns the singleton
+ */
+function getGlobalSingleton(name, creator, obj) {
+ const gbl = (obj || GLOBAL_OBJ) ;
+ const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});
+ const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
+ return singleton;
+}
+
+export { GLOBAL_OBJ, getGlobalObject, getGlobalSingleton };
+//# sourceMappingURL=worldwide.js.map