(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.Experiment = {})); })(this, (function (exports) { 'use strict'; /** * @deprecated Update your version of the amplitude analytics-js SDK to 8.17.0+ and for seamless * integration with the amplitude analytics SDK. */ var AmplitudeUserProvider = /** @class */ (function () { function AmplitudeUserProvider(amplitudeInstance) { this.amplitudeInstance = amplitudeInstance; } AmplitudeUserProvider.prototype.getUser = function () { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; return { device_id: (_b = (_a = this.amplitudeInstance) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.deviceId, user_id: (_d = (_c = this.amplitudeInstance) === null || _c === void 0 ? void 0 : _c.options) === null || _d === void 0 ? void 0 : _d.userId, version: (_f = (_e = this.amplitudeInstance) === null || _e === void 0 ? void 0 : _e.options) === null || _f === void 0 ? void 0 : _f.versionName, language: (_h = (_g = this.amplitudeInstance) === null || _g === void 0 ? void 0 : _g.options) === null || _h === void 0 ? void 0 : _h.language, platform: (_k = (_j = this.amplitudeInstance) === null || _j === void 0 ? void 0 : _j.options) === null || _k === void 0 ? void 0 : _k.platform, os: this.getOs(), device_model: this.getDeviceModel(), }; }; AmplitudeUserProvider.prototype.getOs = function () { var _a, _b, _c, _d, _e, _f; return [ (_c = (_b = (_a = this.amplitudeInstance) === null || _a === void 0 ? void 0 : _a._ua) === null || _b === void 0 ? void 0 : _b.browser) === null || _c === void 0 ? void 0 : _c.name, (_f = (_e = (_d = this.amplitudeInstance) === null || _d === void 0 ? void 0 : _d._ua) === null || _e === void 0 ? void 0 : _e.browser) === null || _f === void 0 ? void 0 : _f.major, ] .filter(function (e) { return e !== null && e !== undefined; }) .join(' '); }; AmplitudeUserProvider.prototype.getDeviceModel = function () { var _a, _b, _c; return (_c = (_b = (_a = this.amplitudeInstance) === null || _a === void 0 ? void 0 : _a._ua) === null || _b === void 0 ? void 0 : _b.os) === null || _c === void 0 ? void 0 : _c.name; }; return AmplitudeUserProvider; }()); /** * @deprecated Update your version of the amplitude analytics-js SDK to 8.17.0+ and for seamless * integration with the amplitude analytics SDK. */ var AmplitudeAnalyticsProvider = /** @class */ (function () { function AmplitudeAnalyticsProvider(amplitudeInstance) { this.amplitudeInstance = amplitudeInstance; } AmplitudeAnalyticsProvider.prototype.track = function (event) { this.amplitudeInstance.logEvent(event.name, event.properties); }; AmplitudeAnalyticsProvider.prototype.setUserProperty = function (event) { var _a; var _b; // if the variant has a value, set the user property and log an event this.amplitudeInstance.setUserProperties((_a = {}, _a[event.userProperty] = (_b = event.variant) === null || _b === void 0 ? void 0 : _b.value, _a)); }; AmplitudeAnalyticsProvider.prototype.unsetUserProperty = function (event) { var _a; // if the variant does not have a value, unset the user property this.amplitudeInstance['_logEvent']('$identify', null, null, { $unset: (_a = {}, _a[event.userProperty] = '-', _a), }); }; return AmplitudeAnalyticsProvider; }()); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign$2 = function () { __assign$2 = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || op[1] > t[0] && op[1] = o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read$2(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spreadArray$1(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || op[1] > t[0] && op[1] = o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read$1(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i > 6 | 192; out[p++] = c & 63 | 128; } else if ((c & 0xfc00) == 0xd800 && i + 1 > 18 | 240; out[p++] = c >> 12 & 63 | 128; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } else { out[p++] = c >> 12 | 224; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } } return Uint8Array.from(out); }; var C1_32 = -0x3361d2af; var C2_32 = 0x1b873593; var R1_32 = 15; var R2_32 = 13; var M_32 = 5; var N_32 = -0x19ab949c; var hash32x86 = function (input, seed) { if (seed === void 0) { seed = 0; } var data = stringToUtf8ByteArray(input); var length = data.length; var nBlocks = length >> 2; var hash = seed; // body for (var i = 0; i >> 0; }; var mix32 = function (k, hash) { var kResult = k; var hashResult = hash; kResult = Math.imul(kResult, C1_32); kResult = rotateLeft(kResult, R1_32); kResult = Math.imul(kResult, C2_32); hashResult ^= kResult; hashResult = rotateLeft(hashResult, R2_32); hashResult = Math.imul(hashResult, M_32); return hashResult + N_32 | 0; }; var fmix32 = function (hash) { var hashResult = hash; hashResult ^= hashResult >>> 16; hashResult = Math.imul(hashResult, -0x7a143595); hashResult ^= hashResult >>> 13; hashResult = Math.imul(hashResult, -0x3d4d51cb); hashResult ^= hashResult >>> 16; return hashResult; }; var rotateLeft = function (x, n, width) { if (width === void 0) { width = 32; } if (n > width) n = n % width; var mask = 0xffffffff >> 0; var r = (x & mask) >>> 0 >>> width - n >>> 0; return (x >> 0; }; var readIntLe = function (data, index) { if (index === void 0) { index = 0; } var n = data[index] >> 24 | (n & 0x00ff0000) >>> 8 | (n & 0x0000ff00) other.major) return 1; if (this.major other.minor) return 1; if (this.minor other.patch) return 1; if (this.patch other.preRelease) return 1; if (this.preRelease = allocationStart && allocationValue = distributionStart && distributionValue filterValue; case EvaluationOperator.GREATER_THAN_EQUALS: case EvaluationOperator.VERSION_GREATER_THAN_EQUALS: return propValue >= filterValue; default: return false; } }; EvaluationEngine.prototype.versionComparator = function (propValue, op, filterValue) { var compareTo = propValue.compareTo(filterValue); switch (op) { case EvaluationOperator.LESS_THAN: case EvaluationOperator.VERSION_LESS_THAN: return compareTo 0; case EvaluationOperator.GREATER_THAN_EQUALS: case EvaluationOperator.VERSION_GREATER_THAN_EQUALS: return compareTo >= 0; default: return false; } }; EvaluationEngine.prototype.matchesRegex = function (propValue, filterValues) { return filterValues.some(function (filterValue) { return Boolean(new RegExp(filterValue).exec(propValue)); }); }; EvaluationEngine.prototype.containsNone = function (filterValues) { return filterValues.some(function (filterValue) { return filterValue === '(none)'; }); }; EvaluationEngine.prototype.containsBooleans = function (filterValues) { return filterValues.some(function (filterValue) { switch (filterValue.toLowerCase()) { case 'true': case 'false': return true; default: return false; } }); }; EvaluationEngine.prototype.parseNumber = function (value) { var _a; return (_a = Number(value)) !== null && _a !== void 0 ? _a : undefined; }; EvaluationEngine.prototype.coerceString = function (value) { if (value === undefined || value === null) { return undefined; } if (typeof value === 'object') { return JSON.stringify(value); } return String(value); }; EvaluationEngine.prototype.coerceStringArray = function (value) { var _this = this; if (Array.isArray(value)) { var anyArray = value; return anyArray.map(function (e) { return _this.coerceString(e); }).filter(Boolean); } var stringValue = String(value); try { var parsedValue = JSON.parse(stringValue); if (Array.isArray(parsedValue)) { var anyArray = value; return anyArray.map(function (e) { return _this.coerceString(e); }).filter(Boolean); } else { var s = this.coerceString(stringValue); return s ? [s] : undefined; } } catch (_a) { var s = this.coerceString(stringValue); return s ? [s] : undefined; } }; EvaluationEngine.prototype.isSetOperator = function (op) { switch (op) { case EvaluationOperator.SET_IS: case EvaluationOperator.SET_IS_NOT: case EvaluationOperator.SET_CONTAINS: case EvaluationOperator.SET_DOES_NOT_CONTAIN: case EvaluationOperator.SET_CONTAINS_ANY: case EvaluationOperator.SET_DOES_NOT_CONTAIN_ANY: return true; default: return false; } }; EvaluationEngine.prototype.setEquals = function (xa, ya) { var xs = new Set(xa); var ys = new Set(ya); return xs.size === ys.size && __spreadArray([], __read$1(ys), false).every(function (y) { return xs.has(y); }); }; EvaluationEngine.prototype.matchesSetContainsAll = function (propValues, filterValues) { var e_8, _a; if (propValues.length { let tab = {}; a.forEach((c, i) => tab[c] = i); return tab; })(b64chs); const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; const _fromCC = String.fromCharCode.bind(String); const _U8Afrom = typeof Uint8Array.from === 'function' ? Uint8Array.from.bind(Uint8Array) : it => new Uint8Array(Array.prototype.slice.call(it, 0)); const _mkUriSafe = src => src.replace(/=/g, '').replace(/[+\/]/g, m0 => m0 == '+' ? '-' : '_'); const _tidyB64 = s => s.replace(/[^A-Za-z0-9\+\/]/g, ''); /** * polyfill version of `btoa` */ const btoaPolyfill = bin => { // console.log('polyfilled'); let u32, c0, c1, c2, asc = ''; const pad = bin.length % 3; for (let i = 0; i 255 || (c1 = bin.charCodeAt(i++)) > 255 || (c2 = bin.charCodeAt(i++)) > 255) throw new TypeError('invalid character found'); u32 = c0 > 18 & 63] + b64chs[u32 >> 12 & 63] + b64chs[u32 >> 6 & 63] + b64chs[u32 & 63]; } return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; }; /** * does what `window.btoa` of web browsers do. * @param {String} bin binary string * @returns {string} Base64-encoded string */ const _btoa = typeof btoa === 'function' ? bin => btoa(bin) : _hasBuffer ? bin => Buffer.from(bin, 'binary').toString('base64') : btoaPolyfill; const _fromUint8Array = _hasBuffer ? u8a => Buffer.from(u8a).toString('base64') : u8a => { // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 const maxargs = 0x1000; let strs = []; for (let i = 0, l = u8a.length; i urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); // This trick is found broken https://github.com/dankogai/js-base64/issues/130 // const utob = (src: string) => unescape(encodeURIComponent(src)); // reverting good old fationed regexp const cb_utob = c => { if (c.length >> 6) + _fromCC(0x80 | cc & 0x3f) : _fromCC(0xe0 | cc >>> 12 & 0x0f) + _fromCC(0x80 | cc >>> 6 & 0x3f) + _fromCC(0x80 | cc & 0x3f); } else { var cc = 0x10000 + (c.charCodeAt(0) - 0xD800) * 0x400 + (c.charCodeAt(1) - 0xDC00); return _fromCC(0xf0 | cc >>> 18 & 0x07) + _fromCC(0x80 | cc >>> 12 & 0x3f) + _fromCC(0x80 | cc >>> 6 & 0x3f) + _fromCC(0x80 | cc & 0x3f); } }; const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; /** * @deprecated should have been internal use only. * @param {string} src UTF-8 string * @returns {string} UTF-16 string */ const utob = u => u.replace(re_utob, cb_utob); // const _encode = _hasBuffer ? s => Buffer.from(s, 'utf8').toString('base64') : _TE ? s => _fromUint8Array(_TE.encode(s)) : s => _btoa(utob(s)); /** * converts a UTF-8-encoded string to a Base64 string. * @param {boolean} [urlsafe] if `true` make the result URL-safe * @returns {string} Base64 string */ const encode = (src, urlsafe = false) => urlsafe ? _mkUriSafe(_encode(src)) : _encode(src); /** * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. * @returns {string} Base64 string */ const encodeURI = src => encode(src, true); // This trick is found broken https://github.com/dankogai/js-base64/issues/130 // const btou = (src: string) => decodeURIComponent(escape(src)); // reverting good old fationed regexp const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; const cb_btou = cccc => { switch (cccc.length) { case 4: var cp = (0x07 & cccc.charCodeAt(0)) >> 10) + 0xD800) + _fromCC((offset & 0x3FF) + 0xDC00); case 3: return _fromCC((0x0f & cccc.charCodeAt(0)) b.replace(re_btou, cb_btou); /** * polyfill version of `atob` */ const atobPolyfill = asc => { // console.log('polyfilled'); asc = asc.replace(/\s+/g, ''); if (!b64re.test(asc)) throw new TypeError('malformed base64.'); asc += '=='.slice(2 - (asc.length & 3)); let u24, bin = '', r1, r2; for (let i = 0; i > 16 & 255) : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); } return bin; }; /** * does what `window.atob` of web browsers do. * @param {String} asc Base64-encoded string * @returns {string} binary string */ const _atob = typeof atob === 'function' ? asc => atob(_tidyB64(asc)) : _hasBuffer ? asc => Buffer.from(asc, 'base64').toString('binary') : atobPolyfill; // const _toUint8Array = _hasBuffer ? a => _U8Afrom(Buffer.from(a, 'base64')) : a => _U8Afrom(_atob(a).split('').map(c => c.charCodeAt(0))); /** * converts a Base64 string to a Uint8Array. */ const toUint8Array = a => _toUint8Array(_unURI(a)); // const _decode = _hasBuffer ? a => Buffer.from(a, 'base64').toString('utf8') : _TD ? a => _TD.decode(_toUint8Array(a)) : a => btou(_atob(a)); const _unURI = a => _tidyB64(a.replace(/[-_]/g, m0 => m0 == '-' ? '+' : '/')); /** * converts a Base64 string to a UTF-8 string. * @param {String} src Base64 string. Both normal and URL-safe are supported * @returns {string} UTF-8 string */ const decode = src => _decode(_unURI(src)); /** * check if a value is a valid Base64 string * @param {String} src a value to check */ const isValid = src => { if (typeof src !== 'string') return false; const s = src.replace(/\s+/g, '').replace(/={0,2}$/, ''); return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); }; // const _noEnum = v => { return { value: v, enumerable: false, writable: true, configurable: true }; }; /** * extend String.prototype with relevant methods */ const extendString = function () { const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body)); _add('fromBase64', function () { return decode(this); }); _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); _add('toBase64URI', function () { return encode(this, true); }); _add('toBase64URL', function () { return encode(this, true); }); _add('toUint8Array', function () { return toUint8Array(this); }); }; /** * extend Uint8Array.prototype with relevant methods */ const extendUint8Array = function () { const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); _add('toBase64URI', function () { return fromUint8Array(this, true); }); _add('toBase64URL', function () { return fromUint8Array(this, true); }); }; /** * extend Builtin prototypes with relevant methods */ const extendBuiltins = () => { extendString(); extendUint8Array(); }; const gBase64 = { version: version$1, VERSION: VERSION, atob: _atob, atobPolyfill: atobPolyfill, btoa: _btoa, btoaPolyfill: btoaPolyfill, fromBase64: decode, toBase64: encode, encode: encode, encodeURI: encodeURI, encodeURL: encodeURI, utob: utob, btou: btou, decode: decode, isValid: isValid, fromUint8Array: fromUint8Array, toUint8Array: toUint8Array, extendString: extendString, extendUint8Array: extendUint8Array, extendBuiltins: extendBuiltins }; var FetchError = /** @class */function (_super) { __extends(FetchError, _super); function FetchError(statusCode, message) { var _this = _super.call(this, message) || this; _this.statusCode = statusCode; Object.setPrototypeOf(_this, FetchError.prototype); return _this; } return FetchError; }(Error); var TimeoutError = /** @class */function (_super) { __extends(TimeoutError, _super); function TimeoutError(message) { var _this = _super.call(this, message) || this; Object.setPrototypeOf(_this, TimeoutError.prototype); return _this; } return TimeoutError; }(Error); var SdkEvaluationApi = /** @class */function () { function SdkEvaluationApi(deploymentKey, serverUrl, httpClient) { this.deploymentKey = deploymentKey; this.serverUrl = serverUrl; this.httpClient = httpClient; } SdkEvaluationApi.prototype.getVariants = function (user, options) { return __awaiter(this, void 0, void 0, function () { var userJsonBase64, headers, url, response; return __generator(this, function (_a) { switch (_a.label) { case 0: userJsonBase64 = gBase64.encodeURL(JSON.stringify(user)); headers = { Authorization: "Api-Key ".concat(this.deploymentKey), 'X-Amp-Exp-User': userJsonBase64 }; if (options === null || options === void 0 ? void 0 : options.flagKeys) { headers['X-Amp-Exp-Flag-Keys'] = gBase64.encodeURL(JSON.stringify(options.flagKeys)); } if (options === null || options === void 0 ? void 0 : options.trackingOption) { headers['X-Amp-Exp-Track'] = options.trackingOption; } url = new URL("".concat(this.serverUrl, "/sdk/v2/vardata?v=0")); if (options === null || options === void 0 ? void 0 : options.evaluationMode) { url.searchParams.append('eval_mode', options === null || options === void 0 ? void 0 : options.evaluationMode); } if (options === null || options === void 0 ? void 0 : options.deliveryMethod) { url.searchParams.append('delivery_method', options === null || options === void 0 ? void 0 : options.deliveryMethod); } return [4 /*yield*/, this.httpClient.request({ requestUrl: url.toString(), method: 'GET', headers: headers, timeoutMillis: options === null || options === void 0 ? void 0 : options.timeoutMillis })]; case 1: response = _a.sent(); if (response.status != 200) { throw new FetchError(response.status, "Fetch error response: status=".concat(response.status)); } return [2 /*return*/, JSON.parse(response.body)]; } }); }); }; return SdkEvaluationApi; }(); var SdkFlagApi = /** @class */function () { function SdkFlagApi(deploymentKey, serverUrl, httpClient) { this.deploymentKey = deploymentKey; this.serverUrl = serverUrl; this.httpClient = httpClient; } SdkFlagApi.prototype.getFlags = function (options) { return __awaiter(this, void 0, void 0, function () { var headers, response, flagsArray; return __generator(this, function (_a) { switch (_a.label) { case 0: headers = { Authorization: "Api-Key ".concat(this.deploymentKey) }; if ((options === null || options === void 0 ? void 0 : options.libraryName) && (options === null || options === void 0 ? void 0 : options.libraryVersion)) { headers['X-Amp-Exp-Library'] = "".concat(options.libraryName, "/").concat(options.libraryVersion); } if (options === null || options === void 0 ? void 0 : options.user) { headers['X-Amp-Exp-User'] = gBase64.encodeURL(JSON.stringify(options.user)); } return [4 /*yield*/, this.httpClient.request({ requestUrl: "".concat(this.serverUrl, "/sdk/v2/flags") + ((options === null || options === void 0 ? void 0 : options.deliveryMethod) ? "?delivery_method=".concat(options.deliveryMethod) : ''), method: 'GET', headers: headers, timeoutMillis: options === null || options === void 0 ? void 0 : options.timeoutMillis })]; case 1: response = _a.sent(); if (response.status != 200) { throw Error("Flags error response: status=".concat(response.status)); } flagsArray = JSON.parse(response.body); return [2 /*return*/, flagsArray.reduce(function (map, flag) { map[flag.key] = flag; return map; }, {})]; } }); }); }; return SdkFlagApi; }(); var safeGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : global || self; var getGlobalScope = function () { if (typeof globalThis !== 'undefined') { return globalThis; } if (typeof window !== 'undefined') { return window; } if (typeof self !== 'undefined') { return self; } if (typeof global !== 'undefined') { return global; } return undefined; }; var isLocalStorageAvailable = function () { var globalScope = getGlobalScope(); if (globalScope) { try { var testKey = 'EXP_test'; globalScope.localStorage.setItem(testKey, testKey); globalScope.localStorage.removeItem(testKey); return true; } catch (e) { return false; } } return false; }; var Poller = /** @class */function () { function Poller(action, ms) { this.poller = undefined; this.action = action; this.ms = ms; } Poller.prototype.start = function () { if (this.poller) { return; } this.poller = safeGlobal$1.setInterval(this.action, this.ms); void this.action(); }; Poller.prototype.stop = function () { if (!this.poller) { return; } // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore safeGlobal$1.clearInterval(this.poller); this.poller = undefined; }; return Poller; }(); var parseAmplitudeCookie = function (apiKey, newFormat) { var e_1, _a; if (newFormat === void 0) { newFormat = false; } // Get the cookie value var key = generateKey(apiKey, newFormat); var value = undefined; var cookies = safeGlobal$1.document.cookie.split('; '); try { for (var cookies_1 = __values$2(cookies), cookies_1_1 = cookies_1.next(); !cookies_1_1.done; cookies_1_1 = cookies_1.next()) { var cookie = cookies_1_1.value; var _b = __read$2(cookie.split('=', 2), 2), cookieKey = _b[0], cookieValue = _b[1]; if (cookieKey === key) { value = decodeURIComponent(cookieValue); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (cookies_1_1 && !cookies_1_1.done && (_a = cookies_1.return)) _a.call(cookies_1); } finally { if (e_1) throw e_1.error; } } if (!value) { return; } // Parse cookie value depending on format try { // New format if (newFormat) { var decoding = atob(value); return JSON.parse(decodeURIComponent(decoding)); } // Old format var values = value.split('.'); var userId = undefined; if (values.length >= 2 && values[1]) { userId = atob(values[1]); } return { deviceId: values[0], userId: userId, }; } catch (e) { return; } }; var parseAmplitudeLocalStorage = function (apiKey) { var key = generateKey(apiKey, true); try { var value = safeGlobal$1.localStorage.getItem(key); if (!value) return; var state = JSON.parse(value); if (typeof state !== 'object') return; return state; } catch (_a) { return; } }; var parseAmplitudeSessionStorage = function (apiKey) { var key = generateKey(apiKey, true); try { var value = safeGlobal$1.sessionStorage.getItem(key); if (!value) return; var state = JSON.parse(value); if (typeof state !== 'object') return; return state; } catch (_a) { return; } }; var generateKey = function (apiKey, newFormat) { if (newFormat) { if ((apiKey === null || apiKey === void 0 ? void 0 : apiKey.length) 0) { this.queue.forEach(function (event) { receiver(event); }); this.queue = []; } }; return EventBridgeImpl; }(); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i = o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any var isEqual = function (obj1, obj2) { var e_1, _a; var primitive = ['string', 'number', 'boolean', 'undefined']; var typeA = typeof obj1; var typeB = typeof obj2; if (typeA !== typeB) { return false; } try { for (var primitive_1 = __values(primitive), primitive_1_1 = primitive_1.next(); !primitive_1_1.done; primitive_1_1 = primitive_1.next()) { var p = primitive_1_1.value; if (p === typeA) { return obj1 === obj2; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (primitive_1_1 && !primitive_1_1.done && (_a = primitive_1.return)) _a.call(primitive_1); } finally { if (e_1) throw e_1.error; } } // check null if (obj1 == null && obj2 == null) { return true; } else if (obj1 == null || obj2 == null) { return false; } // if got here - objects if (obj1.length !== obj2.length) { return false; } //check if arrays var isArrayA = Array.isArray(obj1); var isArrayB = Array.isArray(obj2); if (isArrayA !== isArrayB) { return false; } if (isArrayA && isArrayB) { //arrays for (var i = 0; i this.maxQueueSize) { this.inMemoryQueue = this.inMemoryQueue.slice(this.inMemoryQueue.length - this.maxQueueSize); } safeGlobal$1.localStorage.setItem(this.storageKey, JSON.stringify(this.inMemoryQueue)); } }; PersistentTrackingQueue.prototype.loadFlushStore = function () { this.loadQueue(); this.flush(); this.storeQueue(); }; return PersistentTrackingQueue; }()); var checkIsSessionStorageAvailable = function () { var globalScope = getGlobalScope(); if (globalScope) { try { var testKey = 'EXP_test'; globalScope.sessionStorage.setItem(testKey, testKey); globalScope.sessionStorage.removeItem(testKey); return true; } catch (e) { return false; } } return false; }; var LocalStorage = /** @class */ (function () { function LocalStorage() { this.globalScope = getGlobalScope(); } LocalStorage.prototype.get = function (key) { var _a; return (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.localStorage.getItem(key); }; LocalStorage.prototype.put = function (key, value) { var _a; (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.localStorage.setItem(key, value); }; LocalStorage.prototype.delete = function (key) { var _a; (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.localStorage.removeItem(key); }; return LocalStorage; }()); var getVariantStorage = function (deploymentKey, instanceName, storage) { var truncatedDeployment = deploymentKey.substring(deploymentKey.length - 6); var namespace = "amp-exp-".concat(instanceName, "-").concat(truncatedDeployment); return new LoadStoreCache(namespace, storage, transformVariantFromStorage); }; var getFlagStorage = function (deploymentKey, instanceName, storage) { if (storage === void 0) { storage = new LocalStorage(); } var truncatedDeployment = deploymentKey.substring(deploymentKey.length - 6); var namespace = "amp-exp-".concat(instanceName, "-").concat(truncatedDeployment, "-flags"); return new LoadStoreCache(namespace, storage); }; var LoadStoreCache = /** @class */ (function () { function LoadStoreCache(namespace, storage, transformer) { this.cache = {}; this.namespace = namespace; this.storage = storage; this.transformer = transformer; } LoadStoreCache.prototype.get = function (key) { return this.cache[key]; }; LoadStoreCache.prototype.getAll = function () { return __assign$2({}, this.cache); }; LoadStoreCache.prototype.put = function (key, value) { this.cache[key] = value; }; LoadStoreCache.prototype.putAll = function (values) { var e_1, _a; try { for (var _b = __values$2(Object.keys(values)), _c = _b.next(); !_c.done; _c = _b.next()) { var key = _c.value; this.cache[key] = values[key]; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } }; LoadStoreCache.prototype.remove = function (key) { delete this.cache[key]; }; LoadStoreCache.prototype.clear = function () { this.cache = {}; }; LoadStoreCache.prototype.load = function () { var e_2, _a; var rawValues = this.storage.get(this.namespace); var jsonValues; try { jsonValues = JSON.parse(rawValues) || {}; } catch (_b) { // Do nothing return; } var values = {}; try { for (var _c = __values$2(Object.keys(jsonValues)), _d = _c.next(); !_d.done; _d = _c.next()) { var key = _d.value; try { var value = void 0; if (this.transformer) { value = this.transformer(jsonValues[key]); } else { value = jsonValues[key]; } if (value) { values[key] = value; } } catch (_e) { // Do nothing } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_2) throw e_2.error; } } this.clear(); this.putAll(values); }; LoadStoreCache.prototype.store = function (values) { if (values === void 0) { values = this.cache; } this.storage.put(this.namespace, JSON.stringify(values)); }; return LoadStoreCache; }()); var transformVariantFromStorage = function (storageValue) { if (typeof storageValue === 'string') { // From v0 string format return { key: storageValue, value: storageValue, }; } else if (typeof storageValue === 'object') { // From v1 or v2 object format var key = storageValue['key']; var value = storageValue['value']; var payload = storageValue['payload']; var metadata = storageValue['metadata']; var experimentKey = storageValue['expKey']; if (metadata && metadata.experimentKey) { experimentKey = metadata.experimentKey; } else if (experimentKey) { metadata = metadata || {}; metadata['experimentKey'] = experimentKey; } var variant = {}; if (key) { variant.key = key; } else if (value) { variant.key = value; } if (value) variant.value = value; if (metadata) variant.metadata = metadata; if (payload) variant.payload = payload; if (experimentKey) variant.expKey = experimentKey; return variant; } }; var SessionStorage = /** @class */ (function () { function SessionStorage() { this.globalScope = getGlobalScope(); } SessionStorage.prototype.get = function (key) { var _a; return (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.sessionStorage.getItem(key); }; SessionStorage.prototype.put = function (key, value) { var _a; (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.sessionStorage.setItem(key, value); }; SessionStorage.prototype.delete = function (key) { var _a; (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.sessionStorage.removeItem(key); }; return SessionStorage; }()); /** * Event for tracking a user's exposure to a variant. This event will not count * towards your analytics event volume. * * @deprecated use ExposureTrackingProvider instead */ var exposureEvent = function (user, key, variant, source) { var _a; var name = '[Experiment] Exposure'; var value = variant === null || variant === void 0 ? void 0 : variant.value; var userProperty = "[Experiment] ".concat(key); return { name: name, user: user, key: key, variant: variant, userProperty: userProperty, properties: { key: key, variant: value, source: source, }, userProperties: (_a = {}, _a[userProperty] = value, _a), }; }; var isNullOrUndefined = function (value) { return value === null || value === undefined; }; var isNullUndefinedOrEmpty = function (value) { if (isNullOrUndefined(value)) return true; return value && Object.keys(value).length === 0; }; /** * Filters out null and undefined values from an object, returning a new object * with only defined values. This is useful for config merging where you want * defaults to take precedence over explicit null/undefined values. */ var filterNullUndefined = function (obj) { var e_1, _a; if (!obj || typeof obj !== 'object') { return {}; } var filtered = {}; try { for (var _b = __values$2(Object.entries(obj)), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read$2(_c.value, 2), key = _d[0], value = _d[1]; if (!isNullOrUndefined(value)) { filtered[key] = value; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return filtered; }; var isLocalEvaluationMode = function (flag) { var _a; return ((_a = flag === null || flag === void 0 ? void 0 : flag.metadata) === null || _a === void 0 ? void 0 : _a.evaluationMode) === 'local'; }; var Backoff = /** @class */ (function () { function Backoff(attempts, min, max, scalar) { this.started = false; this.done = false; this.attempts = attempts; this.min = min; this.max = max; this.scalar = scalar; } Backoff.prototype.start = function (fn) { return __awaiter$1(this, void 0, void 0, function () { return __generator$1(this, function (_a) { switch (_a.label) { case 0: if (!this.started) { this.started = true; } else { throw Error('Backoff already started'); } return [4 /*yield*/, this.backoff(fn, 0, this.min)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; Backoff.prototype.cancel = function () { this.done = true; clearTimeout(this.timeoutHandle); }; Backoff.prototype.backoff = function (fn, attempt, delay) { return __awaiter$1(this, void 0, void 0, function () { var _this = this; return __generator$1(this, function (_a) { if (this.done) { return [2 /*return*/]; } this.timeoutHandle = safeGlobal$1.setTimeout(function () { return __awaiter$1(_this, void 0, void 0, function () { var nextAttempt, nextDelay; return __generator$1(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, fn()]; case 1: _a.sent(); return [3 /*break*/, 3]; case 2: _a.sent(); nextAttempt = attempt + 1; if (nextAttempt 0 && groupNames[0]) { var groupName = groupNames[0]; var groupNameMap = { group_name: groupName, }; // Check for group properties var groupProperties = (_c = (_b = user.group_properties) === null || _b === void 0 ? void 0 : _b[groupType]) === null || _c === void 0 ? void 0 : _c[groupName]; if (groupProperties && Object.keys(groupProperties).length > 0) { groupNameMap['group_properties'] = groupProperties; } groups[groupType] = groupNameMap; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_e && !_e.done && (_a = _d.return)) _a.call(_d); } finally { if (e_1) throw e_1.error; } } if (Object.keys(groups).length > 0) { context['groups'] = groups; } delete context.user['groups']; delete context.user['group_properties']; return context; }; var convertVariant = function (value) { if (value === null || value === undefined) { return {}; } if (typeof value == 'string') { return { key: value, value: value, }; } else { return value; } }; var convertEvaluationVariantToVariant = function (evaluationVariant) { if (!evaluationVariant) { return {}; } var experimentKey = undefined; if (evaluationVariant.metadata) { experimentKey = evaluationVariant.metadata['experimentKey']; } var variant = {}; if (evaluationVariant.key) variant.key = evaluationVariant.key; if (evaluationVariant.value) variant.value = evaluationVariant.value; if (evaluationVariant.payload) variant.payload = evaluationVariant.payload; if (experimentKey) variant.expKey = experimentKey; if (evaluationVariant.metadata) variant.metadata = evaluationVariant.metadata; return variant; }; /** * A wrapper for an analytics provider which only sends one exposure event per * flag, per variant, per session. In other words, wrapping an analytics * provider in this class will prevent the same exposure event to be sent twice * in one session. */ var SessionAnalyticsProvider = /** @class */ (function () { function SessionAnalyticsProvider(analyticsProvider) { // In memory record of flagKey and variant value to in order to only set // user properties and track an exposure event once per session unless the // variant value changes this.setProperties = {}; this.unsetProperties = {}; this.analyticsProvider = analyticsProvider; } SessionAnalyticsProvider.prototype.track = function (event) { if (this.setProperties[event.key] == event.variant.value) { return; } else { this.setProperties[event.key] = event.variant.value; delete this.unsetProperties[event.key]; } this.analyticsProvider.track(event); }; SessionAnalyticsProvider.prototype.setUserProperty = function (event) { if (this.setProperties[event.key] == event.variant.value) { return; } this.analyticsProvider.setUserProperty(event); }; SessionAnalyticsProvider.prototype.unsetUserProperty = function (event) { if (this.unsetProperties[event.key]) { return; } else { this.unsetProperties[event.key] = 'unset'; delete this.setProperties[event.key]; } this.analyticsProvider.unsetUserProperty(event); }; return SessionAnalyticsProvider; }()); var SessionExposureTrackingProvider = /** @class */ (function () { function SessionExposureTrackingProvider(exposureTrackingProvider) { this.tracked = {}; this.exposureTrackingProvider = exposureTrackingProvider; } SessionExposureTrackingProvider.prototype.track = function (exposure) { var trackedExposure = this.tracked[exposure.flag_key]; if (trackedExposure && trackedExposure.variant === exposure.variant) { return; } else { this.tracked[exposure.flag_key] = exposure; this.exposureTrackingProvider.track(exposure); } }; return SessionExposureTrackingProvider; }()); /** * @packageDocumentation * @module experiment-js-client */ // Configs which have been removed from the public API. // May be added back in the future. var fetchBackoffTimeout = 10000; var fetchBackoffAttempts = 8; var fetchBackoffMinMillis = 500; var fetchBackoffMaxMillis = 10000; var fetchBackoffScalar = 1.5; var minFlagPollerIntervalMillis = 60000; var euServerUrl = 'https://api.lab.eu.amplitude.com'; var euFlagsServerUrl = 'https://flag.lab.eu.amplitude.com'; /** * The default {@link Client} used to fetch variations from Experiment's * servers. * * @category Core Usage */ var ExperimentClient = /** @class */ (function () { /** * Creates a new ExperimentClient instance. * * In most cases you will want to use the `initialize` factory method in * {@link Experiment}. * * @param apiKey The Client key for the Experiment project * @param config See {@link ExperimentConfig} for config options */ function ExperimentClient(apiKey, config) { var _this = this; var _a, _b, _c, _d; this.engine = new EvaluationEngine(); this.isRunning = false; this.apiKey = apiKey; // Filter out null/undefined values from config to ensure defaults take precedence config = filterNullUndefined(config); // Merge configs with defaults and wrap providers this.config = __assign$2(__assign$2(__assign$2({}, Defaults), config), { // Set server URLs separately serverUrl: (config === null || config === void 0 ? void 0 : config.serverUrl) || (((_a = config === null || config === void 0 ? void 0 : config.serverZone) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'eu' ? euServerUrl : Defaults.serverUrl), flagsServerUrl: (config === null || config === void 0 ? void 0 : config.flagsServerUrl) || (((_b = config === null || config === void 0 ? void 0 : config.serverZone) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'eu' ? euFlagsServerUrl : Defaults.flagsServerUrl), // Force minimum flag config polling interval. flagConfigPollingIntervalMillis: config.flagConfigPollingIntervalMillis = 500 || e.statusCode === 429; } return true; }; /** * Add a plugin to the experiment client. * @param plugin the plugin to add. */ ExperimentClient.prototype.addPlugin = function (plugin) { if (plugin.type === 'integration') { this.integrationManager.setIntegration(plugin); } }; return ExperimentClient; }()); var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, basedir, module) { return module = { path: basedir, exports: {}, require: function (path, base) { return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); } }, fn(module, module.exports), module.exports; } function commonjsRequire () { throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); } var uaParser = createCommonjsModule(function (module, exports) { ///////////////////////////////////////////////////////////////////////////////// /* UAParser.js v0.7.33 Copyright © 2012-2021 Faisal Salman MIT License */ /* Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment. Demo : https://faisalman.github.io/ua-parser-js Source : https://github.com/faisalman/ua-parser-js */ ///////////////////////////////////////////////////////////////////////////////// (function (window, undefined$1) { ////////////// // Constants ///////////// var LIBVERSION = "0.7.33", EMPTY = "", UNKNOWN = "?", FUNC_TYPE = "function", UNDEF_TYPE = "undefined", OBJ_TYPE = "object", STR_TYPE = "string", MAJOR = "major", MODEL = "model", NAME = "name", TYPE = "type", VENDOR = "vendor", VERSION = "version", ARCHITECTURE = "architecture", CONSOLE = "console", MOBILE = "mobile", TABLET = "tablet", SMARTTV = "smarttv", WEARABLE = "wearable", EMBEDDED = "embedded", UA_MAX_LENGTH = 350; var AMAZON = "Amazon", APPLE = "Apple", ASUS = "ASUS", BLACKBERRY = "BlackBerry", BROWSER = "Browser", CHROME = "Chrome", EDGE = "Edge", FIREFOX = "Firefox", GOOGLE = "Google", HUAWEI = "Huawei", LG = "LG", MICROSOFT = "Microsoft", MOTOROLA = "Motorola", OPERA = "Opera", SAMSUNG = "Samsung", SHARP = "Sharp", SONY = "Sony", XIAOMI = "Xiaomi", ZEBRA = "Zebra", FACEBOOK = "Facebook"; /////////// // Helper ////////// var extend = function (regexes, extensions) { var mergedRegexes = {}; for (var i in regexes) { if (extensions[i] && extensions[i].length % 2 === 0) { mergedRegexes[i] = extensions[i].concat(regexes[i]); } else { mergedRegexes[i] = regexes[i]; } } return mergedRegexes; }, enumerize = function (arr) { var enums = {}; for (var i = 0; i 0) { if (q.length === 2) { if (typeof q[1] == FUNC_TYPE) { // assign modified match this[q[0]] = q[1].call(this, match); } else { // assign given value, ignore regex match this[q[0]] = q[1]; } } else if (q.length === 3) { // check whether function or regex if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { // call function (usually string mapper) this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined$1; } else { // sanitize match using given regex this[q[0]] = match ? match.replace(q[1], q[2]) : undefined$1; } } else if (q.length === 4) { this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined$1; } } else { this[q] = match ? match : undefined$1; } } } } i += 2; } }, strMapper = function (str, map) { for (var i in map) { // check if current value is array if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { for (var j = 0; j = 8.0 ], [VERSION, [NAME, OPERA + " Mini"]], [/\bopr\/([\w\.]+)/i // Opera Webkit ], [VERSION, [NAME, OPERA]], [ // Mixed /(kindle)\/([\w\.]+)/i, // Kindle /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer // Trident based /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser /(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ /(weibo)__([\d\.]+)/i // Weibo ], [NAME, VERSION], [/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser ], [VERSION, [NAME, "UC" + BROWSER]], [/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser /\bqbcore\/([\w\.]+).+microm/i], [VERSION, [NAME, "WeChat(Win) Desktop"]], [/micromessenger\/([\w\.]+)/i // WeChat ], [VERSION, [NAME, "WeChat"]], [/konqueror\/([\w\.]+)/i // Konqueror ], [VERSION, [NAME, "Konqueror"]], [/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11 ], [VERSION, [NAME, "IE"]], [/yabrowser\/([\w\.]+)/i // Yandex ], [VERSION, [NAME, "Yandex"]], [/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser ], [[NAME, /(.+)/, "$1 Secure " + BROWSER], VERSION], [/\bfocus\/([\w\.]+)/i // Firefox Focus ], [VERSION, [NAME, FIREFOX + " Focus"]], [/\bopt\/([\w\.]+)/i // Opera Touch ], [VERSION, [NAME, OPERA + " Touch"]], [/coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser ], [VERSION, [NAME, "Coc Coc"]], [/dolfin\/([\w\.]+)/i // Dolphin ], [VERSION, [NAME, "Dolphin"]], [/coast\/([\w\.]+)/i // Opera Coast ], [VERSION, [NAME, OPERA + " Coast"]], [/miuibrowser\/([\w\.]+)/i // MIUI Browser ], [VERSION, [NAME, "MIUI " + BROWSER]], [/fxios\/([-\w\.]+)/i // Firefox for iOS ], [VERSION, [NAME, FIREFOX]], [/\bqihu|(qi?ho?o?|360)browser/i // 360 ], [[NAME, "360 " + BROWSER]], [/(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i], [[NAME, /(.+)/, "$1 " + BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon ], [[NAME, /_/g, " "], VERSION], [/(electron)\/([\w\.]+) safari/i, // Electron-based App /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser ], [NAME, VERSION], [/(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser /(lbbrowser)/i, // LieBao Browser /\[(linkedin)app\]/i // LinkedIn App for iOS & Android ], [NAME], [ // WebView /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android ], [[NAME, FACEBOOK], VERSION], [/safari (line)\/([\w\.]+)/i, // Line App for iOS /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram ], [NAME, VERSION], [/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS ], [VERSION, [NAME, "GSA"]], [/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless ], [VERSION, [NAME, CHROME + " Headless"]], [/ wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView ], [[NAME, CHROME + " WebView"], VERSION], [/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser ], [VERSION, [NAME, "Android " + BROWSER]], [/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia ], [NAME, VERSION], [/version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i // Mobile Safari ], [VERSION, [NAME, "Mobile Safari"]], [/version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile ], [VERSION, NAME], [/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua; return this; }; this.setUA(_ua); return this; }; UAParser.VERSION = LIBVERSION; UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]); UAParser.CPU = enumerize([ARCHITECTURE]); UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]); UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]); /////////// // Export ////////// // check js environment { // nodejs env if (module.exports) { exports = module.exports = UAParser; } exports.UAParser = UAParser; } // jQuery/Zepto specific (optional) // Note: // In AMD env the global scope should be kept clean, but jQuery is an exception. // jQuery always exports to global scope, unless jQuery.noConflict(true) is used, // and we should catch that. var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto); if ($ && !$.ua) { var parser = new UAParser(); $.ua = parser.getResult(); $.ua.get = function () { return parser.getUA(); }; $.ua.set = function (ua) { parser.setUA(ua); var result = parser.getResult(); for (var prop in result) { $.ua[prop] = result[prop]; } }; } })(typeof window === "object" ? window : commonjsGlobal); }); var DefaultUserProvider = /** @class */ (function () { function DefaultUserProvider(userProvider, apiKey) { var _a, _b, _c; this.globalScope = getGlobalScope(); this.userAgent = typeof ((_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.navigator) !== 'undefined' ? (_b = this.globalScope) === null || _b === void 0 ? void 0 : _b.navigator.userAgent : undefined; this.ua = new uaParser.UAParser(this.userAgent).getResult(); this.localStorage = new LocalStorage(); this.sessionStorage = new SessionStorage(); this.userProvider = userProvider; this.apiKey = apiKey; this.storageKey = "EXP_".concat((_c = this.apiKey) === null || _c === void 0 ? void 0 : _c.slice(0, 10), "_DEFAULT_USER_PROVIDER"); } DefaultUserProvider.prototype.getUser = function () { var _a, _b, _c, _d, _e; var user = ((_a = this.userProvider) === null || _a === void 0 ? void 0 : _a.getUser()) || {}; return __assign$2({ language: this.getLanguage(), platform: 'Web', os: this.getOs(this.ua), device_model: this.getDeviceModel(this.ua), device_category: (_c = (_b = this.ua.device) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'desktop', referring_url: (_e = (_d = this.globalScope) === null || _d === void 0 ? void 0 : _d.document) === null || _e === void 0 ? void 0 : _e.referrer.replace(/\/$/, ''), cookie: this.getCookie(), browser: this.getBrowser(this.ua), landing_url: this.getLandingUrl(), first_seen: this.getFirstSeen(), url_param: this.getUrlParam(), user_agent: this.userAgent }, user); }; DefaultUserProvider.prototype.getLanguage = function () { return ((typeof navigator !== 'undefined' && ((navigator.languages && navigator.languages[0]) || navigator.language)) || ''); }; DefaultUserProvider.prototype.getOs = function (ua) { var _a, _b; return [(_a = ua.browser) === null || _a === void 0 ? void 0 : _a.name, (_b = ua.browser) === null || _b === void 0 ? void 0 : _b.major] .filter(function (e) { return e !== null && e !== undefined; }) .join(' '); }; DefaultUserProvider.prototype.getDeviceModel = function (ua) { var _a; return (_a = ua.os) === null || _a === void 0 ? void 0 : _a.name; }; DefaultUserProvider.prototype.getBrowser = function (ua) { var _a; var browser = (_a = ua.browser) === null || _a === void 0 ? void 0 : _a.name; // Normalize for Chrome, Firefox, Safari, Edge, and Opera. if (browser === null || browser === void 0 ? void 0 : browser.includes('Chrom')) browser = 'Chrome'; // Chrome, Chrome Mobile, Chromium, etc if (browser === null || browser === void 0 ? void 0 : browser.includes('Firefox')) browser = 'Firefox'; // Firefox, Firefox Mobile, etc if (browser === null || browser === void 0 ? void 0 : browser.includes('Safari')) browser = 'Safari'; // Safari, Safari Mobile if (browser === null || browser === void 0 ? void 0 : browser.includes('Edge')) browser = 'Edge'; // Edge if (browser === null || browser === void 0 ? void 0 : browser.includes('Opera')) browser = 'Opera'; // Opera, Opera Mobi, etc return browser; }; DefaultUserProvider.prototype.getCookie = function () { var _a, _b, _c, _d, _e; if (!((_b = (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.document) === null || _b === void 0 ? void 0 : _b.cookie)) { return undefined; } return Object.fromEntries((_e = (_d = (_c = this.globalScope) === null || _c === void 0 ? void 0 : _c.document) === null || _d === void 0 ? void 0 : _d.cookie) === null || _e === void 0 ? void 0 : _e.split('; ').map(function (c) { return c.split('='); })); }; DefaultUserProvider.prototype.getLandingUrl = function () { var _a, _b; try { var sessionUser = JSON.parse(this.sessionStorage.get(this.storageKey) || '{}'); if (!sessionUser.landing_url) { sessionUser.landing_url = (_b = (_a = this.globalScope) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href.replace(/\/$/, ''); this.sessionStorage.put(this.storageKey, JSON.stringify(sessionUser)); } return sessionUser.landing_url; } catch (_c) { return undefined; } }; DefaultUserProvider.prototype.getFirstSeen = function () { try { var localUser = JSON.parse(this.localStorage.get(this.storageKey) || '{}'); if (!localUser.first_seen) { localUser.first_seen = (Date.now() / 1000).toString(); this.localStorage.put(this.storageKey, JSON.stringify(localUser)); } return localUser.first_seen; } catch (_a) { return undefined; } }; DefaultUserProvider.prototype.getUrlParam = function () { var e_1, _a; var _b; if (!this.globalScope) { return undefined; } var params = {}; try { var url = new URL(this.globalScope.location.href); try { for (var _c = __values$2(url.searchParams), _d = _c.next(); !_d.done; _d = _c.next()) { var _e = __read$2(_d.value, 2), name_1 = _e[0], value = _e[1]; params[name_1] = __spreadArray$1(__spreadArray$1([], __read$2(((_b = params[name_1]) !== null && _b !== void 0 ? _b : [])), false), __read$2(value.split(',')), false); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_1) throw e_1.error; } } } catch (error) { return undefined; } return Object.entries(params).reduce(function (acc, _a) { var _b = __read$2(_a, 2), name = _b[0], value = _b[1]; acc[name] = value.length == 1 ? value[0] : value; return acc; }, {}); }; return DefaultUserProvider; }()); // Global instances for debugging. safeGlobal$1.experimentInstances = {}; var instances = safeGlobal$1.experimentInstances; /** * Initializes a singleton {@link ExperimentClient} identified by the configured * instance name. * * @param apiKey The deployment API Key * @param config See {@link ExperimentConfig} for config options */ var initialize = function (apiKey, config) { return _initialize(apiKey, config); }; /** * Initialize a singleton {@link ExperimentClient} which automatically * integrates with the installed and initialized instance of the amplitude * analytics SDK. * * You must be using amplitude-js SDK version 8.17.0+ for this integration to * work. * * @param apiKey The deployment API Key * @param config See {@link ExperimentConfig} for config options */ var initializeWithAmplitudeAnalytics = function (apiKey, config) { var plugin = function () { return new AmplitudeIntegrationPlugin(apiKey, AnalyticsConnector.getInstance(getInstanceName(config)), 10000); }; return _initialize(apiKey, config, plugin); }; var getInstanceName = function (config) { return (config === null || config === void 0 ? void 0 : config.instanceName) || Defaults.instanceName; }; var getInstanceKey = function (apiKey, config) { // Store instances by appending the instance name and api key. Allows for // initializing multiple default instances for different api keys. var instanceName = getInstanceName(config); // The internal instance name prefix is used by web experiment to differentiate // web and feature experiment sdks which use the same api key. var internalInstanceNameSuffix = config === null || config === void 0 ? void 0 : config['internalInstanceNameSuffix']; return internalInstanceNameSuffix ? "".concat(instanceName, ".").concat(apiKey, ".").concat(internalInstanceNameSuffix) : "".concat(instanceName, ".").concat(apiKey); }; var newExperimentClient = function (apiKey, config) { return new ExperimentClient(apiKey, __assign$2(__assign$2({}, config), { userProvider: new DefaultUserProvider(config === null || config === void 0 ? void 0 : config.userProvider, apiKey) })); }; var _initialize = function (apiKey, config, plugin) { var instanceKey = getInstanceKey(apiKey, config); var client = instances[instanceKey]; if (client) { return client; } client = newExperimentClient(apiKey, config); if (plugin) { client.addPlugin(plugin()); } instances[instanceKey] = client; return client; }; /** * Provides factory methods for storing singleton instances of {@link ExperimentClient} * @category Core Usage */ var Experiment = { initialize: initialize, initializeWithAmplitudeAnalytics: initializeWithAmplitudeAnalytics, }; /** * A stub {@link Client} implementation that does nothing for all methods */ var StubExperimentClient = /** @class */ (function () { function StubExperimentClient() { } StubExperimentClient.prototype.getUser = function () { return {}; }; StubExperimentClient.prototype.start = function (user) { return __awaiter$1(this, void 0, void 0, function () { return __generator$1(this, function (_a) { return [2 /*return*/]; }); }); }; StubExperimentClient.prototype.stop = function () { }; StubExperimentClient.prototype.setUser = function (user) { }; StubExperimentClient.prototype.fetch = function (user, options) { return __awaiter$1(this, void 0, void 0, function () { return __generator$1(this, function (_a) { return [2 /*return*/, this]; }); }); }; StubExperimentClient.prototype.getUserProvider = function () { return null; }; StubExperimentClient.prototype.setUserProvider = function (uerProvider) { return this; }; StubExperimentClient.prototype.variant = function (key, fallback) { return Defaults.fallbackVariant; }; StubExperimentClient.prototype.all = function () { return {}; }; StubExperimentClient.prototype.clear = function () { }; StubExperimentClient.prototype.exposure = function (key) { }; return StubExperimentClient; }()); exports.AmplitudeAnalyticsProvider = AmplitudeAnalyticsProvider; exports.AmplitudeIntegrationPlugin = AmplitudeIntegrationPlugin; exports.AmplitudeUserProvider = AmplitudeUserProvider; exports.Experiment = Experiment; exports.ExperimentClient = ExperimentClient; exports.StubExperimentClient = StubExperimentClient; exports.initialize = initialize; exports.initializeWithAmplitudeAnalytics = initializeWithAmplitudeAnalytics; Object.defineProperty(exports, '__esModule', { value: true }); }));