@rudderstack/analytics-js
Version:
RudderStack JavaScript SDK
598 lines (554 loc) • 408 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.rudderanalytics = {}));
})(this, (function (exports) { 'use strict';
function _isPlaceholder(a){return a!=null&&typeof a==='object'&&a['@@functional/placeholder']===true;}
/**
* Optimized internal one-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/function _curry1(fn){return function f1(a){if(arguments.length===0||_isPlaceholder(a)){return f1;}else {return fn.apply(this,arguments);}};}
/**
* Optimized internal two-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/function _curry2(fn){return function f2(a,b){switch(arguments.length){case 0:return f2;case 1:return _isPlaceholder(a)?f2:_curry1(function(_b){return fn(a,_b);});default:return _isPlaceholder(a)&&_isPlaceholder(b)?f2:_isPlaceholder(a)?_curry1(function(_a){return fn(_a,b);}):_isPlaceholder(b)?_curry1(function(_b){return fn(a,_b);}):fn(a,b);}};}
/**
* Optimized internal three-arity curry function.
*
* @private
* @category Function
* @param {Function} fn The function to curry.
* @return {Function} The curried function.
*/function _curry3(fn){return function f3(a,b,c){switch(arguments.length){case 0:return f3;case 1:return _isPlaceholder(a)?f3:_curry2(function(_b,_c){return fn(a,_b,_c);});case 2:return _isPlaceholder(a)&&_isPlaceholder(b)?f3:_isPlaceholder(a)?_curry2(function(_a,_c){return fn(_a,b,_c);}):_isPlaceholder(b)?_curry2(function(_b,_c){return fn(a,_b,_c);}):_curry1(function(_c){return fn(a,b,_c);});default:return _isPlaceholder(a)&&_isPlaceholder(b)&&_isPlaceholder(c)?f3:_isPlaceholder(a)&&_isPlaceholder(b)?_curry2(function(_a,_b){return fn(_a,_b,c);}):_isPlaceholder(a)&&_isPlaceholder(c)?_curry2(function(_a,_c){return fn(_a,b,_c);}):_isPlaceholder(b)&&_isPlaceholder(c)?_curry2(function(_b,_c){return fn(a,_b,_c);}):_isPlaceholder(a)?_curry1(function(_a){return fn(_a,b,c);}):_isPlaceholder(b)?_curry1(function(_b){return fn(a,_b,c);}):_isPlaceholder(c)?_curry1(function(_c){return fn(a,b,_c);}):fn(a,b,c);}};}
function _has(prop,obj){return Object.prototype.hasOwnProperty.call(obj,prop);}
/**
* Gives a single-word string description of the (native) type of a value,
* returning such answers as 'Object', 'Number', 'Array', or 'Null'. Does not
* attempt to distinguish user Object types any further, reporting them all as
* 'Object'.
*
* @func
* @memberOf R
* @since v0.8.0
* @category Type
* @sig * -> String
* @param {*} val The value to test
* @return {String}
* @example
*
* R.type({}); //=> "Object"
* R.type(1); //=> "Number"
* R.type(false); //=> "Boolean"
* R.type('s'); //=> "String"
* R.type(null); //=> "Null"
* R.type([]); //=> "Array"
* R.type(/[A-z]/); //=> "RegExp"
* R.type(() => {}); //=> "Function"
* R.type(async () => {}); //=> "AsyncFunction"
* R.type(undefined); //=> "Undefined"
* R.type(BigInt(123)); //=> "BigInt"
*/var type=/*#__PURE__*/_curry1(function type(val){return val===null?'Null':val===undefined?'Undefined':Object.prototype.toString.call(val).slice(8,-1);});
function _isObject(x){return Object.prototype.toString.call(x)==='[object Object]';}
/**
* Determine if the passed argument is an integer.
*
* @private
* @param {*} n
* @category Type
* @return {Boolean}
*/const _isInteger = Number.isInteger||function _isInteger(n){return n<<0===n;};
function _nth(offset,list){var idx=offset<0?list.length+offset:offset;return list[idx];}
function _cloneRegExp(pattern){return new RegExp(pattern.source,pattern.flags?pattern.flags:(pattern.global?'g':'')+(pattern.ignoreCase?'i':'')+(pattern.multiline?'m':'')+(pattern.sticky?'y':'')+(pattern.unicode?'u':'')+(pattern.dotAll?'s':''));}
/**
* Copies an object.
*
* @private
* @param {*} value The value to be copied
* @param {Boolean} deep Whether or not to perform deep cloning.
* @return {*} The copied value.
*/function _clone(value,deep,map){map||(map=new _ObjectMap());// this avoids the slower switch with a quick if decision removing some milliseconds in each run.
if(_isPrimitive(value)){return value;}var copy=function copy(copiedValue){// Check for circular and same references on the object graph and return its corresponding clone.
var cachedCopy=map.get(value);if(cachedCopy){return cachedCopy;}map.set(value,copiedValue);for(var key in value){if(Object.prototype.hasOwnProperty.call(value,key)){copiedValue[key]=_clone(value[key],true,map);}}return copiedValue;};switch(type(value)){case 'Object':return copy(Object.create(Object.getPrototypeOf(value)));case 'Array':return copy(Array(value.length));case 'Date':return new Date(value.valueOf());case 'RegExp':return _cloneRegExp(value);case 'Int8Array':case 'Uint8Array':case 'Uint8ClampedArray':case 'Int16Array':case 'Uint16Array':case 'Int32Array':case 'Uint32Array':case 'Float32Array':case 'Float64Array':case 'BigInt64Array':case 'BigUint64Array':return value.slice();default:return value;}}function _isPrimitive(param){var type=typeof param;return param==null||type!='object'&&type!='function';}var _ObjectMap=/*#__PURE__*/function(){function _ObjectMap(){this.map={};this.length=0;}_ObjectMap.prototype.set=function(key,value){var hashedKey=this.hash(key);var bucket=this.map[hashedKey];if(!bucket){this.map[hashedKey]=bucket=[];}bucket.push([key,value]);this.length+=1;};_ObjectMap.prototype.hash=function(key){var hashedKey=[];for(var value in key){hashedKey.push(Object.prototype.toString.call(key[value]));}return hashedKey.join();};_ObjectMap.prototype.get=function(key){/**
* depending on the number of objects to be cloned is faster to just iterate over the items in the map just because the hash function is so costly,
* on my tests this number is 180, anything above that using the hash function is faster.
*/if(this.length<=180){for(var p in this.map){var bucket=this.map[p];for(var i=0;i<bucket.length;i+=1){var element=bucket[i];if(element[0]===key){return element[1];}}}return;}var hashedKey=this.hash(key);var bucket=this.map[hashedKey];if(!bucket){return;}for(var i=0;i<bucket.length;i+=1){var element=bucket[i];if(element[0]===key){return element[1];}}};return _ObjectMap;}();
/**
* Creates a deep copy of the source that can be used in place of the source
* object without retaining any references to it.
* The source object may contain (nested) `Array`s and `Object`s,
* `Number`s, `String`s, `Boolean`s and `Date`s.
* `Function`s are assigned by reference rather than copied.
*
* Dispatches to a `clone` method if present.
*
* Note that if the source object has multiple nodes that share a reference,
* the returned object will have the same structure, but the references will
* be pointed to the location within the cloned value.
*
* @func
* @memberOf R
* @since v0.1.0
* @category Object
* @sig {*} -> {*}
* @param {*} value The object or array to clone
* @return {*} A deeply cloned copy of `val`
* @example
*
* const objects = [{}, {}, {}];
* const objectsClone = R.clone(objects);
* objects === objectsClone; //=> false
* objects[0] === objectsClone[0]; //=> false
*/var clone=/*#__PURE__*/_curry1(function clone(value){return value!=null&&typeof value.clone==='function'?value.clone():_clone(value);});
function _path(pathAr,obj){var val=obj;for(var i=0;i<pathAr.length;i+=1){if(val==null){return undefined;}var p=pathAr[i];if(_isInteger(p)){val=_nth(p,val);}else {val=val[p];}}return val;}
/**
* Creates a new object with the own properties of the two provided objects. If
* a key exists in both objects, the provided function is applied to the key
* and the values associated with the key in each object, with the result being
* used as the value associated with the key in the returned object.
*
* @func
* @memberOf R
* @since v0.19.0
* @category Object
* @sig ((String, a, a) -> a) -> {a} -> {a} -> {a}
* @param {Function} fn
* @param {Object} l
* @param {Object} r
* @return {Object}
* @see R.mergeDeepWithKey, R.mergeWith
* @example
*
* let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r
* R.mergeWithKey(concatValues,
* { a: true, thing: 'foo', values: [10, 20] },
* { b: true, thing: 'bar', values: [15, 35] });
* //=> { a: true, b: true, thing: 'bar', values: [10, 20, 15, 35] }
* @symb R.mergeWithKey(f, { x: 1, y: 2 }, { y: 5, z: 3 }) = { x: 1, y: f('y', 2, 5), z: 3 }
*/var mergeWithKey=/*#__PURE__*/_curry3(function mergeWithKey(fn,l,r){var result={};var k;l=l||{};r=r||{};for(k in l){if(_has(k,l)){result[k]=_has(k,r)?fn(k,l[k],r[k]):l[k];}}for(k in r){if(_has(k,r)&&!_has(k,result)){result[k]=r[k];}}return result;});
/**
* Creates a new object with the own properties of the two provided objects.
* If a key exists in both objects:
* - and both associated values are also objects then the values will be
* recursively merged.
* - otherwise the provided function is applied to the key and associated values
* using the resulting value as the new value associated with the key.
* If a key only exists in one object, the value will be associated with the key
* of the resulting object.
*
* @func
* @memberOf R
* @since v0.24.0
* @category Object
* @sig ((String, a, a) -> a) -> {a} -> {a} -> {a}
* @param {Function} fn
* @param {Object} lObj
* @param {Object} rObj
* @return {Object}
* @see R.mergeWithKey, R.mergeDeepWith
* @example
*
* let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r
* R.mergeDeepWithKey(concatValues,
* { a: true, c: { thing: 'foo', values: [10, 20] }},
* { b: true, c: { thing: 'bar', values: [15, 35] }});
* //=> { a: true, b: true, c: { thing: 'bar', values: [10, 20, 15, 35] }}
*/var mergeDeepWithKey=/*#__PURE__*/_curry3(function mergeDeepWithKey(fn,lObj,rObj){return mergeWithKey(function(k,lVal,rVal){if(_isObject(lVal)&&_isObject(rVal)){return mergeDeepWithKey(fn,lVal,rVal);}else {return fn(k,lVal,rVal);}},lObj,rObj);});
/**
* Creates a new object with the own properties of the two provided objects.
* If a key exists in both objects:
* - and both associated values are also objects then the values will be
* recursively merged.
* - otherwise the provided function is applied to associated values using the
* resulting value as the new value associated with the key.
* If a key only exists in one object, the value will be associated with the key
* of the resulting object.
*
* @func
* @memberOf R
* @since v0.24.0
* @category Object
* @sig ((a, a) -> a) -> {a} -> {a} -> {a}
* @param {Function} fn
* @param {Object} lObj
* @param {Object} rObj
* @return {Object}
* @see R.mergeWith, R.mergeDeepWithKey
* @example
*
* R.mergeDeepWith(R.concat,
* { a: true, c: { values: [10, 20] }},
* { b: true, c: { values: [15, 35] }});
* //=> { a: true, b: true, c: { values: [10, 20, 15, 35] }}
*/var mergeDeepWith=/*#__PURE__*/_curry3(function mergeDeepWith(fn,lObj,rObj){return mergeDeepWithKey(function(k,lVal,rVal){return fn(lVal,rVal);},lObj,rObj);});
/**
* Retrieves the value at a given path. The nodes of the path can be arbitrary strings or non-negative integers.
* For anything else, the value is unspecified. Integer paths are meant to index arrays, strings are meant for objects.
*
* @func
* @memberOf R
* @since v0.2.0
* @category Object
* @typedefn Idx = String | Int | Symbol
* @sig [Idx] -> {a} -> a | Undefined
* @sig Idx = String | NonNegativeInt
* @param {Array} path The path to use.
* @param {Object} obj The object or array to retrieve the nested property from.
* @return {*} The data at `path`.
* @see R.prop, R.nth, R.assocPath, R.dissocPath
* @example
*
* R.path(['a', 'b'], {a: {b: 2}}); //=> 2
* R.path(['a', 'b'], {c: {b: 2}}); //=> undefined
* R.path(['a', 'b', 0], {a: {b: [1, 2, 3]}}); //=> 1
* R.path(['a', 'b', -2], {a: {b: [1, 2, 3]}}); //=> 2
* R.path([2], {'2': 2}); //=> 2
* R.path([-2], {'-2': 'a'}); //=> undefined
*/var path=/*#__PURE__*/_curry2(_path);
/**
* Returns a partial copy of an object containing only the keys that satisfy
* the supplied predicate.
*
* @func
* @memberOf R
* @since v0.8.0
* @category Object
* @sig ((v, k) -> Boolean) -> {k: v} -> {k: v}
* @param {Function} pred A predicate to determine whether or not a key
* should be included on the output object.
* @param {Object} obj The object to copy from
* @return {Object} A new object with only properties that satisfy `pred`
* on it.
* @see R.pick, R.filter
* @example
*
* const isUpperCase = (val, key) => key.toUpperCase() === key;
* R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); //=> {A: 3, B: 4}
*/var pickBy=/*#__PURE__*/_curry2(function pickBy(test,obj){var result={};for(var prop in obj){if(test(obj[prop],prop,obj)){result[prop]=obj[prop];}}return result;});
/**
* A function to check given value is a function
* @param value input value
* @returns boolean
*/const isFunction=value=>typeof value==='function'&&Boolean(value.constructor&&value.call&&value.apply);/**
* A function to check given value is a string
* @param value input value
* @returns boolean
*/const isString=value=>typeof value==='string';/**
* A function to check given value is null or not
* @param value input value
* @returns boolean
*/const isNull=value=>value===null;/**
* A function to check given value is undefined
* @param value input value
* @returns boolean
*/const isUndefined=value=>typeof value==='undefined';/**
* A function to check given value is null or undefined
* @param value input value
* @returns boolean
*/const isNullOrUndefined=value=>isNull(value)||isUndefined(value);/**
* Checks if the input is a BigInt
* @param value input value
* @returns True if the input is a BigInt
*/const isBigInt=value=>typeof value==='bigint';/**
* A function to check given value is defined
* @param value input value
* @returns boolean
*/const isDefined=value=>!isUndefined(value);/**
* A function to check given value is defined and not null
* @param value input value
* @returns boolean
*/const isDefinedAndNotNull=value=>!isNullOrUndefined(value);/**
* A function to check given value is defined and not null
* @param value input value
* @returns boolean
*/const isDefinedNotNullAndNotEmptyString=value=>isDefinedAndNotNull(value)&&value!=='';/**
* Determines if the input is of type error
* @param value input value
* @returns true if the input is of type error else false
*/const isTypeOfError=value=>{switch(Object.prototype.toString.call(value)){case '[object Error]':case '[object Exception]':case '[object DOMException]':return true;default:return value instanceof Error;}};/**
* A function to check given value is a boolean
* @param value input value
* @returns boolean
*/const isBoolean=value=>typeof value==='boolean';
const getValueByPath=(obj,keyPath)=>{const pathParts=keyPath.split('.');return path(pathParts,obj);};const hasValueByPath=(obj,path)=>Boolean(getValueByPath(obj,path));const isObject=value=>typeof value==='object';/**
* Checks if the input is an object literal or built-in object type and not null
* @param value Input value
* @returns true if the input is an object and not null
*/const isObjectAndNotNull=value=>!isNull(value)&&isObject(value)&&!Array.isArray(value);/**
* Checks if the input is an object literal and not null
* @param value Input value
* @returns true if the input is an object and not null
*/const isObjectLiteralAndNotNull=value=>!isNull(value)&&Object.prototype.toString.call(value)==='[object Object]';/**
* Merges two arrays deeply, right-to-left
* In the case of conflicts, the right array's values replace the left array's values in the
* same index position
* @param leftValue - The left array
* @param rightValue - The right array
* @returns The merged array
*/const mergeDeepRightObjectArrays=(leftValue,rightValue)=>{if(!Array.isArray(leftValue)||!Array.isArray(rightValue)){return clone(rightValue);}const mergedArray=clone(leftValue);rightValue.forEach((value,index)=>{mergedArray[index]=Array.isArray(value)||isObjectAndNotNull(value)?// eslint-disable-next-line @typescript-eslint/no-use-before-define
mergeDeepRight(mergedArray[index],value):value;});return mergedArray;};/**
* Merges two objects deeply, right-to-left.
* In the case of conflicts, the right object's values take precedence.
* For arrays, the right array's values replace the left array's values in the
* same index position keeping the remaining left array's values in the resultant array.
* @param leftObject - The left object
* @param rightObject - The right object
* @returns The merged object
*/const mergeDeepRight=(leftObject,rightObject)=>mergeDeepWith(mergeDeepRightObjectArrays,leftObject,rightObject);/**
Checks if the input is a non-empty object literal type and not undefined or null
* @param value input any
* @returns boolean
*/const isNonEmptyObject=value=>isObjectLiteralAndNotNull(value)&&Object.keys(value).length>0;/**
* A utility to recursively remove undefined values from an object
* @param obj input object
* @returns a new object
*/const removeUndefinedValues=obj=>{const result=pickBy(isDefined,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedValues(value);}});return result;};/**
* A utility to recursively remove undefined and null values from an object
* @param obj input object
* @returns a new object
*/const removeUndefinedAndNullValues=obj=>{const result=pickBy(isDefinedAndNotNull,obj);Object.keys(result).forEach(key=>{const value=result[key];if(isObjectLiteralAndNotNull(value)){result[key]=removeUndefinedAndNullValues(value);}});return result;};/**
* Normalizes an object by removing undefined and null values.
* @param val - The value to normalize
* @returns The normalized object, or undefined if input is not a non-empty object
* @example
* getNormalizedObjectValue({ a: 1, b: null, c: undefined }) // returns { a: 1 }
* getNormalizedObjectValue({}) // returns undefined
* getNormalizedObjectValue(null) // returns undefined
*/const getNormalizedObjectValue=val=>{if(!isNonEmptyObject(val)){return undefined;}return removeUndefinedAndNullValues(val);};/**
* Normalizes a value to a boolean, with support for a default value
* @param val Input value
* @param defVal Default value
* @returns Returns the input value if it is a boolean, otherwise returns the default value
* @example
* getNormalizedBooleanValue(true, false) // returns true
*/const getNormalizedBooleanValue=(val,defVal)=>typeof val==='boolean'?val:defVal;
const trim=value=>value.replace(/^\s+|\s+$/gm,'');const removeLeadingPeriod=value=>value.replace(/^\.+/,'');/**
* A function to convert values to string
* @param val input value
* @returns stringified value
*/const tryStringify=val=>{let retVal=val;if(!isString(val)&&!isNullOrUndefined(val)){try{retVal=JSON.stringify(val);}catch(e){retVal=null;}}return retVal;};// The following text encoding and decoding is done before base64 encoding to prevent
// https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
/**
* Converts a base64 encoded string to bytes array
* @param base64Str base64 encoded string
* @returns bytes array
*/const base64ToBytes=base64Str=>{const binString=globalThis.atob(base64Str);const bytes=binString.split('').map(char=>char.charCodeAt(0));return new Uint8Array(bytes);};/**
* Converts a bytes array to base64 encoded string
* @param bytes bytes array to be converted to base64
* @returns base64 encoded string
*/const bytesToBase64=bytes=>{const binString=Array.from(bytes,x=>String.fromCodePoint(x)).join('');return globalThis.btoa(binString);};/**
* Encodes a string to base64 even with unicode characters
* @param value input string
* @returns base64 encoded string
*/const toBase64=value=>bytesToBase64(new TextEncoder().encode(value));/**
* Decodes a base64 encoded string
* @param value base64 encoded string
* @returns decoded string
*/const fromBase64=value=>new TextDecoder().decode(base64ToBytes(value));
// if yes make them null instead of omitting in overloaded cases
/*
* Normalise the overloaded arguments of the page call facade
*/const pageArgumentsToCallOptions=(category,name,properties,options,callback)=>{const payload={category:category,name:name,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.category=category;payload.name=name;payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.category=category;payload.name=name;payload.properties=undefined;payload.options=undefined;payload.callback=properties;}if(isFunction(name)){payload.category=category;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=name;}if(isFunction(category)){payload.category=undefined;payload.name=undefined;payload.properties=undefined;payload.options=undefined;payload.callback=category;}if(isObjectLiteralAndNotNull(category)){payload.name=undefined;payload.category=undefined;payload.properties=category;if(!isFunction(name)){payload.options=name;}else {payload.options=undefined;}}else if(isObjectLiteralAndNotNull(name)){payload.name=undefined;payload.properties=name;if(!isFunction(properties)){payload.options=properties;}else {payload.options=undefined;}}// if the category argument alone is provided b/w category and name,
// use it as name and set category to undefined
if(isString(category)&&!isString(name)){payload.category=undefined;payload.name=category;}// Rest of the code is just to clean up undefined values
// and set some proper defaults
// Also, to clone the incoming object type arguments
if(!isDefined(payload.category)){payload.category=undefined;}if(!isDefined(payload.name)){payload.name=undefined;}payload.properties=payload.properties?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}const nameForProperties=isString(payload.name)?payload.name:payload.properties.name;const categoryForProperties=isString(payload.category)?payload.category:payload.properties.category;// add name and category to properties
payload.properties=mergeDeepRight(isObjectLiteralAndNotNull(payload.properties)?payload.properties:{},{...(nameForProperties&&{name:nameForProperties}),...(categoryForProperties&&{category:categoryForProperties})});return payload;};/*
* Normalise the overloaded arguments of the track call facade
*/const trackArgumentsToCallOptions=(event,properties,options,callback)=>{const payload={name:event,properties:properties,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.properties=properties;payload.options=undefined;payload.callback=options;}if(isFunction(properties)){payload.properties=undefined;payload.options=undefined;payload.callback=properties;}// Rest of the code is just to clean up undefined values
// and set some proper defaults
// Also, to clone the incoming object type arguments
payload.properties=isDefinedAndNotNull(payload.properties)?clone(payload.properties):{};if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
* Normalise the overloaded arguments of the identify call facade
*/const identifyArgumentsToCallOptions=(userId,traits,options,callback)=>{const payload={userId:userId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.userId=userId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.userId=userId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(userId)||isNull(userId)){// Explicitly set null to prevent resetting the existing value
// in the Analytics class
payload.userId=null;payload.traits=userId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
// and set some proper defaults
// Also, to clone the incoming object type arguments
payload.userId=tryStringify(payload.userId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
* Normalise the overloaded arguments of the alias call facade
*/const aliasArgumentsToCallOptions=(to,from,options,callback)=>{const payload={to,from:from,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.to=to;payload.from=from;payload.options=undefined;payload.callback=options;}if(isFunction(from)){payload.to=to;payload.from=undefined;payload.options=undefined;payload.callback=from;}else if(isObjectLiteralAndNotNull(from)||isNull(from)){payload.to=to;payload.from=undefined;payload.options=from;}// Rest of the code is just to clean up undefined values
// and set some proper defaults
// Also, to clone the incoming object type arguments
if(isDefined(payload.to)){payload.to=tryStringify(payload.to);}if(isDefined(payload.from)){payload.from=tryStringify(payload.from);}else {payload.from=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};/*
* Normalise the overloaded arguments of the group call facade
*/const groupArgumentsToCallOptions=(groupId,traits,options,callback)=>{const payload={groupId:groupId,traits:traits,options:options,callback:undefined};if(isFunction(callback)){payload.callback=callback;}if(isFunction(options)){payload.groupId=groupId;payload.traits=traits;payload.options=undefined;payload.callback=options;}if(isFunction(traits)){payload.groupId=groupId;payload.traits=undefined;payload.options=undefined;payload.callback=traits;}if(isObjectLiteralAndNotNull(groupId)||isNull(groupId)){// Explicitly set null to prevent resetting the existing value
// in the Analytics class
payload.groupId=null;payload.traits=groupId;if(!isFunction(traits)){payload.options=traits;}else {payload.options=undefined;}}// Rest of the code is just to clean up undefined values
// and set some proper defaults
// Also, to clone the incoming object type arguments
payload.groupId=tryStringify(payload.groupId);if(isObjectLiteralAndNotNull(payload.traits)){payload.traits=clone(payload.traits);}else {payload.traits=undefined;}if(isDefined(payload.options)){payload.options=clone(payload.options);}else {payload.options=undefined;}return payload;};
/**
* Represents the options parameter for anonymousId
*//**
* Represents the beacon queue options parameter in loadOptions type
*//**
* Represents the queue options parameter in loadOptions type
*//**
* Represents the destinations queue options parameter in loadOptions type
*/let PageLifecycleEvents=/*#__PURE__*/function(PageLifecycleEvents){PageLifecycleEvents["UNLOADED"]="Page Unloaded";return PageLifecycleEvents;}({});/**
* Represents the source configuration override options for destinations
*//**
* Represents the options parameter in the load API
*/
const API_SUFFIX='API';const CAPABILITIES_MANAGER='CapabilitiesManager';const CONFIG_MANAGER='ConfigManager';const EVENT_MANAGER='EventManager';const PLUGINS_MANAGER='PluginsManager';const USER_SESSION_MANAGER='UserSessionManager';const ERROR_HANDLER='ErrorHandler';const PLUGIN_ENGINE='PluginEngine';const STORE_MANAGER='StoreManager';const READY_API=`Ready${API_SUFFIX}`;const LOAD_API=`Load${API_SUFFIX}`;const HTTP_CLIENT='HttpClient';const RSA='RudderStackAnalytics';const ANALYTICS_CORE='AnalyticsCore';
function random(len){return crypto.getRandomValues(new Uint8Array(len));}
var SIZE=4096,HEX$1=[],IDX$1=0,BUFFER$1;for(;IDX$1<256;IDX$1++){HEX$1[IDX$1]=(IDX$1+256).toString(16).substring(1);}function v4$1(){if(!BUFFER$1||IDX$1+16>SIZE){BUFFER$1=random(SIZE);IDX$1=0;}var i=0,tmp,out='';for(;i<16;i++){tmp=BUFFER$1[IDX$1+i];if(i==6)out+=HEX$1[tmp&15|64];else if(i==8)out+=HEX$1[tmp&63|128];else out+=HEX$1[tmp];if(i&1&&i>1&&i<11)out+='-';}IDX$1+=16;return out;}
var IDX=256,HEX=[],BUFFER;while(IDX--)HEX[IDX]=(IDX+256).toString(16).substring(1);function v4(){var i=0,num,out='';if(!BUFFER||IDX+16>256){BUFFER=Array(i=256);while(i--)BUFFER[i]=256*Math.random()|0;i=IDX=0;}for(;i<16;i++){num=BUFFER[IDX+i];if(i==6)out+=HEX[num&15|64];else if(i==8)out+=HEX[num&63|128];else out+=HEX[num];if(i&1&&i>1&&i<11)out+='-';}IDX++;return out;}
const hasCrypto$1=()=>!isNullOrUndefined(globalThis.crypto)&&isFunction(globalThis.crypto.getRandomValues);
const generateUUID=()=>{if(hasCrypto$1()){return v4$1();}return v4();};
const onPageLeave=callback=>{// To ensure the callback is only called once even if more than one events
// are fired at once.
let pageLeft=false;let isAccessible=false;function handleOnLeave(){if(pageLeft){return;}pageLeft=true;callback(isAccessible);// Reset pageLeft on the next tick
// to ensure callback executes for other listeners
// when closing an inactive browser tab.
setTimeout(()=>{pageLeft=false;},0);}// Catches the unloading of the page (e.g., closing the tab or navigating away).
// Includes user actions like clicking a link, entering a new URL,
// refreshing the page, or closing the browser tab
// Note that 'pagehide' is not supported in IE.
// So, this is a fallback.
globalThis.addEventListener('beforeunload',()=>{isAccessible=false;handleOnLeave();});globalThis.addEventListener('blur',()=>{isAccessible=true;handleOnLeave();});globalThis.addEventListener('focus',()=>{pageLeft=false;});// Catches the page being hidden, including scenarios like closing the tab.
document.addEventListener('pagehide',()=>{isAccessible=document.visibilityState==='hidden';handleOnLeave();});// Catches visibility changes, such as switching tabs or minimizing the browser.
document.addEventListener('visibilitychange',()=>{isAccessible=true;if(document.visibilityState==='hidden'){handleOnLeave();}else {pageLeft=false;}});};
const getFormattedTimestamp=date=>date.toISOString();/**
* To get the current timestamp in ISO string format
* @returns ISO formatted timestamp string
*/const getCurrentTimeFormatted=()=>getFormattedTimestamp(new Date());
const LOG_CONTEXT_SEPARATOR=':: ';const SCRIPT_ALREADY_EXISTS_ERROR=id=>`A script with the id "${id}" is already loaded. Skipping the loading of this script to prevent conflicts`;const SCRIPT_LOAD_ERROR=(id,url,ev)=>`Unable to load (${isString(ev)?ev:ev.type}) the script with the id "${id}" from URL "${url}"`;const SCRIPT_LOAD_TIMEOUT_ERROR=(id,url,timeout)=>`A timeout of ${timeout} ms occurred while trying to load the script with id "${id}" from URL "${url}"`;const CIRCULAR_REFERENCE_WARNING=(context,key)=>`${context}${LOG_CONTEXT_SEPARATOR}A circular reference has been detected in the object and the property "${key}" has been dropped from the output.`;const JSON_STRINGIFY_WARNING=`Failed to convert the value to a JSON string.`;const COOKIE_DATA_ENCODING_ERROR=`Failed to encode the cookie data.`;
const JSON_STRINGIFY='JSONStringify';const BIG_INT_PLACEHOLDER='[BigInt]';const CIRCULAR_REFERENCE_PLACEHOLDER='[Circular Reference]';const getCircularReplacer=(excludeNull,excludeKeys,logger)=>{const ancestors=[];// Here we do not want to use arrow function to use "this" in function context
// eslint-disable-next-line func-names
return function(key,value){if(excludeKeys?.includes(key)){return undefined;}if(excludeNull&&isNullOrUndefined(value)){return undefined;}if(typeof value!=='object'||isNull(value)){return value;}// `this` is the object that value is contained in, i.e., its direct parent.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-next-line
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();}if(ancestors.includes(value)){logger?.warn(CIRCULAR_REFERENCE_WARNING(JSON_STRINGIFY,key));return CIRCULAR_REFERENCE_PLACEHOLDER;}ancestors.push(value);return value;};};/**
* Utility method for JSON stringify object excluding null values & circular references
*
* @param {*} value input
* @param {boolean} excludeNull if it should exclude nul or not
* @param {function} logger optional logger methods for warning
* @returns string
*/const stringifyWithoutCircular=(value,excludeNull,excludeKeys,logger)=>{try{return JSON.stringify(value,getCircularReplacer(excludeNull,excludeKeys,logger));}catch(err){logger?.warn(JSON_STRINGIFY_WARNING,err);return null;}};const getReplacer=logger=>{const ancestors=[];// Array to track ancestor objects
// Using a regular function to use `this` for the parent context
return function replacer(key,value){if(isBigInt(value)){return BIG_INT_PLACEHOLDER;// Replace BigInt values
}// `this` is the object that value is contained in, i.e., its direct parent.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-next-line
while(ancestors.length>0&&ancestors[ancestors.length-1]!==this){ancestors.pop();// Remove ancestors that are no longer part of the chain
}// Check for circular references (if the value is already in the ancestors)
if(ancestors.includes(value)){return CIRCULAR_REFERENCE_PLACEHOLDER;}// Add current value to ancestors
ancestors.push(value);return value;};};const traverseWithThis=(obj,replacer)=>{// Create a new result object or array
const result=Array.isArray(obj)?[]:{};// Traverse object properties or array elements
// eslint-disable-next-line no-restricted-syntax
for(const key in obj){if(Object.hasOwnProperty.call(obj,key)){const value=obj[key];// Recursively apply the replacer and traversal
const sanitizedValue=replacer.call(obj,key,value);// If the value is an object or array, continue traversal
if(isObjectLiteralAndNotNull(sanitizedValue)||Array.isArray(sanitizedValue)){result[key]=traverseWithThis(sanitizedValue,replacer);}else {result[key]=sanitizedValue;}}}return result;};/**
* Recursively traverses an object similar to JSON.stringify,
* sanitizing BigInts and circular references
* @param value Input object
* @param logger Logger instance
* @returns Sanitized value
*/const getSanitizedValue=(value,logger)=>{const replacer=getReplacer();// This is needed for registering the first ancestor
const newValue=replacer.call(value,'',value);if(isObjectLiteralAndNotNull(value)||Array.isArray(value)){return traverseWithThis(value,replacer);}return newValue;};
const MANUAL_ERROR_IDENTIFIER='[SDK DISPATCHED ERROR]';const getStacktrace=err=>{const{stack,stacktrace,'opera#sourceloc':operaSourceloc}=err;const stackString=stack??stacktrace??operaSourceloc;if(!!stackString&&typeof stackString==='string'){return stackString;}return undefined;};/**
* Get mutated error with issue prepended to error message
* @param err Original error
* @param issue Issue to prepend to error message
* @returns Instance of Error with message prepended with issue
*/const getMutatedError=(err,issue)=>{if(!isTypeOfError(err)){return new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}try{// Preserve the specific error type (TypeError, ReferenceError, etc.)
const ErrorConstructor=err.constructor;const newError=new ErrorConstructor(`${issue}: ${err.message}`);// Preserve stack trace
const stack=getStacktrace(err);if(stack){newError.stack=stack;}// Preserve any other enumerable properties
Object.getOwnPropertyNames(err).forEach(key=>{if(key!=='message'&&key!=='stack'&&key!=='name'){try{newError[key]=err[key];}catch{// Ignore if property is not writable
}}});return newError;}catch{return new Error(`${issue}: ${stringifyWithoutCircular(err)}`);}};const dispatchErrorEvent=error=>{if(isTypeOfError(error)){const errStack=getStacktrace(error);if(errStack){const{stack,stacktrace,'opera#sourceloc':operaSourceloc}=error;switch(errStack){case stack:// eslint-disable-next-line no-param-reassign
error.stack=`${stack}\n${MANUAL_ERROR_IDENTIFIER}`;break;case stacktrace:// eslint-disable-next-line no-param-reassign
error.stacktrace=`${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`;break;case operaSourceloc:default:// eslint-disable-next-line no-param-reassign
error['opera#sourceloc']=`${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`;break;}}}globalThis.dispatchEvent(new ErrorEvent('error',{error,bubbles:true,cancelable:true,composed:true}));};
const APP_NAME='RudderLabs JavaScript SDK';const APP_VERSION='3.23.0';const APP_NAMESPACE='com.rudderlabs.javascript';const MODULE_TYPE='npm';const ADBLOCK_PAGE_CATEGORY='RudderJS-Initiated';const ADBLOCK_PAGE_NAME='ad-block page request';const ADBLOCK_PAGE_PATH='/ad-blocked';const GLOBAL_PRELOAD_BUFFER='preloadedEventsBuffer';const CONSENT_TRACK_EVENT_NAME='Consent Management Interaction';
const QUERY_PARAM_TRAIT_PREFIX='ajs_trait_';const QUERY_PARAM_PROPERTY_PREFIX='ajs_prop_';const QUERY_PARAM_ANONYMOUS_ID_KEY='ajs_aid';const QUERY_PARAM_USER_ID_KEY='ajs_uid';const QUERY_PARAM_TRACK_EVENT_NAME_KEY='ajs_event';
const DEFAULT_XHR_TIMEOUT_MS=10*1000;// 10 seconds
const DEFAULT_COOKIE_MAX_AGE_MS=31536000*1000;// 1 year
const DEFAULT_SESSION_CUT_OFF_DURATION_MS=12*60*60*1000;// 12 hours
const DEFAULT_SESSION_TIMEOUT_MS=30*60*1000;// 30 minutes
const MIN_SESSION_TIMEOUT_MS=10*1000;// 10 seconds
const DEFAULT_DATA_PLANE_EVENTS_BUFFER_TIMEOUT_MS=10*1000;// 10 seconds
const DEBOUNCED_TIMEOUT_MS=250;// 250 milliseconds
/**
* Create globally accessible RudderStackGlobals object
*/const createExposedGlobals=(analyticsInstanceId='app')=>{if(!globalThis.RudderStackGlobals){globalThis.RudderStackGlobals={};}if(!globalThis.RudderStackGlobals[analyticsInstanceId]){globalThis.RudderStackGlobals[analyticsInstanceId]={};}};/**
* Add move values to globally accessible RudderStackGlobals object per analytics instance
*/const setExposedGlobal=(keyName,value,analyticsInstanceId='app')=>{createExposedGlobals(analyticsInstanceId);globalThis.RudderStackGlobals[analyticsInstanceId][keyName]=value;};/**
* Get values from globally accessible RudderStackGlobals object by analytics instance
*/const getExposedGlobal=(keyName,analyticsInstanceId='app')=>{createExposedGlobals(analyticsInstanceId);return globalThis.RudderStackGlobals[analyticsInstanceId][keyName];};function debounce(func,thisArg,delay=DEBOUNCED_TIMEOUT_MS){let timeoutId;return (...args)=>{globalThis.clearTimeout(timeoutId);timeoutId=globalThis.setTimeout(()=>{func.apply(thisArg,args);},delay);};}
/**
* Parse query string params into object values for keys that start with a defined prefix
*/const getEventDataFromQueryString=(params,dataTypeNamePrefix)=>{const data={};params.forEach((value,key)=>{if(key.startsWith(dataTypeNamePrefix)){// remove prefix from key name
const dataKey=key.substring(dataTypeNamePrefix.length);// add new key value pair in generated object
data[dataKey]=params.get(key);}});return data;};/**
* Parse query string into preload buffer events & push into existing array before any other events
*/const retrieveEventsFromQueryString=(argumentsArray=[])=>{// Mapping for trait and properties values based on key prefix
const eventArgumentToQueryParamMap={trait:QUERY_PARAM_TRAIT_PREFIX,properties:QUERY_PARAM_PROPERTY_PREFIX};const queryObject=new URLSearchParams(globalThis.location.search);// Add track events with name and properties
if(queryObject.get(QUERY_PARAM_TRACK_EVENT_NAME_KEY)){argumentsArray.unshift(['track',queryObject.get(QUERY_PARAM_TRACK_EVENT_NAME_KEY),getEventDataFromQueryString(queryObject,eventArgumentToQueryParamMap.properties)]);}// Set userId and user traits
if(queryObject.get(QUERY_PARAM_USER_ID_KEY)){argumentsArray.unshift(['identify',queryObject.get(QUERY_PARAM_USER_ID_KEY),getEventDataFromQueryString(queryObject,eventArgumentToQueryParamMap.trait)]);}// Set anonymousID
if(queryObject.get(QUERY_PARAM_ANONYMOUS_ID_KEY)){argumentsArray.unshift(['setAnonymousId',queryObject.get(QUERY_PARAM_ANONYMOUS_ID_KEY)]);}};/**
* Retrieve an existing buffered load method call and remove from the existing array
*/const getPreloadedLoadEvent=preloadedEventsArray=>{const loadMethodName='load';let loadEvent=[];/**
* Iterate the buffered API calls until we find load call and process it separately
*/let i=0;while(i<preloadedEventsArray.length){if(preloadedEventsArray[i]&&preloadedEventsArray[i][0]===loadMethodName){loadEvent=clone(preloadedEventsArray[i]);preloadedEventsArray.splice(i,1);break;}i+=1;}return loadEvent;};/**
* Promote consent events to the top of the preloaded events array
* @param preloadedEventsArray Preloaded events array
* @returns None
*/const promotePreloadedConsentEventsToTop=preloadedEventsArray=>{const consentMethodName='consent';const consentEvents=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]===consentMethodName);const nonConsentEvents=preloadedEventsArray.filter(bufferedEvent=>bufferedEvent[0]!==consentMethodName);// Remove all elements and add consent events first followed by non consent events
// eslint-disable-next-line unicorn/no-useless-spread
preloadedEventsArray.splice(0,preloadedEventsArray.length,...consentEvents,...nonConsentEvents);};/**
* Retrieve any existing events that were triggered before SDK load and enqueue in buffer
*/const retrievePreloadBufferEvents=instance=>{const preloadedEventsArray=getExposedGlobal(GLOBAL_PRELOAD_BUFFER)||[];// Get events that are pre-populated via query string params
retrieveEventsFromQueryString(preloadedEventsArray);// Enqueue the non load events in the buffer of the global rudder analytics singleton
if(preloadedEventsArray.length>0){instance.enqueuePreloadBufferEvents(preloadedEventsArray);setExposedGlobal(GLOBAL_PRELOAD_BUFFER,[]);}};const consumePreloadBufferedEvent=(event,analyticsInstance)=>{const methodName=event.shift();let callOptions;if(isFunction(analyticsInstance[methodName])){switch(methodName){case 'page':callOptions=pageArgumentsToCallOptions(...event);break;case 'track':callOptions=trackArgumentsToCallOptions(...event);break;case 'identify':callOptions=identifyArgumentsToCallOptions(...event);break;case 'alias':callOptions=aliasArgumentsToCallOptions(...event);break;case 'group':callOptions=groupArgumentsToCallOptions(...event);break;default:analyticsInstance[methodName](...event);break;}if(callOptions){analyticsInstance[methodName](callOptions);}}};
const DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS=10*1000;// 10 seconds
const EXTERNAL_SOURCE_LOAD_ORIGIN='RS_JS_SDK';
/**
* Create the DOM element to load a script marked as RS SDK originated
*
* @param {*} url The URL of the script to be loaded
* @param {*} id ID for the script tag
* @param {*} async Whether to load the script in async mode. Defaults to `true` [optional]
* @param {*} onload callback to invoke onload [optional]
* @param {*} onerror callback to invoke onerror [optional]
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
*
* @returns HTMLScriptElement
*/const createScriptElement=(url,id,async=true,onload=null,onerror=null,extraAttributes={})=>{const scriptElement=document.createElement('script');scriptElement.type='text/javascript';scriptElement.onload=onload;scriptElement.onerror=onerror;scriptElement.src=url;scriptElement.id=id;scriptElement.async=async;Object.keys(extraAttributes).forEach(attributeName=>{scriptElement.setAttribute(attributeName,extraAttributes[attributeName]);});scriptElement.setAttribute('data-loader',EXTERNAL_SOURCE_LOAD_ORIGIN);return scriptElement;};/**
* Add script DOM element to DOM
*
* @param {*} newScriptElement the script element to add
*
* @returns
*/const insertScript=newScriptElement=>{// First try to add it to the head
const headElements=document.getElementsByTagName('head');if(headElements.length>0){headElements[0]?.insertBefore(newScriptElement,headElements[0]?.firstChild);return;}// Else wise add it before the first script tag
const scriptElements=document.getElementsByTagName('script');if(scriptElements.length>0&&scriptElements[0]?.parentNode){scriptElements[0]?.parentNode.insertBefore(newScriptElement,scriptElements[0]);return;}// Create a new head element and add the script as fallback
const headElement=document.createElement('head');headElement.appendChild(newScriptElement);const htmlElement=document.getElementsByTagName('html')[0];htmlElement?.insertBefore(headElement,htmlElement.firstChild);};/**
* Loads external js file as a script html tag
*
* @param {*} url The URL of the script to be loaded
* @param {*} id ID for the script tag
* @param {*} timeout loading timeout
* @param {*} async Whether to load the script in async mode. Defaults to `true` [optional]
* @param {*} extraAttributes key/value pair with html attributes to add in html tag [optional]
*
* @returns
*/const jsFileLoader=(url,id,timeout,async=true,extraAttributes)=>new Promise((resolve,reject)=>{const scriptExists=document.getElementById(id);if(scriptExists){reject(new Error(SCRIPT_ALREADY_EXISTS_ERROR(id)));}try{let timeoutID;const onload=()=>{globalThis.clearTimeout(timeoutID);resolve(id);};const onerror=ev=>{globalThis.clearTimeout(timeoutID);reject(new Error(SCRIPT_LOAD_ERROR(id,url,ev)));};// Create the DOM element to load the script and add it to the DOM
insertScript(createScriptElement(url,id,async,onload,onerror,extraAttributes));// Reject on timeout
timeoutID=globalThis.setTimeout(()=>{reject(new Error(SCRIPT_LOAD_TIMEOUT_ERROR(id,url,timeout)));},timeout);}catch(err){reject(getMutatedError(err,SCRIPT_LOAD_ERROR(id,url,'unknown')));}});
/**
* Service to load external resources/files
*/class ExternalSrcLoader{constructor(logger,timeout=DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS){this.logger=logger;this.timeout=timeout;}/**
* Load external resource of type javascript
*/loadJSFile(config){const{url,id,timeout,async,callback,extraAttributes}=config;const isFireAndForget=!isFunction(callback);jsFileLoader(url,id,timeout||this.timeout,async,extraAttributes).then(id=>{if(!isFireAndForget){callback(id);}}).catch(err=>{if(!isFireAndForget){callback(id,err);}});}}
var i=Symbol.for("preact-signals");function t(){if(!(s>1)){var i,t=false;while(void 0!==h){var r=h;h=void 0;f++;while(void 0!==r){var o=r.o;r.o=void 0;r.f&=-3;if(!(8&r.f)&&c(r))try{r.c();}catch(r){if(!t){i=r;t=true;}}r=o;}}f=0;s--;if(t)throw i;}else s--;}function r(i){if(s>0)return i();s++;try{return i();}finally{t();}}var o=void 0;function n(i){var t=o;o=void 0;try{return i();}finally{o=t;}}var h=void 0,s=0,f=0,v=0;function e(i){if(void 0!==o){var t=i.n;if(void 0===t||t.t!==o){t={i:0,S:i,p:o.s,n:void 0,t:o,e:void 0,x:void 0,r:t};if(void 0!==o.s)o.s.n=t;o.s=t;i.n=t;if(32&o.f)i.S(t);return t;}else if(-1===t.i){t.i=0;if(void 0!==t.n){t.n.p=t.p;if(void 0!==t.p)t.p.n=t.n;t.p=o.s;t.n=void 0;o.s.n=t;o.s=t;}return t;}}}function u(i,t){this.v=i;this.i=0;this.n=void 0;this.t=void 0;this.W=null==t?void 0:t.watched;this.Z=null==t?void 0:t.unwatched;}u.prototype.brand=i;u.prototype.h=function(){return true;};u.prototype.S=function(i){var t=this,r=this.t;if(r!==i&&void 0===i.e){i.x=r;this.t=i;if(void 0!==r)r.e=i;else n(function(){var i;null==(i=t.W)||i.call(t);});}};u.prototype.U=function(i){var t=this;if(void 0!==this.t){var r=i.e,o=i.x;if(void 0!==r){r.x=o;i.e=void 0;}if(void 0!==o){o.e=r;i.x=void 0;}if(i===this.t){this.t=o;if(void 0===o)n(function(){var i;null==(i=t.Z)||i.call(t);});}}};u.prototype.subscribe=function(i){var t=this;return E(function(){var r=t.value,n=o;o=void 0;try{i(r);}finally{o=n;}});};u.prototype.valueOf=function(){return this.value;};u.prototype.toString=function(){return this.value+"";};u.prototype.toJSON=function(){return this.value;};u.prototype.peek=function(){var i=o;o=void 0;try{return this.value;}finally{o=i;}};Object.defineProperty(u.prototype,"value",{get:function(){var i=e(this);if(void 0!==i)i.i=this.i;return this.v;},set:function(i){if(i!==this.v){if(f>100)throw new Error("Cycle detected");this.v=i;this.i++;v++;s++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N();}finally{t();}}}});function d$1(i,t){return new u(i,t);}function c(i){for(var t=i.s;void 0!==t;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return true;return false;}function a(i){for(var t=i.s;void 0!==t;t=t.n){var r=t.S.n;if(void 0!==r)t.r=r;t.S.n=t;t.i=-1;if(void 0===t.n){i.s=t;break;}}}function l(i){var t=i.s,r=void