{"version":3,"file":"static/js/c213338a77ff4f8631a5.bundle.js","mappings":"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","sources":["webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/backoffController.js?c9ab","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/browserDatafileManager.js?a0e2","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/browserRequest.js?ed33","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/config.js?13d2","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/eventEmitter.js?48fd","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/httpPollingDatafileManager.js?dff8","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-datafile-manager/lib/index.browser.js?6ccb","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/eventDispatcher.js?1709","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/eventProcessor.js?361e","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/eventQueue.js?065e","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/events.js?9a8a","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/index.js?36e0","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/managed.js?7ec6","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/pendingEventsDispatcher.js?edb9","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/pendingEventsStore.js?66e8","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/requestTracker.js?4de2","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/v1/buildEventV1.js?ade6","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-event-processor/lib/v1/v1EventProcessor.js?8dc0","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-logging/lib/errorHandler.js?2e5b","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-logging/lib/index.js?8103","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-logging/lib/logger.js?d8ae","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-logging/lib/models.js?fd2f","webpack://mattressfirm/./node_modules/@optimizely/js-sdk-utils/lib/index.js?ec0a","webpack://mattressfirm/../node_modules/tslib/tslib.es6.js?6dbe","webpack://mattressfirm/../lib/utils/fns/index.ts?dd44","webpack://mattressfirm/../lib/utils/enums/index.ts?c573","webpack://mattressfirm/../lib/utils/config_validator/index.ts?48e0","webpack://mattressfirm/../lib/plugins/error_handler/index.ts?c0e1","webpack://mattressfirm/../lib/plugins/event_dispatcher/index.browser.ts?f3b3","webpack://mattressfirm/../lib/plugins/logger/index.ts?3d0b","webpack://mattressfirm/../lib/shared_types.ts?9bad","webpack://mattressfirm/../lib/optimizely_decision/index.ts?7965","webpack://mattressfirm/../lib/optimizely_user_context/index.ts?a55d","webpack://mattressfirm/../lib/core/condition_tree_evaluator/index.ts?dbd4","webpack://mattressfirm/../lib/core/optimizely_config/index.ts?9c43","webpack://mattressfirm/../lib/core/project_config/index.ts?ce32","webpack://mattressfirm/../lib/core/project_config/project_config_manager.ts?df4f","webpack://mattressfirm/../lib/core/bucketer/index.ts?33a0","webpack://mattressfirm/../lib/utils/semantic_version/index.ts?9691","webpack://mattressfirm/../lib/core/custom_attribute_condition_evaluator/index.ts?7488","webpack://mattressfirm/../lib/core/audience_evaluator/index.ts?5ec5","webpack://mattressfirm/../lib/utils/string_value_validator/index.ts?aa55","webpack://mattressfirm/../lib/core/decision_service/index.ts?52c1","webpack://mattressfirm/../lib/utils/event_tag_utils/index.ts?809c","webpack://mattressfirm/../lib/utils/attributes_validator/index.ts?42cb","webpack://mattressfirm/../lib/core/event_builder/index.ts?ae89","webpack://mattressfirm/../lib/core/decision/index.ts?fe54","webpack://mattressfirm/../lib/core/event_builder/event_helpers.ts?fb6b","webpack://mattressfirm/../lib/utils/user_profile_service_validator/index.ts?dab8","webpack://mattressfirm/../lib/optimizely/index.ts?5614","webpack://mattressfirm/../lib/utils/event_tags_validator/index.ts?2e25","webpack://mattressfirm/../lib/utils/event_processor_config_validator/index.ts?20f9","webpack://mattressfirm/../lib/core/notification_center/index.ts?0fff","webpack://mattressfirm/../lib/plugins/event_processor/index.ts?3fc3","webpack://mattressfirm/../lib/plugins/datafile_manager/http_polling_datafile_manager.ts?ad59","webpack://mattressfirm/../lib/index.browser.ts?b89c"],"sourcesContent":["\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar config_1 = require(\"./config\");\nfunction randomMilliseconds() {\n return Math.round(Math.random() * 1000);\n}\nvar BackoffController = /** @class */ (function () {\n function BackoffController() {\n this.errorCount = 0;\n }\n BackoffController.prototype.getDelay = function () {\n if (this.errorCount === 0) {\n return 0;\n }\n var baseWaitSeconds = config_1.BACKOFF_BASE_WAIT_SECONDS_BY_ERROR_COUNT[Math.min(config_1.BACKOFF_BASE_WAIT_SECONDS_BY_ERROR_COUNT.length - 1, this.errorCount)];\n return baseWaitSeconds * 1000 + randomMilliseconds();\n };\n BackoffController.prototype.countError = function () {\n if (this.errorCount < config_1.BACKOFF_BASE_WAIT_SECONDS_BY_ERROR_COUNT.length - 1) {\n this.errorCount++;\n }\n };\n BackoffController.prototype.reset = function () {\n this.errorCount = 0;\n };\n return BackoffController;\n}());\nexports.default = BackoffController;\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar browserRequest_1 = require(\"./browserRequest\");\nvar httpPollingDatafileManager_1 = __importDefault(require(\"./httpPollingDatafileManager\"));\nvar BrowserDatafileManager = /** @class */ (function (_super) {\n __extends(BrowserDatafileManager, _super);\n function BrowserDatafileManager() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n BrowserDatafileManager.prototype.makeGetRequest = function (reqUrl, headers) {\n return browserRequest_1.makeGetRequest(reqUrl, headers);\n };\n BrowserDatafileManager.prototype.getConfigDefaults = function () {\n return {\n autoUpdate: false,\n };\n };\n return BrowserDatafileManager;\n}(httpPollingDatafileManager_1.default));\nexports.default = BrowserDatafileManager;\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar config_1 = require(\"./config\");\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar logger = js_sdk_logging_1.getLogger('DatafileManager');\nvar GET_METHOD = 'GET';\nvar READY_STATE_DONE = 4;\nfunction parseHeadersFromXhr(req) {\n var allHeadersString = req.getAllResponseHeaders();\n if (allHeadersString === null) {\n return {};\n }\n var headerLines = allHeadersString.split('\\r\\n');\n var headers = {};\n headerLines.forEach(function (headerLine) {\n var separatorIndex = headerLine.indexOf(': ');\n if (separatorIndex > -1) {\n var headerName = headerLine.slice(0, separatorIndex);\n var headerValue = headerLine.slice(separatorIndex + 2);\n if (headerValue.length > 0) {\n headers[headerName] = headerValue;\n }\n }\n });\n return headers;\n}\nfunction setHeadersInXhr(headers, req) {\n Object.keys(headers).forEach(function (headerName) {\n var header = headers[headerName];\n req.setRequestHeader(headerName, header);\n });\n}\nfunction makeGetRequest(reqUrl, headers) {\n var req = new XMLHttpRequest();\n var responsePromise = new Promise(function (resolve, reject) {\n req.open(GET_METHOD, reqUrl, true);\n setHeadersInXhr(headers, req);\n req.onreadystatechange = function () {\n if (req.readyState === READY_STATE_DONE) {\n var statusCode = req.status;\n if (statusCode === 0) {\n reject(new Error('Request error'));\n return;\n }\n var headers_1 = parseHeadersFromXhr(req);\n var resp = {\n statusCode: req.status,\n body: req.responseText,\n headers: headers_1,\n };\n resolve(resp);\n }\n };\n req.timeout = config_1.REQUEST_TIMEOUT_MS;\n req.ontimeout = function () {\n logger.error('Request timed out');\n };\n req.send();\n });\n return {\n responsePromise: responsePromise,\n abort: function () {\n req.abort();\n },\n };\n}\nexports.makeGetRequest = makeGetRequest;\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.DEFAULT_UPDATE_INTERVAL = 5 * 60 * 1000; // 5 minutes\nexports.MIN_UPDATE_INTERVAL = 1000;\nexports.DEFAULT_URL_TEMPLATE = \"https://cdn.optimizely.com/datafiles/%s.json\";\nexports.DEFAULT_AUTHENTICATED_URL_TEMPLATE = \"https://config.optimizely.com/datafiles/auth/%s.json\";\nexports.BACKOFF_BASE_WAIT_SECONDS_BY_ERROR_COUNT = [0, 8, 16, 32, 64, 128, 256, 512];\nexports.REQUEST_TIMEOUT_MS = 60 * 1000; // 1 minute\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar EventEmitter = /** @class */ (function () {\n function EventEmitter() {\n this.listeners = {};\n this.listenerId = 1;\n }\n EventEmitter.prototype.on = function (eventName, listener) {\n var _this = this;\n if (!this.listeners[eventName]) {\n this.listeners[eventName] = {};\n }\n var currentListenerId = String(this.listenerId);\n this.listenerId++;\n this.listeners[eventName][currentListenerId] = listener;\n return function () {\n if (_this.listeners[eventName]) {\n delete _this.listeners[eventName][currentListenerId];\n }\n };\n };\n EventEmitter.prototype.emit = function (eventName, arg) {\n var listeners = this.listeners[eventName];\n if (listeners) {\n Object.keys(listeners).forEach(function (listenerId) {\n var listener = listeners[listenerId];\n listener(arg);\n });\n }\n };\n EventEmitter.prototype.removeAllListeners = function () {\n this.listeners = {};\n };\n return EventEmitter;\n}());\nexports.default = EventEmitter;\n// TODO: Create a typed event emitter for use in TS only (not JS)\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar js_sdk_utils_1 = require(\"@optimizely/js-sdk-utils\");\nvar eventEmitter_1 = __importDefault(require(\"./eventEmitter\"));\nvar config_1 = require(\"./config\");\nvar backoffController_1 = __importDefault(require(\"./backoffController\"));\nvar logger = js_sdk_logging_1.getLogger('DatafileManager');\nvar UPDATE_EVT = 'update';\nfunction isValidUpdateInterval(updateInterval) {\n return updateInterval >= config_1.MIN_UPDATE_INTERVAL;\n}\nfunction isSuccessStatusCode(statusCode) {\n return statusCode >= 200 && statusCode < 400;\n}\nvar noOpKeyValueCache = {\n get: function () {\n return Promise.resolve('');\n },\n set: function () {\n return Promise.resolve();\n },\n contains: function () {\n return Promise.resolve(false);\n },\n remove: function () {\n return Promise.resolve();\n },\n};\nvar HttpPollingDatafileManager = /** @class */ (function () {\n function HttpPollingDatafileManager(config) {\n var _this = this;\n var configWithDefaultsApplied = __assign(__assign({}, this.getConfigDefaults()), config);\n var datafile = configWithDefaultsApplied.datafile, _a = configWithDefaultsApplied.autoUpdate, autoUpdate = _a === void 0 ? false : _a, sdkKey = configWithDefaultsApplied.sdkKey, _b = configWithDefaultsApplied.updateInterval, updateInterval = _b === void 0 ? config_1.DEFAULT_UPDATE_INTERVAL : _b, _c = configWithDefaultsApplied.urlTemplate, urlTemplate = _c === void 0 ? config_1.DEFAULT_URL_TEMPLATE : _c, _d = configWithDefaultsApplied.cache, cache = _d === void 0 ? noOpKeyValueCache : _d;\n this.cache = cache;\n this.cacheKey = 'opt-datafile-' + sdkKey;\n this.isReadyPromiseSettled = false;\n this.readyPromiseResolver = function () { };\n this.readyPromiseRejecter = function () { };\n this.readyPromise = new Promise(function (resolve, reject) {\n _this.readyPromiseResolver = resolve;\n _this.readyPromiseRejecter = reject;\n });\n if (datafile) {\n this.currentDatafile = datafile;\n if (!sdkKey) {\n this.resolveReadyPromise();\n }\n }\n else {\n this.currentDatafile = '';\n }\n this.isStarted = false;\n this.datafileUrl = js_sdk_utils_1.sprintf(urlTemplate, sdkKey);\n this.emitter = new eventEmitter_1.default();\n this.autoUpdate = autoUpdate;\n if (isValidUpdateInterval(updateInterval)) {\n this.updateInterval = updateInterval;\n }\n else {\n logger.warn('Invalid updateInterval %s, defaulting to %s', updateInterval, config_1.DEFAULT_UPDATE_INTERVAL);\n this.updateInterval = config_1.DEFAULT_UPDATE_INTERVAL;\n }\n this.currentTimeout = null;\n this.currentRequest = null;\n this.backoffController = new backoffController_1.default();\n this.syncOnCurrentRequestComplete = false;\n }\n HttpPollingDatafileManager.prototype.get = function () {\n return this.currentDatafile;\n };\n HttpPollingDatafileManager.prototype.start = function () {\n if (!this.isStarted) {\n logger.debug('Datafile manager started');\n this.isStarted = true;\n this.backoffController.reset();\n this.setDatafileFromCacheIfAvailable();\n this.syncDatafile();\n }\n };\n HttpPollingDatafileManager.prototype.stop = function () {\n logger.debug('Datafile manager stopped');\n this.isStarted = false;\n if (this.currentTimeout) {\n clearTimeout(this.currentTimeout);\n this.currentTimeout = null;\n }\n this.emitter.removeAllListeners();\n if (this.currentRequest) {\n this.currentRequest.abort();\n this.currentRequest = null;\n }\n return Promise.resolve();\n };\n HttpPollingDatafileManager.prototype.onReady = function () {\n return this.readyPromise;\n };\n HttpPollingDatafileManager.prototype.on = function (eventName, listener) {\n return this.emitter.on(eventName, listener);\n };\n HttpPollingDatafileManager.prototype.onRequestRejected = function (err) {\n if (!this.isStarted) {\n return;\n }\n this.backoffController.countError();\n if (err instanceof Error) {\n logger.error('Error fetching datafile: %s', err.message, err);\n }\n else if (typeof err === 'string') {\n logger.error('Error fetching datafile: %s', err);\n }\n else {\n logger.error('Error fetching datafile');\n }\n };\n HttpPollingDatafileManager.prototype.onRequestResolved = function (response) {\n if (!this.isStarted) {\n return;\n }\n if (typeof response.statusCode !== 'undefined' && isSuccessStatusCode(response.statusCode)) {\n this.backoffController.reset();\n }\n else {\n this.backoffController.countError();\n }\n this.trySavingLastModified(response.headers);\n var datafile = this.getNextDatafileFromResponse(response);\n if (datafile !== '') {\n logger.info('Updating datafile from response');\n this.currentDatafile = datafile;\n this.cache.set(this.cacheKey, datafile);\n if (!this.isReadyPromiseSettled) {\n this.resolveReadyPromise();\n }\n else {\n var datafileUpdate = {\n datafile: datafile,\n };\n this.emitter.emit(UPDATE_EVT, datafileUpdate);\n }\n }\n };\n HttpPollingDatafileManager.prototype.onRequestComplete = function () {\n if (!this.isStarted) {\n return;\n }\n this.currentRequest = null;\n if (!this.isReadyPromiseSettled && !this.autoUpdate) {\n // We will never resolve ready, so reject it\n this.rejectReadyPromise(new Error('Failed to become ready'));\n }\n if (this.autoUpdate && this.syncOnCurrentRequestComplete) {\n this.syncDatafile();\n }\n this.syncOnCurrentRequestComplete = false;\n };\n HttpPollingDatafileManager.prototype.syncDatafile = function () {\n var _this = this;\n var headers = {};\n if (this.lastResponseLastModified) {\n headers['if-modified-since'] = this.lastResponseLastModified;\n }\n logger.debug('Making datafile request to url %s with headers: %s', this.datafileUrl, function () { return JSON.stringify(headers); });\n this.currentRequest = this.makeGetRequest(this.datafileUrl, headers);\n var onRequestComplete = function () {\n _this.onRequestComplete();\n };\n var onRequestResolved = function (response) {\n _this.onRequestResolved(response);\n };\n var onRequestRejected = function (err) {\n _this.onRequestRejected(err);\n };\n this.currentRequest.responsePromise\n .then(onRequestResolved, onRequestRejected)\n .then(onRequestComplete, onRequestComplete);\n if (this.autoUpdate) {\n this.scheduleNextUpdate();\n }\n };\n HttpPollingDatafileManager.prototype.resolveReadyPromise = function () {\n this.readyPromiseResolver();\n this.isReadyPromiseSettled = true;\n };\n HttpPollingDatafileManager.prototype.rejectReadyPromise = function (err) {\n this.readyPromiseRejecter(err);\n this.isReadyPromiseSettled = true;\n };\n HttpPollingDatafileManager.prototype.scheduleNextUpdate = function () {\n var _this = this;\n var currentBackoffDelay = this.backoffController.getDelay();\n var nextUpdateDelay = Math.max(currentBackoffDelay, this.updateInterval);\n logger.debug('Scheduling sync in %s ms', nextUpdateDelay);\n this.currentTimeout = setTimeout(function () {\n if (_this.currentRequest) {\n _this.syncOnCurrentRequestComplete = true;\n }\n else {\n _this.syncDatafile();\n }\n }, nextUpdateDelay);\n };\n HttpPollingDatafileManager.prototype.getNextDatafileFromResponse = function (response) {\n logger.debug('Response status code: %s', response.statusCode);\n if (typeof response.statusCode === 'undefined') {\n return '';\n }\n if (response.statusCode === 304) {\n return '';\n }\n if (isSuccessStatusCode(response.statusCode)) {\n return response.body;\n }\n return '';\n };\n HttpPollingDatafileManager.prototype.trySavingLastModified = function (headers) {\n var lastModifiedHeader = headers['last-modified'] || headers['Last-Modified'];\n if (typeof lastModifiedHeader !== 'undefined') {\n this.lastResponseLastModified = lastModifiedHeader;\n logger.debug('Saved last modified header value from response: %s', this.lastResponseLastModified);\n }\n };\n HttpPollingDatafileManager.prototype.setDatafileFromCacheIfAvailable = function () {\n var _this = this;\n this.cache.get(this.cacheKey).then(function (datafile) {\n if (_this.isStarted && !_this.isReadyPromiseSettled && datafile !== '') {\n logger.debug('Using datafile from cache');\n _this.currentDatafile = datafile;\n _this.resolveReadyPromise();\n }\n });\n };\n return HttpPollingDatafileManager;\n}());\nexports.default = HttpPollingDatafileManager;\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar browserDatafileManager_1 = require(\"./browserDatafileManager\");\nexports.HttpPollingDatafileManager = browserDatafileManager_1.default;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.sendEventNotification = exports.getQueue = exports.validateAndGetBatchSize = exports.validateAndGetFlushInterval = exports.DEFAULT_BATCH_SIZE = exports.DEFAULT_FLUSH_INTERVAL = void 0;\nvar eventQueue_1 = require(\"./eventQueue\");\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar js_sdk_utils_1 = require(\"@optimizely/js-sdk-utils\");\nexports.DEFAULT_FLUSH_INTERVAL = 30000; // Unit is ms - default flush interval is 30s\nexports.DEFAULT_BATCH_SIZE = 10;\nvar logger = js_sdk_logging_1.getLogger('EventProcessor');\nfunction validateAndGetFlushInterval(flushInterval) {\n if (flushInterval <= 0) {\n logger.warn(\"Invalid flushInterval \" + flushInterval + \", defaulting to \" + exports.DEFAULT_FLUSH_INTERVAL);\n flushInterval = exports.DEFAULT_FLUSH_INTERVAL;\n }\n return flushInterval;\n}\nexports.validateAndGetFlushInterval = validateAndGetFlushInterval;\nfunction validateAndGetBatchSize(batchSize) {\n batchSize = Math.floor(batchSize);\n if (batchSize < 1) {\n logger.warn(\"Invalid batchSize \" + batchSize + \", defaulting to \" + exports.DEFAULT_BATCH_SIZE);\n batchSize = exports.DEFAULT_BATCH_SIZE;\n }\n batchSize = Math.max(1, batchSize);\n return batchSize;\n}\nexports.validateAndGetBatchSize = validateAndGetBatchSize;\nfunction getQueue(batchSize, flushInterval, sink, batchComparator) {\n var queue;\n if (batchSize > 1) {\n queue = new eventQueue_1.DefaultEventQueue({\n flushInterval: flushInterval,\n maxQueueSize: batchSize,\n sink: sink,\n batchComparator: batchComparator,\n });\n }\n else {\n queue = new eventQueue_1.SingleEventQueue({ sink: sink });\n }\n return queue;\n}\nexports.getQueue = getQueue;\nfunction sendEventNotification(notificationCenter, event) {\n if (notificationCenter) {\n notificationCenter.sendNotifications(js_sdk_utils_1.NOTIFICATION_TYPES.LOG_EVENT, event);\n }\n}\nexports.sendEventNotification = sendEventNotification;\n","\"use strict\";\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.DefaultEventQueue = exports.SingleEventQueue = void 0;\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar logger = js_sdk_logging_1.getLogger('EventProcessor');\nvar Timer = /** @class */ (function () {\n function Timer(_a) {\n var timeout = _a.timeout, callback = _a.callback;\n this.timeout = Math.max(timeout, 0);\n this.callback = callback;\n }\n Timer.prototype.start = function () {\n this.timeoutId = setTimeout(this.callback, this.timeout);\n };\n Timer.prototype.refresh = function () {\n this.stop();\n this.start();\n };\n Timer.prototype.stop = function () {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n }\n };\n return Timer;\n}());\nvar SingleEventQueue = /** @class */ (function () {\n function SingleEventQueue(_a) {\n var sink = _a.sink;\n this.sink = sink;\n }\n SingleEventQueue.prototype.start = function () {\n // no-op\n };\n SingleEventQueue.prototype.stop = function () {\n // no-op\n return Promise.resolve();\n };\n SingleEventQueue.prototype.enqueue = function (event) {\n this.sink([event]);\n };\n return SingleEventQueue;\n}());\nexports.SingleEventQueue = SingleEventQueue;\nvar DefaultEventQueue = /** @class */ (function () {\n function DefaultEventQueue(_a) {\n var flushInterval = _a.flushInterval, maxQueueSize = _a.maxQueueSize, sink = _a.sink, batchComparator = _a.batchComparator;\n this.buffer = [];\n this.maxQueueSize = Math.max(maxQueueSize, 1);\n this.sink = sink;\n this.batchComparator = batchComparator;\n this.timer = new Timer({\n callback: this.flush.bind(this),\n timeout: flushInterval,\n });\n this.started = false;\n }\n DefaultEventQueue.prototype.start = function () {\n this.started = true;\n // dont start the timer until the first event is enqueued\n };\n DefaultEventQueue.prototype.stop = function () {\n this.started = false;\n var result = this.sink(this.buffer);\n this.buffer = [];\n this.timer.stop();\n return result;\n };\n DefaultEventQueue.prototype.enqueue = function (event) {\n if (!this.started) {\n logger.warn('Queue is stopped, not accepting event');\n return;\n }\n // If new event cannot be included into the current batch, flush so it can\n // be in its own new batch.\n var bufferedEvent = this.buffer[0];\n if (bufferedEvent && !this.batchComparator(bufferedEvent, event)) {\n this.flush();\n }\n // start the timer when the first event is put in\n if (this.buffer.length === 0) {\n this.timer.refresh();\n }\n this.buffer.push(event);\n if (this.buffer.length >= this.maxQueueSize) {\n this.flush();\n }\n };\n DefaultEventQueue.prototype.flush = function () {\n this.sink(this.buffer);\n this.buffer = [];\n this.timer.stop();\n };\n return DefaultEventQueue;\n}());\nexports.DefaultEventQueue = DefaultEventQueue;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.areEventContextsEqual = void 0;\nfunction areEventContextsEqual(eventA, eventB) {\n var contextA = eventA.context;\n var contextB = eventB.context;\n return (contextA.accountId === contextB.accountId &&\n contextA.projectId === contextB.projectId &&\n contextA.clientName === contextB.clientName &&\n contextA.clientVersion === contextB.clientVersion &&\n contextA.revision === contextB.revision &&\n contextA.anonymizeIP === contextB.anonymizeIP &&\n contextA.botFiltering === contextB.botFiltering);\n}\nexports.areEventContextsEqual = areEventContextsEqual;\n","\"use strict\";\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./events\"), exports);\n__exportStar(require(\"./eventProcessor\"), exports);\n__exportStar(require(\"./eventDispatcher\"), exports);\n__exportStar(require(\"./managed\"), exports);\n__exportStar(require(\"./pendingEventsDispatcher\"), exports);\n__exportStar(require(\"./v1/buildEventV1\"), exports);\n__exportStar(require(\"./v1/v1EventProcessor\"), exports);\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n","\"use strict\";\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.LocalStoragePendingEventsDispatcher = exports.PendingEventsDispatcher = void 0;\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar pendingEventsStore_1 = require(\"./pendingEventsStore\");\nvar js_sdk_utils_1 = require(\"@optimizely/js-sdk-utils\");\nvar logger = js_sdk_logging_1.getLogger('EventProcessor');\nvar PendingEventsDispatcher = /** @class */ (function () {\n function PendingEventsDispatcher(_a) {\n var eventDispatcher = _a.eventDispatcher, store = _a.store;\n this.dispatcher = eventDispatcher;\n this.store = store;\n }\n PendingEventsDispatcher.prototype.dispatchEvent = function (request, callback) {\n this.send({\n uuid: js_sdk_utils_1.generateUUID(),\n timestamp: js_sdk_utils_1.getTimestamp(),\n request: request,\n }, callback);\n };\n PendingEventsDispatcher.prototype.sendPendingEvents = function () {\n var _this = this;\n var pendingEvents = this.store.values();\n logger.debug('Sending %s pending events from previous page', pendingEvents.length);\n pendingEvents.forEach(function (item) {\n try {\n _this.send(item, function () { });\n }\n catch (e) { }\n });\n };\n PendingEventsDispatcher.prototype.send = function (entry, callback) {\n var _this = this;\n this.store.set(entry.uuid, entry);\n this.dispatcher.dispatchEvent(entry.request, function (response) {\n _this.store.remove(entry.uuid);\n callback(response);\n });\n };\n return PendingEventsDispatcher;\n}());\nexports.PendingEventsDispatcher = PendingEventsDispatcher;\nvar LocalStoragePendingEventsDispatcher = /** @class */ (function (_super) {\n __extends(LocalStoragePendingEventsDispatcher, _super);\n function LocalStoragePendingEventsDispatcher(_a) {\n var eventDispatcher = _a.eventDispatcher;\n return _super.call(this, {\n eventDispatcher: eventDispatcher,\n store: new pendingEventsStore_1.LocalStorageStore({\n // TODO make this configurable\n maxValues: 100,\n key: 'fs_optly_pending_events',\n }),\n }) || this;\n }\n return LocalStoragePendingEventsDispatcher;\n}(PendingEventsDispatcher));\nexports.LocalStoragePendingEventsDispatcher = LocalStoragePendingEventsDispatcher;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.LocalStorageStore = void 0;\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar js_sdk_utils_1 = require(\"@optimizely/js-sdk-utils\");\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar logger = js_sdk_logging_1.getLogger('EventProcessor');\nvar LocalStorageStore = /** @class */ (function () {\n function LocalStorageStore(_a) {\n var key = _a.key, _b = _a.maxValues, maxValues = _b === void 0 ? 1000 : _b;\n this.LS_KEY = key;\n this.maxValues = maxValues;\n }\n LocalStorageStore.prototype.get = function (key) {\n return this.getMap()[key] || null;\n };\n LocalStorageStore.prototype.set = function (key, value) {\n var map = this.getMap();\n map[key] = value;\n this.replace(map);\n };\n LocalStorageStore.prototype.remove = function (key) {\n var map = this.getMap();\n delete map[key];\n this.replace(map);\n };\n LocalStorageStore.prototype.values = function () {\n return js_sdk_utils_1.objectValues(this.getMap());\n };\n LocalStorageStore.prototype.clear = function () {\n this.replace({});\n };\n LocalStorageStore.prototype.replace = function (map) {\n try {\n // This is a temporary fix to support React Native which does not have localStorage.\n window.localStorage && localStorage.setItem(this.LS_KEY, JSON.stringify(map));\n this.clean();\n }\n catch (e) {\n logger.error(e);\n }\n };\n LocalStorageStore.prototype.clean = function () {\n var map = this.getMap();\n var keys = Object.keys(map);\n var toRemove = keys.length - this.maxValues;\n if (toRemove < 1) {\n return;\n }\n var entries = keys.map(function (key) { return ({\n key: key,\n value: map[key]\n }); });\n entries.sort(function (a, b) { return a.value.timestamp - b.value.timestamp; });\n for (var i = 0; i < toRemove; i++) {\n delete map[entries[i].key];\n }\n this.replace(map);\n };\n LocalStorageStore.prototype.getMap = function () {\n try {\n // This is a temporary fix to support React Native which does not have localStorage.\n var data = window.localStorage && localStorage.getItem(this.LS_KEY);\n if (data) {\n return JSON.parse(data) || {};\n }\n }\n catch (e) {\n logger.error(e);\n }\n return {};\n };\n return LocalStorageStore;\n}());\nexports.LocalStorageStore = LocalStorageStore;\n","\"use strict\";\n/**\n * Copyright 2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * RequestTracker keeps track of in-flight requests for EventProcessor using\n * an internal counter. It exposes methods for adding a new request to be\n * tracked, and getting a Promise representing the completion of currently\n * tracked requests.\n */\nvar RequestTracker = /** @class */ (function () {\n function RequestTracker() {\n this.reqsInFlightCount = 0;\n this.reqsCompleteResolvers = [];\n }\n /**\n * Track the argument request (represented by a Promise). reqPromise will feed\n * into the state of Promises returned by onRequestsComplete.\n * @param {Promise} reqPromise\n */\n RequestTracker.prototype.trackRequest = function (reqPromise) {\n var _this = this;\n this.reqsInFlightCount++;\n var onReqComplete = function () {\n _this.reqsInFlightCount--;\n if (_this.reqsInFlightCount === 0) {\n _this.reqsCompleteResolvers.forEach(function (resolver) { return resolver(); });\n _this.reqsCompleteResolvers = [];\n }\n };\n reqPromise.then(onReqComplete, onReqComplete);\n };\n /**\n * Return a Promise that fulfills after all currently-tracked request promises\n * are resolved.\n * @return {Promise}\n */\n RequestTracker.prototype.onRequestsComplete = function () {\n var _this = this;\n return new Promise(function (resolve) {\n if (_this.reqsInFlightCount === 0) {\n resolve();\n }\n else {\n _this.reqsCompleteResolvers.push(resolve);\n }\n });\n };\n return RequestTracker;\n}());\nexports.default = RequestTracker;\n","\"use strict\";\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.formatEvents = exports.buildConversionEventV1 = exports.buildImpressionEventV1 = exports.makeBatchedEventV1 = void 0;\nvar ACTIVATE_EVENT_KEY = 'campaign_activated';\nvar CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom';\nvar BOT_FILTERING_KEY = '$opt_bot_filtering';\n/**\n * Given an array of batchable Decision or ConversionEvent events it returns\n * a single EventV1 with proper batching\n *\n * @param {ProcessableEvent[]} events\n * @returns {EventV1}\n */\nfunction makeBatchedEventV1(events) {\n var visitors = [];\n var data = events[0];\n events.forEach(function (event) {\n if (event.type === 'conversion' || event.type === 'impression') {\n var visitor = makeVisitor(event);\n if (event.type === 'impression') {\n visitor.snapshots.push(makeDecisionSnapshot(event));\n }\n else if (event.type === 'conversion') {\n visitor.snapshots.push(makeConversionSnapshot(event));\n }\n visitors.push(visitor);\n }\n });\n return {\n client_name: data.context.clientName,\n client_version: data.context.clientVersion,\n account_id: data.context.accountId,\n project_id: data.context.projectId,\n revision: data.context.revision,\n anonymize_ip: data.context.anonymizeIP,\n enrich_decisions: true,\n visitors: visitors,\n };\n}\nexports.makeBatchedEventV1 = makeBatchedEventV1;\nfunction makeConversionSnapshot(conversion) {\n var tags = __assign({}, conversion.tags);\n delete tags['revenue'];\n delete tags['value'];\n var event = {\n entity_id: conversion.event.id,\n key: conversion.event.key,\n timestamp: conversion.timestamp,\n uuid: conversion.uuid,\n };\n if (conversion.tags) {\n event.tags = conversion.tags;\n }\n if (conversion.value != null) {\n event.value = conversion.value;\n }\n if (conversion.revenue != null) {\n event.revenue = conversion.revenue;\n }\n return {\n events: [event],\n };\n}\nfunction makeDecisionSnapshot(event) {\n var _a, _b;\n var layer = event.layer, experiment = event.experiment, variation = event.variation, ruleKey = event.ruleKey, flagKey = event.flagKey, ruleType = event.ruleType, enabled = event.enabled;\n var layerId = layer ? layer.id : null;\n var experimentId = (_a = experiment === null || experiment === void 0 ? void 0 : experiment.id) !== null && _a !== void 0 ? _a : '';\n var variationId = (_b = variation === null || variation === void 0 ? void 0 : variation.id) !== null && _b !== void 0 ? _b : '';\n var variationKey = variation ? variation.key : '';\n return {\n decisions: [\n {\n campaign_id: layerId,\n experiment_id: experimentId,\n variation_id: variationId,\n metadata: {\n flag_key: flagKey,\n rule_key: ruleKey,\n rule_type: ruleType,\n variation_key: variationKey,\n enabled: enabled,\n },\n },\n ],\n events: [\n {\n entity_id: layerId,\n timestamp: event.timestamp,\n key: ACTIVATE_EVENT_KEY,\n uuid: event.uuid,\n },\n ],\n };\n}\nfunction makeVisitor(data) {\n var visitor = {\n snapshots: [],\n visitor_id: data.user.id,\n attributes: [],\n };\n data.user.attributes.forEach(function (attr) {\n visitor.attributes.push({\n entity_id: attr.entityId,\n key: attr.key,\n type: 'custom',\n value: attr.value,\n });\n });\n if (typeof data.context.botFiltering === 'boolean') {\n visitor.attributes.push({\n entity_id: BOT_FILTERING_KEY,\n key: BOT_FILTERING_KEY,\n type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,\n value: data.context.botFiltering,\n });\n }\n return visitor;\n}\n/**\n * Event for usage with v1 logtier\n *\n * @export\n * @interface EventBuilderV1\n */\nfunction buildImpressionEventV1(data) {\n var visitor = makeVisitor(data);\n visitor.snapshots.push(makeDecisionSnapshot(data));\n return {\n client_name: data.context.clientName,\n client_version: data.context.clientVersion,\n account_id: data.context.accountId,\n project_id: data.context.projectId,\n revision: data.context.revision,\n anonymize_ip: data.context.anonymizeIP,\n enrich_decisions: true,\n visitors: [visitor],\n };\n}\nexports.buildImpressionEventV1 = buildImpressionEventV1;\nfunction buildConversionEventV1(data) {\n var visitor = makeVisitor(data);\n visitor.snapshots.push(makeConversionSnapshot(data));\n return {\n client_name: data.context.clientName,\n client_version: data.context.clientVersion,\n account_id: data.context.accountId,\n project_id: data.context.projectId,\n revision: data.context.revision,\n anonymize_ip: data.context.anonymizeIP,\n enrich_decisions: true,\n visitors: [visitor],\n };\n}\nexports.buildConversionEventV1 = buildConversionEventV1;\nfunction formatEvents(events) {\n return {\n url: 'https://logx.optimizely.com/v1/events',\n httpVerb: 'POST',\n params: makeBatchedEventV1(events),\n };\n}\nexports.formatEvents = formatEvents;\n","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (this && this.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.LogTierV1EventProcessor = void 0;\n/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar js_sdk_logging_1 = require(\"@optimizely/js-sdk-logging\");\nvar eventProcessor_1 = require(\"../eventProcessor\");\nvar requestTracker_1 = __importDefault(require(\"../requestTracker\"));\nvar events_1 = require(\"../events\");\nvar buildEventV1_1 = require(\"./buildEventV1\");\nvar logger = js_sdk_logging_1.getLogger('LogTierV1EventProcessor');\nvar LogTierV1EventProcessor = /** @class */ (function () {\n function LogTierV1EventProcessor(_a) {\n var dispatcher = _a.dispatcher, _b = _a.flushInterval, flushInterval = _b === void 0 ? eventProcessor_1.DEFAULT_FLUSH_INTERVAL : _b, _c = _a.batchSize, batchSize = _c === void 0 ? eventProcessor_1.DEFAULT_BATCH_SIZE : _c, notificationCenter = _a.notificationCenter;\n this.dispatcher = dispatcher;\n this.notificationCenter = notificationCenter;\n this.requestTracker = new requestTracker_1.default();\n flushInterval = eventProcessor_1.validateAndGetFlushInterval(flushInterval);\n batchSize = eventProcessor_1.validateAndGetBatchSize(batchSize);\n this.queue = eventProcessor_1.getQueue(batchSize, flushInterval, this.drainQueue.bind(this), events_1.areEventContextsEqual);\n }\n LogTierV1EventProcessor.prototype.drainQueue = function (buffer) {\n var _this = this;\n var reqPromise = new Promise(function (resolve) {\n logger.debug('draining queue with %s events', buffer.length);\n if (buffer.length === 0) {\n resolve();\n return;\n }\n var formattedEvent = buildEventV1_1.formatEvents(buffer);\n _this.dispatcher.dispatchEvent(formattedEvent, function () {\n resolve();\n });\n eventProcessor_1.sendEventNotification(_this.notificationCenter, formattedEvent);\n });\n this.requestTracker.trackRequest(reqPromise);\n return reqPromise;\n };\n LogTierV1EventProcessor.prototype.process = function (event) {\n this.queue.enqueue(event);\n };\n LogTierV1EventProcessor.prototype.stop = function () {\n // swallow - an error stopping this queue shouldn't prevent this from stopping\n try {\n this.queue.stop();\n return this.requestTracker.onRequestsComplete();\n }\n catch (e) {\n logger.error('Error stopping EventProcessor: \"%s\"', e.message, e);\n }\n return Promise.resolve();\n };\n LogTierV1EventProcessor.prototype.start = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n this.queue.start();\n return [2 /*return*/];\n });\n });\n };\n return LogTierV1EventProcessor;\n}());\nexports.LogTierV1EventProcessor = LogTierV1EventProcessor;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * @export\n * @class NoopErrorHandler\n * @implements {ErrorHandler}\n */\nvar NoopErrorHandler = /** @class */ (function () {\n function NoopErrorHandler() {\n }\n /**\n * @param {Error} exception\n * @memberof NoopErrorHandler\n */\n NoopErrorHandler.prototype.handleError = function (exception) {\n // no-op\n return;\n };\n return NoopErrorHandler;\n}());\nexports.NoopErrorHandler = NoopErrorHandler;\nvar globalErrorHandler = new NoopErrorHandler();\n/**\n * @export\n * @param {ErrorHandler} handler\n */\nfunction setErrorHandler(handler) {\n globalErrorHandler = handler;\n}\nexports.setErrorHandler = setErrorHandler;\n/**\n * @export\n * @returns {ErrorHandler}\n */\nfunction getErrorHandler() {\n return globalErrorHandler;\n}\nexports.getErrorHandler = getErrorHandler;\n/**\n * @export\n */\nfunction resetErrorHandler() {\n globalErrorHandler = new NoopErrorHandler();\n}\nexports.resetErrorHandler = resetErrorHandler;\n","\"use strict\";\nfunction __export(m) {\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n}\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n__export(require(\"./errorHandler\"));\n__export(require(\"./models\"));\n__export(require(\"./logger\"));\n","\"use strict\";\nvar __spreadArrays = (this && this.__spreadArrays) || function () {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar errorHandler_1 = require(\"./errorHandler\");\nvar js_sdk_utils_1 = require(\"@optimizely/js-sdk-utils\");\nvar models_1 = require(\"./models\");\nvar stringToLogLevel = {\n NOTSET: 0,\n DEBUG: 1,\n INFO: 2,\n WARNING: 3,\n ERROR: 4,\n};\nfunction coerceLogLevel(level) {\n if (typeof level !== 'string') {\n return level;\n }\n level = level.toUpperCase();\n if (level === 'WARN') {\n level = 'WARNING';\n }\n if (!stringToLogLevel[level]) {\n return level;\n }\n return stringToLogLevel[level];\n}\nvar DefaultLogManager = /** @class */ (function () {\n function DefaultLogManager() {\n this.defaultLoggerFacade = new OptimizelyLogger();\n this.loggers = {};\n }\n DefaultLogManager.prototype.getLogger = function (name) {\n if (!name) {\n return this.defaultLoggerFacade;\n }\n if (!this.loggers[name]) {\n this.loggers[name] = new OptimizelyLogger({ messagePrefix: name });\n }\n return this.loggers[name];\n };\n return DefaultLogManager;\n}());\nvar ConsoleLogHandler = /** @class */ (function () {\n /**\n * Creates an instance of ConsoleLogger.\n * @param {ConsoleLogHandlerConfig} config\n * @memberof ConsoleLogger\n */\n function ConsoleLogHandler(config) {\n if (config === void 0) { config = {}; }\n this.logLevel = models_1.LogLevel.NOTSET;\n if (config.logLevel !== undefined && js_sdk_utils_1.isValidEnum(models_1.LogLevel, config.logLevel)) {\n this.setLogLevel(config.logLevel);\n }\n this.logToConsole = config.logToConsole !== undefined ? !!config.logToConsole : true;\n this.prefix = config.prefix !== undefined ? config.prefix : '[OPTIMIZELY]';\n }\n /**\n * @param {LogLevel} level\n * @param {string} message\n * @memberof ConsoleLogger\n */\n ConsoleLogHandler.prototype.log = function (level, message) {\n if (!this.shouldLog(level) || !this.logToConsole) {\n return;\n }\n var logMessage = this.prefix + \" - \" + this.getLogLevelName(level) + \" \" + this.getTime() + \" \" + message;\n this.consoleLog(level, [logMessage]);\n };\n /**\n * @param {LogLevel} level\n * @memberof ConsoleLogger\n */\n ConsoleLogHandler.prototype.setLogLevel = function (level) {\n level = coerceLogLevel(level);\n if (!js_sdk_utils_1.isValidEnum(models_1.LogLevel, level) || level === undefined) {\n this.logLevel = models_1.LogLevel.ERROR;\n }\n else {\n this.logLevel = level;\n }\n };\n /**\n * @returns {string}\n * @memberof ConsoleLogger\n */\n ConsoleLogHandler.prototype.getTime = function () {\n return new Date().toISOString();\n };\n /**\n * @private\n * @param {LogLevel} targetLogLevel\n * @returns {boolean}\n * @memberof ConsoleLogger\n */\n ConsoleLogHandler.prototype.shouldLog = function (targetLogLevel) {\n return targetLogLevel >= this.logLevel;\n };\n /**\n * @private\n * @param {LogLevel} logLevel\n * @returns {string}\n * @memberof ConsoleLogger\n */\n ConsoleLogHandler.prototype.getLogLevelName = function (logLevel) {\n switch (logLevel) {\n case models_1.LogLevel.DEBUG:\n return 'DEBUG';\n case models_1.LogLevel.INFO:\n return 'INFO ';\n case models_1.LogLevel.WARNING:\n return 'WARN ';\n case models_1.LogLevel.ERROR:\n return 'ERROR';\n default:\n return 'NOTSET';\n }\n };\n /**\n * @private\n * @param {LogLevel} logLevel\n * @param {string[]} logArguments\n * @memberof ConsoleLogger\n */\n ConsoleLogHandler.prototype.consoleLog = function (logLevel, logArguments) {\n switch (logLevel) {\n case models_1.LogLevel.DEBUG:\n console.log.apply(console, logArguments);\n break;\n case models_1.LogLevel.INFO:\n console.info.apply(console, logArguments);\n break;\n case models_1.LogLevel.WARNING:\n console.warn.apply(console, logArguments);\n break;\n case models_1.LogLevel.ERROR:\n console.error.apply(console, logArguments);\n break;\n default:\n console.log.apply(console, logArguments);\n }\n };\n return ConsoleLogHandler;\n}());\nexports.ConsoleLogHandler = ConsoleLogHandler;\nvar globalLogLevel = models_1.LogLevel.NOTSET;\nvar globalLogHandler = null;\nvar OptimizelyLogger = /** @class */ (function () {\n function OptimizelyLogger(opts) {\n if (opts === void 0) { opts = {}; }\n this.messagePrefix = '';\n if (opts.messagePrefix) {\n this.messagePrefix = opts.messagePrefix;\n }\n }\n /**\n * @param {(LogLevel | LogInputObject)} levelOrObj\n * @param {string} [message]\n * @memberof OptimizelyLogger\n */\n OptimizelyLogger.prototype.log = function (level, message) {\n var splat = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n splat[_i - 2] = arguments[_i];\n }\n this.internalLog(coerceLogLevel(level), {\n message: message,\n splat: splat,\n });\n };\n OptimizelyLogger.prototype.info = function (message) {\n var splat = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n splat[_i - 1] = arguments[_i];\n }\n this.namedLog(models_1.LogLevel.INFO, message, splat);\n };\n OptimizelyLogger.prototype.debug = function (message) {\n var splat = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n splat[_i - 1] = arguments[_i];\n }\n this.namedLog(models_1.LogLevel.DEBUG, message, splat);\n };\n OptimizelyLogger.prototype.warn = function (message) {\n var splat = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n splat[_i - 1] = arguments[_i];\n }\n this.namedLog(models_1.LogLevel.WARNING, message, splat);\n };\n OptimizelyLogger.prototype.error = function (message) {\n var splat = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n splat[_i - 1] = arguments[_i];\n }\n this.namedLog(models_1.LogLevel.ERROR, message, splat);\n };\n OptimizelyLogger.prototype.format = function (data) {\n return \"\" + (this.messagePrefix ? this.messagePrefix + ': ' : '') + js_sdk_utils_1.sprintf.apply(void 0, __spreadArrays([data.message], data.splat));\n };\n OptimizelyLogger.prototype.internalLog = function (level, data) {\n if (!globalLogHandler) {\n return;\n }\n if (level < globalLogLevel) {\n return;\n }\n globalLogHandler.log(level, this.format(data));\n if (data.error && data.error instanceof Error) {\n errorHandler_1.getErrorHandler().handleError(data.error);\n }\n };\n OptimizelyLogger.prototype.namedLog = function (level, message, splat) {\n var error;\n if (message instanceof Error) {\n error = message;\n message = error.message;\n this.internalLog(level, {\n error: error,\n message: message,\n splat: splat,\n });\n return;\n }\n if (splat.length === 0) {\n this.internalLog(level, {\n message: message,\n splat: splat,\n });\n return;\n }\n var last = splat[splat.length - 1];\n if (last instanceof Error) {\n error = last;\n splat.splice(-1);\n }\n this.internalLog(level, { message: message, error: error, splat: splat });\n };\n return OptimizelyLogger;\n}());\nvar globalLogManager = new DefaultLogManager();\nfunction getLogger(name) {\n return globalLogManager.getLogger(name);\n}\nexports.getLogger = getLogger;\nfunction setLogHandler(logger) {\n globalLogHandler = logger;\n}\nexports.setLogHandler = setLogHandler;\nfunction setLogLevel(level) {\n level = coerceLogLevel(level);\n if (!js_sdk_utils_1.isValidEnum(models_1.LogLevel, level) || level === undefined) {\n globalLogLevel = models_1.LogLevel.ERROR;\n }\n else {\n globalLogLevel = level;\n }\n}\nexports.setLogLevel = setLogLevel;\nfunction getLogLevel() {\n return globalLogLevel;\n}\nexports.getLogLevel = getLogLevel;\n/**\n * Resets all global logger state to it's original\n */\nfunction resetLogger() {\n globalLogManager = new DefaultLogManager();\n globalLogLevel = models_1.LogLevel.NOTSET;\n}\nexports.resetLogger = resetLogger;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar LogLevel;\n(function (LogLevel) {\n LogLevel[LogLevel[\"NOTSET\"] = 0] = \"NOTSET\";\n LogLevel[LogLevel[\"DEBUG\"] = 1] = \"DEBUG\";\n LogLevel[LogLevel[\"INFO\"] = 2] = \"INFO\";\n LogLevel[LogLevel[\"WARNING\"] = 3] = \"WARNING\";\n LogLevel[LogLevel[\"ERROR\"] = 4] = \"ERROR\";\n})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Copyright 2019, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar uuid_1 = require(\"uuid\");\nfunction generateUUID() {\n return uuid_1.v4();\n}\nexports.generateUUID = generateUUID;\nfunction getTimestamp() {\n return new Date().getTime();\n}\nexports.getTimestamp = getTimestamp;\n/**\n * Validates a value is a valid TypeScript enum\n *\n * @export\n * @param {object} enumToCheck\n * @param {*} value\n * @returns {boolean}\n */\nfunction isValidEnum(enumToCheck, value) {\n var found = false;\n var keys = Object.keys(enumToCheck);\n for (var index = 0; index < keys.length; index++) {\n if (value === enumToCheck[keys[index]]) {\n found = true;\n break;\n }\n }\n return found;\n}\nexports.isValidEnum = isValidEnum;\nfunction groupBy(arr, grouperFn) {\n var grouper = {};\n arr.forEach(function (item) {\n var key = grouperFn(item);\n grouper[key] = grouper[key] || [];\n grouper[key].push(item);\n });\n return objectValues(grouper);\n}\nexports.groupBy = groupBy;\nfunction objectValues(obj) {\n return Object.keys(obj).map(function (key) { return obj[key]; });\n}\nexports.objectValues = objectValues;\nfunction objectEntries(obj) {\n return Object.keys(obj).map(function (key) { return [key, obj[key]]; });\n}\nexports.objectEntries = objectEntries;\nfunction find(arr, cond) {\n var found;\n for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {\n var item = arr_1[_i];\n if (cond(item)) {\n found = item;\n break;\n }\n }\n return found;\n}\nexports.find = find;\nfunction keyBy(arr, keyByFn) {\n var map = {};\n arr.forEach(function (item) {\n var key = keyByFn(item);\n map[key] = item;\n });\n return map;\n}\nexports.keyBy = keyBy;\nfunction sprintf(format) {\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n var i = 0;\n return format.replace(/%s/g, function () {\n var arg = args[i++];\n var type = typeof arg;\n if (type === 'function') {\n return arg();\n }\n else if (type === 'string') {\n return arg;\n }\n else {\n return String(arg);\n }\n });\n}\nexports.sprintf = sprintf;\n/*\n * Notification types for use with NotificationCenter\n * Format is EVENT: \n *\n * SDK consumers can use these to register callbacks with the notification center.\n *\n * @deprecated since 3.1.0\n * ACTIVATE: An impression event will be sent to Optimizely\n * Callbacks will receive an object argument with the following properties:\n * - experiment {Object}\n * - userId {string}\n * - attributes {Object|undefined}\n * - variation {Object}\n * - logEvent {Object}\n *\n * DECISION: A decision is made in the system. i.e. user activation,\n * feature access or feature-variable value retrieval\n * Callbacks will receive an object argument with the following properties:\n * - type {string}\n * - userId {string}\n * - attributes {Object|undefined}\n * - decisionInfo {Object|undefined}\n *\n * LOG_EVENT: A batch of events, which could contain impressions and/or conversions,\n * will be sent to Optimizely\n * Callbacks will receive an object argument with the following properties:\n * - url {string}\n * - httpVerb {string}\n * - params {Object}\n *\n * OPTIMIZELY_CONFIG_UPDATE: This Optimizely instance has been updated with a new\n * config\n *\n * TRACK: A conversion event will be sent to Optimizely\n * Callbacks will receive the an object argument with the following properties:\n * - eventKey {string}\n * - userId {string}\n * - attributes {Object|undefined}\n * - eventTags {Object|undefined}\n * - logEvent {Object}\n *\n */\nvar NOTIFICATION_TYPES;\n(function (NOTIFICATION_TYPES) {\n NOTIFICATION_TYPES[\"ACTIVATE\"] = \"ACTIVATE:experiment, user_id,attributes, variation, event\";\n NOTIFICATION_TYPES[\"DECISION\"] = \"DECISION:type, userId, attributes, decisionInfo\";\n NOTIFICATION_TYPES[\"LOG_EVENT\"] = \"LOG_EVENT:logEvent\";\n NOTIFICATION_TYPES[\"OPTIMIZELY_CONFIG_UPDATE\"] = \"OPTIMIZELY_CONFIG_UPDATE\";\n NOTIFICATION_TYPES[\"TRACK\"] = \"TRACK:event_key, user_id, attributes, event_tags, event\";\n})(NOTIFICATION_TYPES = exports.NOTIFICATION_TYPES || (exports.NOTIFICATION_TYPES = {}));\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","/**\n * Copyright 2017, 2019-2020, 2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport v4 from 'uuid';\n\nconst MAX_SAFE_INTEGER_LIMIT = Math.pow(2, 53);\n\n// eslint-disable-next-line\nexport function assign(target: any, ...sources: any[]): any {\n if (!target) {\n return {};\n }\n if (typeof Object.assign === 'function') {\n return Object.assign(target, ...sources);\n } else {\n const to = Object(target);\n for (let index = 0; index < sources.length; index++) {\n const nextSource = sources[index];\n if (nextSource !== null && nextSource !== undefined) {\n for (const nextKey in nextSource) {\n // Avoid bugs when hasOwnProperty is shadowed\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n }\n}\n\nfunction currentTimestamp(): number {\n return Math.round(new Date().getTime());\n}\n\nfunction isSafeInteger(number: unknown): boolean {\n return typeof number == 'number' && Math.abs(number) <= MAX_SAFE_INTEGER_LIMIT;\n}\n\nexport function keyBy(arr: K[], key: string): { [key: string]: K } {\n if (!arr) return {};\n return keyByUtil(arr, function (item) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (item as any)[key];\n });\n}\n\nfunction isNumber(value: unknown): boolean {\n return typeof value === 'number';\n}\n\nexport function uuid(): string {\n return v4()\n}\n\nexport type Omit = Pick>\n\nexport function getTimestamp(): number {\n return new Date().getTime()\n}\n\n/**\n* Validates a value is a valid TypeScript enum\n*\n* @export\n* @param {object} enumToCheck\n* @param {*} value\n* @returns {boolean}\n*/\n// TODO[OASIS-6649]: Don't use any type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isValidEnum(enumToCheck: { [key: string]: any }, value: number | string): boolean {\n let found = false\n\n const keys = Object.keys(enumToCheck)\n for (let index = 0; index < keys.length; index++) {\n if (value === enumToCheck[keys[index]]) {\n found = true\n break\n }\n }\n return found\n}\n\nexport function groupBy(arr: K[], grouperFn: (item: K) => string): Array {\n const grouper: { [key: string]: K[] } = {}\n\n arr.forEach(item => {\n const key = grouperFn(item)\n grouper[key] = grouper[key] || []\n grouper[key].push(item)\n })\n\n return objectValues(grouper)\n}\n\nexport function objectValues(obj: { [key: string]: K }): K[] {\n return Object.keys(obj).map(key => obj[key])\n}\n\nexport function objectEntries(obj: { [key: string]: K }): [string, K][] {\n return Object.keys(obj).map(key => [key, obj[key]])\n}\n\nexport function find(arr: K[], cond: (arg: K) => boolean): K | undefined {\n let found\n\n for (const item of arr) {\n if (cond(item)) {\n found = item\n break\n }\n }\n\n return found\n}\n\nexport function keyByUtil(arr: K[], keyByFn: (item: K) => string): { [key: string]: K } {\n const map: { [key: string]: K } = {}\n arr.forEach(item => {\n const key = keyByFn(item)\n map[key] = item\n })\n return map\n}\n\n// TODO[OASIS-6649]: Don't use any type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function sprintf(format: string, ...args: any[]): string {\n let i = 0\n return format.replace(/%s/g, function() {\n const arg = args[i++]\n const type = typeof arg\n if (type === 'function') {\n return arg()\n } else if (type === 'string') {\n return arg\n } else {\n return String(arg)\n }\n })\n}\n\nexport default {\n assign,\n currentTimestamp,\n isSafeInteger,\n keyBy,\n uuid,\n isNumber,\n getTimestamp,\n isValidEnum,\n groupBy,\n objectValues,\n objectEntries,\n find,\n keyByUtil,\n sprintf\n}\n","/****************************************************************************\n * Copyright 2016-2022, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\n\n/**\n * Contains global enums used throughout the library\n */\nexport const LOG_LEVEL = {\n NOTSET: 0,\n DEBUG: 1,\n INFO: 2,\n WARNING: 3,\n ERROR: 4,\n};\n\nexport const ERROR_MESSAGES = {\n CONDITION_EVALUATOR_ERROR: '%s: Error evaluating audience condition of type %s: %s',\n DATAFILE_AND_SDK_KEY_MISSING: '%s: You must provide at least one of sdkKey or datafile. Cannot start Optimizely',\n EXPERIMENT_KEY_NOT_IN_DATAFILE: '%s: Experiment key %s is not in datafile.',\n FEATURE_NOT_IN_DATAFILE: '%s: Feature key %s is not in datafile.',\n IMPROPERLY_FORMATTED_EXPERIMENT: '%s: Experiment key %s is improperly formatted.',\n INVALID_ATTRIBUTES: '%s: Provided attributes are in an invalid format.',\n INVALID_BUCKETING_ID: '%s: Unable to generate hash for bucketing ID %s: %s',\n INVALID_DATAFILE: '%s: Datafile is invalid - property %s: %s',\n INVALID_DATAFILE_MALFORMED: '%s: Datafile is invalid because it is malformed.',\n INVALID_CONFIG: '%s: Provided Optimizely config is in an invalid format.',\n INVALID_JSON: '%s: JSON object is not valid.',\n INVALID_ERROR_HANDLER: '%s: Provided \"errorHandler\" is in an invalid format.',\n INVALID_EVENT_DISPATCHER: '%s: Provided \"eventDispatcher\" is in an invalid format.',\n INVALID_EVENT_TAGS: '%s: Provided event tags are in an invalid format.',\n INVALID_EXPERIMENT_KEY: '%s: Experiment key %s is not in datafile. It is either invalid, paused, or archived.',\n INVALID_EXPERIMENT_ID: '%s: Experiment ID %s is not in datafile.',\n INVALID_GROUP_ID: '%s: Group ID %s is not in datafile.',\n INVALID_LOGGER: '%s: Provided \"logger\" is in an invalid format.',\n INVALID_ROLLOUT_ID: '%s: Invalid rollout ID %s attached to feature %s',\n INVALID_USER_ID: '%s: Provided user ID is in an invalid format.',\n INVALID_USER_PROFILE_SERVICE: '%s: Provided user profile service instance is in an invalid format: %s.',\n NO_DATAFILE_SPECIFIED: '%s: No datafile specified. Cannot start optimizely.',\n NO_JSON_PROVIDED: '%s: No JSON object to validate against schema.',\n NO_VARIATION_FOR_EXPERIMENT_KEY: '%s: No variation key %s defined in datafile for experiment %s.',\n UNDEFINED_ATTRIBUTE: '%s: Provided attribute: %s has an undefined value.',\n UNRECOGNIZED_ATTRIBUTE: '%s: Unrecognized attribute %s provided. Pruning before sending event to Optimizely.',\n UNABLE_TO_CAST_VALUE: '%s: Unable to cast value %s to type %s, returning null.',\n USER_NOT_IN_FORCED_VARIATION: '%s: User %s is not in the forced variation map. Cannot remove their forced variation.',\n USER_PROFILE_LOOKUP_ERROR: '%s: Error while looking up user profile for user ID \"%s\": %s.',\n USER_PROFILE_SAVE_ERROR: '%s: Error while saving user profile for user ID \"%s\": %s.',\n VARIABLE_KEY_NOT_IN_DATAFILE: '%s: Variable with key \"%s\" associated with feature with key \"%s\" is not in datafile.',\n VARIATION_ID_NOT_IN_DATAFILE: '%s: No variation ID %s defined in datafile for experiment %s.',\n VARIATION_ID_NOT_IN_DATAFILE_NO_EXPERIMENT: '%s: Variation ID %s is not in the datafile.',\n INVALID_INPUT_FORMAT: '%s: Provided %s is in an invalid format.',\n INVALID_DATAFILE_VERSION: '%s: This version of the JavaScript SDK does not support the given datafile version: %s',\n INVALID_VARIATION_KEY: '%s: Provided variation key is in an invalid format.',\n};\n\nexport const LOG_MESSAGES = {\n ACTIVATE_USER: '%s: Activating user %s in experiment %s.',\n DISPATCH_CONVERSION_EVENT: '%s: Dispatching conversion event to URL %s with params %s.',\n DISPATCH_IMPRESSION_EVENT: '%s: Dispatching impression event to URL %s with params %s.',\n DEPRECATED_EVENT_VALUE: '%s: Event value is deprecated in %s call.',\n EVENT_KEY_NOT_FOUND: '%s: Event key %s is not in datafile.',\n EXPERIMENT_NOT_RUNNING: '%s: Experiment %s is not running.',\n FEATURE_ENABLED_FOR_USER: '%s: Feature %s is enabled for user %s.',\n FEATURE_NOT_ENABLED_FOR_USER: '%s: Feature %s is not enabled for user %s.',\n FEATURE_HAS_NO_EXPERIMENTS: '%s: Feature %s is not attached to any experiments.',\n FAILED_TO_PARSE_VALUE: '%s: Failed to parse event value \"%s\" from event tags.',\n FAILED_TO_PARSE_REVENUE: '%s: Failed to parse revenue value \"%s\" from event tags.',\n FORCED_BUCKETING_FAILED: '%s: Variation key %s is not in datafile. Not activating user %s.',\n INVALID_OBJECT: '%s: Optimizely object is not valid. Failing %s.',\n INVALID_CLIENT_ENGINE: '%s: Invalid client engine passed: %s. Defaulting to node-sdk.',\n INVALID_DEFAULT_DECIDE_OPTIONS: '%s: Provided default decide options is not an array.',\n INVALID_DECIDE_OPTIONS: '%s: Provided decide options is not an array. Using default decide options.',\n INVALID_VARIATION_ID: '%s: Bucketed into an invalid variation ID. Returning null.',\n NOTIFICATION_LISTENER_EXCEPTION: '%s: Notification listener for (%s) threw exception: %s',\n NO_ROLLOUT_EXISTS: '%s: There is no rollout of feature %s.',\n NOT_ACTIVATING_USER: '%s: Not activating user %s for experiment %s.',\n NOT_TRACKING_USER: '%s: Not tracking user %s.',\n PARSED_REVENUE_VALUE: '%s: Parsed revenue value \"%s\" from event tags.',\n PARSED_NUMERIC_VALUE: '%s: Parsed event value \"%s\" from event tags.',\n RETURNING_STORED_VARIATION:\n '%s: Returning previously activated variation \"%s\" of experiment \"%s\" for user \"%s\" from user profile.',\n ROLLOUT_HAS_NO_EXPERIMENTS: '%s: Rollout of feature %s has no experiments',\n SAVED_VARIATION: '%s: Saved variation \"%s\" of experiment \"%s\" for user \"%s\".',\n SAVED_VARIATION_NOT_FOUND:\n '%s: User %s was previously bucketed into variation with ID %s for experiment %s, but no matching variation was found.',\n SHOULD_NOT_DISPATCH_ACTIVATE: '%s: Experiment %s is not in \"Running\" state. Not activating user.',\n SKIPPING_JSON_VALIDATION: '%s: Skipping JSON schema validation.',\n TRACK_EVENT: '%s: Tracking event %s for user %s.',\n UNRECOGNIZED_DECIDE_OPTION: '%s: Unrecognized decide option %s provided.',\n USER_ASSIGNED_TO_EXPERIMENT_BUCKET: '%s: Assigned bucket %s to user with bucketing ID %s.',\n USER_BUCKETED_INTO_EXPERIMENT_IN_GROUP: '%s: User %s is in experiment %s of group %s.',\n USER_BUCKETED_INTO_TARGETING_RULE: '%s: User %s bucketed into targeting rule %s.',\n USER_IN_FEATURE_EXPERIMENT: '%s: User %s is in variation %s of experiment %s on the feature %s.',\n USER_IN_ROLLOUT: '%s: User %s is in rollout of feature %s.',\n USER_NOT_BUCKETED_INTO_EVERYONE_TARGETING_RULE:\n '%s: User %s not bucketed into everyone targeting rule due to traffic allocation.',\n USER_NOT_BUCKETED_INTO_EXPERIMENT_IN_GROUP: '%s: User %s is not in experiment %s of group %s.',\n USER_NOT_BUCKETED_INTO_ANY_EXPERIMENT_IN_GROUP: '%s: User %s is not in any experiment of group %s.',\n USER_NOT_BUCKETED_INTO_TARGETING_RULE:\n '%s User %s not bucketed into targeting rule %s due to traffic allocation. Trying everyone rule.',\n USER_NOT_IN_FEATURE_EXPERIMENT: '%s: User %s is not in any experiment on the feature %s.',\n USER_NOT_IN_ROLLOUT: '%s: User %s is not in rollout of feature %s.',\n USER_FORCED_IN_VARIATION: '%s: User %s is forced in variation %s.',\n USER_MAPPED_TO_FORCED_VARIATION: '%s: Set variation %s for experiment %s and user %s in the forced variation map.',\n USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE: '%s: User %s does not meet conditions for targeting rule %s.',\n USER_MEETS_CONDITIONS_FOR_TARGETING_RULE: '%s: User %s meets conditions for targeting rule %s.',\n USER_HAS_VARIATION: '%s: User %s is in variation %s of experiment %s.',\n USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED: 'Variation (%s) is mapped to flag (%s), rule (%s) and user (%s) in the forced decision map.',\n USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED: 'Variation (%s) is mapped to flag (%s) and user (%s) in the forced decision map.',\n USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID: 'Invalid variation is mapped to flag (%s), rule (%s) and user (%s) in the forced decision map.',\n USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID: 'Invalid variation is mapped to flag (%s) and user (%s) in the forced decision map.',\n USER_HAS_FORCED_VARIATION: '%s: Variation %s is mapped to experiment %s and user %s in the forced variation map.',\n USER_HAS_NO_VARIATION: '%s: User %s is in no variation of experiment %s.',\n USER_HAS_NO_FORCED_VARIATION: '%s: User %s is not in the forced variation map.',\n USER_HAS_NO_FORCED_VARIATION_FOR_EXPERIMENT: '%s: No experiment %s mapped to user %s in the forced variation map.',\n USER_NOT_IN_ANY_EXPERIMENT: '%s: User %s is not in any experiment of group %s.',\n USER_NOT_IN_EXPERIMENT: '%s: User %s does not meet conditions to be in experiment %s.',\n USER_RECEIVED_DEFAULT_VARIABLE_VALUE:\n '%s: User \"%s\" is not in any variation or rollout rule. Returning default value for variable \"%s\" of feature flag \"%s\".',\n FEATURE_NOT_ENABLED_RETURN_DEFAULT_VARIABLE_VALUE:\n '%s: Feature \"%s\" is not enabled for user %s. Returning the default variable value \"%s\".',\n VARIABLE_NOT_USED_RETURN_DEFAULT_VARIABLE_VALUE:\n '%s: Variable \"%s\" is not used in variation \"%s\". Returning default value.',\n USER_RECEIVED_VARIABLE_VALUE: '%s: Got variable value \"%s\" for variable \"%s\" of feature flag \"%s\"',\n VALID_DATAFILE: '%s: Datafile is valid.',\n VALID_USER_PROFILE_SERVICE: '%s: Valid user profile service provided.',\n VARIATION_REMOVED_FOR_USER: '%s: Variation mapped to experiment %s has been removed for user %s.',\n VARIABLE_REQUESTED_WITH_WRONG_TYPE:\n '%s: Requested variable type \"%s\", but variable is of type \"%s\". Use correct API to retrieve value. Returning None.',\n VALID_BUCKETING_ID: '%s: BucketingId is valid: \"%s\"',\n BUCKETING_ID_NOT_STRING: '%s: BucketingID attribute is not a string. Defaulted to userId',\n EVALUATING_AUDIENCE: '%s: Starting to evaluate audience \"%s\" with conditions: %s.',\n EVALUATING_AUDIENCES_COMBINED: '%s: Evaluating audiences for %s \"%s\": %s.',\n AUDIENCE_EVALUATION_RESULT: '%s: Audience \"%s\" evaluated to %s.',\n AUDIENCE_EVALUATION_RESULT_COMBINED: '%s: Audiences for %s %s collectively evaluated to %s.',\n MISSING_ATTRIBUTE_VALUE:\n '%s: Audience condition %s evaluated to UNKNOWN because no value was passed for user attribute \"%s\".',\n UNEXPECTED_CONDITION_VALUE:\n '%s: Audience condition %s evaluated to UNKNOWN because the condition value is not supported.',\n UNEXPECTED_TYPE:\n '%s: Audience condition %s evaluated to UNKNOWN because a value of type \"%s\" was passed for user attribute \"%s\".',\n UNEXPECTED_TYPE_NULL:\n '%s: Audience condition %s evaluated to UNKNOWN because a null value was passed for user attribute \"%s\".',\n UNKNOWN_CONDITION_TYPE:\n '%s: Audience condition %s has an unknown condition type. You may need to upgrade to a newer release of the Optimizely SDK.',\n UNKNOWN_MATCH_TYPE:\n '%s: Audience condition %s uses an unknown match type. You may need to upgrade to a newer release of the Optimizely SDK.',\n UPDATED_OPTIMIZELY_CONFIG: '%s: Updated Optimizely config to revision %s (project id %s)',\n OUT_OF_BOUNDS:\n '%s: Audience condition %s evaluated to UNKNOWN because the number value for user attribute \"%s\" is not in the range [-2^53, +2^53].',\n UNABLE_TO_ATTACH_UNLOAD: '%s: unable to bind optimizely.close() to page unload event: \"%s\"',\n};\n\nexport const enum RESERVED_EVENT_KEYWORDS {\n REVENUE = 'revenue',\n VALUE = 'value',\n}\n\nexport const CONTROL_ATTRIBUTES = {\n BOT_FILTERING: '$opt_bot_filtering',\n BUCKETING_ID: '$opt_bucketing_id',\n STICKY_BUCKETING_KEY: '$opt_experiment_bucket_map',\n USER_AGENT: '$opt_user_agent',\n FORCED_DECISION_NULL_RULE_KEY: '$opt_null_rule_key'\n};\n\nexport const JAVASCRIPT_CLIENT_ENGINE = 'javascript-sdk';\nexport const NODE_CLIENT_ENGINE = 'node-sdk';\nexport const REACT_CLIENT_ENGINE = 'react-sdk';\nexport const REACT_NATIVE_CLIENT_ENGINE = 'react-native-sdk';\nexport const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk';\nexport const BROWSER_CLIENT_VERSION = '4.9.4';\nexport const NODE_CLIENT_VERSION = '4.9.4';\n\nexport const DECISION_NOTIFICATION_TYPES = {\n AB_TEST: 'ab-test',\n FEATURE: 'feature',\n FEATURE_TEST: 'feature-test',\n FEATURE_VARIABLE: 'feature-variable',\n ALL_FEATURE_VARIABLES: 'all-feature-variables',\n FLAG: 'flag',\n};\n\n/*\n * Represents the source of a decision for feature management. When a feature\n * is accessed through isFeatureEnabled or getVariableValue APIs, the decision\n * source is used to decide whether to dispatch an impression event to\n * Optimizely.\n */\nexport const DECISION_SOURCES = {\n FEATURE_TEST: 'feature-test',\n ROLLOUT: 'rollout',\n EXPERIMENT: 'experiment',\n};\n\nexport const AUDIENCE_EVALUATION_TYPES = {\n RULE: 'rule',\n EXPERIMENT: 'experiment',\n};\n\n/*\n * Possible types of variables attached to features\n */\nexport const FEATURE_VARIABLE_TYPES = {\n BOOLEAN: 'boolean',\n DOUBLE: 'double',\n INTEGER: 'integer',\n STRING: 'string',\n JSON: 'json',\n};\n\n/*\n * Supported datafile versions\n */\nexport const DATAFILE_VERSIONS = {\n V2: '2',\n V3: '3',\n V4: '4',\n};\n\n/*\n * Pre-Release and Build symbols\n */\nexport const enum VERSION_TYPE {\n PRE_RELEASE_VERSION_DELIMITER = '-',\n BUILD_VERSION_DELIMITER = '+'\n}\n\nexport const DECISION_MESSAGES = {\n SDK_NOT_READY: 'Optimizely SDK not configured properly yet.',\n FLAG_KEY_INVALID: 'No flag was found for key \"%s\".',\n VARIABLE_VALUE_INVALID: 'Variable value for key \"%s\" is invalid or wrong type.',\n}\n\n/*\n* Notification types for use with NotificationCenter\n* Format is EVENT: \n*\n* SDK consumers can use these to register callbacks with the notification center.\n*\n* @deprecated since 3.1.0\n* ACTIVATE: An impression event will be sent to Optimizely\n* Callbacks will receive an object argument with the following properties:\n* - experiment {Object}\n* - userId {string}\n* - attributes {Object|undefined}\n* - variation {Object}\n* - logEvent {Object}\n*\n* DECISION: A decision is made in the system. i.e. user activation,\n* feature access or feature-variable value retrieval\n* Callbacks will receive an object argument with the following properties:\n* - type {string}\n* - userId {string}\n* - attributes {Object|undefined}\n* - decisionInfo {Object|undefined}\n*\n* LOG_EVENT: A batch of events, which could contain impressions and/or conversions,\n* will be sent to Optimizely\n* Callbacks will receive an object argument with the following properties:\n* - url {string}\n* - httpVerb {string}\n* - params {Object}\n*\n* OPTIMIZELY_CONFIG_UPDATE: This Optimizely instance has been updated with a new\n* config\n*\n* TRACK: A conversion event will be sent to Optimizely\n* Callbacks will receive the an object argument with the following properties:\n* - eventKey {string}\n* - userId {string}\n* - attributes {Object|undefined}\n* - eventTags {Object|undefined}\n* - logEvent {Object}\n*\n*/\nexport enum NOTIFICATION_TYPES {\n ACTIVATE = 'ACTIVATE:experiment, user_id,attributes, variation, event',\n DECISION = 'DECISION:type, userId, attributes, decisionInfo',\n LOG_EVENT = 'LOG_EVENT:logEvent',\n OPTIMIZELY_CONFIG_UPDATE = 'OPTIMIZELY_CONFIG_UPDATE',\n TRACK = 'TRACK:event_key, user_id, attributes, event_tags, event',\n}\n","/**\n * Copyright 2016, 2018-2020, 2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { sprintf } from '../../utils/fns';\nimport { ObjectWithUnknownProperties } from '../../shared_types';\n\nimport { \n ERROR_MESSAGES, \n DATAFILE_VERSIONS,\n} from '../enums';\n\nconst MODULE_NAME = 'CONFIG_VALIDATOR';\nconst SUPPORTED_VERSIONS = [DATAFILE_VERSIONS.V2, DATAFILE_VERSIONS.V3, DATAFILE_VERSIONS.V4];\n\n/**\n * Validates the given config options\n * @param {unknown} config\n * @param {object} config.errorHandler\n * @param {object} config.eventDispatcher\n * @param {object} config.logger\n * @return {boolean} true if the config options are valid\n * @throws If any of the config options are not valid\n */\nexport const validate = function(config: unknown): boolean {\n if (typeof config === 'object' && config !== null) {\n const configObj = config as ObjectWithUnknownProperties;\n const errorHandler = configObj['errorHandler'];\n const eventDispatcher = configObj['eventDispatcher'];\n const logger = configObj['logger'];\n if (errorHandler && typeof (errorHandler as ObjectWithUnknownProperties)['handleError'] !== 'function') {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_ERROR_HANDLER, MODULE_NAME));\n }\n if (eventDispatcher && typeof (eventDispatcher as ObjectWithUnknownProperties)['dispatchEvent'] !== 'function') {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EVENT_DISPATCHER, MODULE_NAME));\n }\n if (logger && typeof (logger as ObjectWithUnknownProperties)['log'] !== 'function') {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_LOGGER, MODULE_NAME));\n }\n return true;\n }\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_CONFIG, MODULE_NAME));\n}\n\n/**\n * Validates the datafile\n * @param {Object|string} datafile\n * @return {Object} The datafile object if the datafile is valid\n * @throws If the datafile is not valid for any of the following reasons:\n - The datafile string is undefined\n - The datafile string cannot be parsed as a JSON object\n - The datafile version is not supported\n */\n// eslint-disable-next-line\nexport const validateDatafile = function(datafile: unknown): any {\n if (!datafile) {\n throw new Error(sprintf(ERROR_MESSAGES.NO_DATAFILE_SPECIFIED, MODULE_NAME));\n }\n if (typeof datafile === 'string') {\n // Attempt to parse the datafile string\n try {\n datafile = JSON.parse(datafile);\n } catch (ex) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_DATAFILE_MALFORMED, MODULE_NAME));\n }\n }\n if (typeof datafile === 'object' && !Array.isArray(datafile) && datafile !== null) {\n if (SUPPORTED_VERSIONS.indexOf(datafile['version' as keyof unknown]) === -1) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_DATAFILE_VERSION, MODULE_NAME, datafile['version' as keyof unknown]));\n }\n }\n\n return datafile;\n};\n\n/**\n * Provides utility methods for validating that the configuration options are valid\n */\nexport default {\n validate: validate,\n validateDatafile: validateDatafile,\n}\n","/**\n * Copyright 2016, 2020-2021, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Default error handler implementation\n */\nexport function handleError(): void {\n // no-op\n}\n\nexport default {\n handleError,\n}\n","/**\n * Copyright 2016-2017, 2020-2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst POST_METHOD = 'POST';\nconst GET_METHOD = 'GET';\nconst READYSTATE_COMPLETE = 4;\n\nexport interface Event {\n url: string;\n httpVerb: 'POST' | 'GET';\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: any;\n}\n\n\n/**\n * Sample event dispatcher implementation for tracking impression and conversions\n * Users of the SDK can provide their own implementation\n * @param {Event} eventObj\n * @param {Function} callback\n */\nexport const dispatchEvent = function(\n eventObj: Event,\n callback: (response: { statusCode: number; }) => void\n): void {\n const params = eventObj.params;\n let url: string = eventObj.url;\n let req: XMLHttpRequest;\n if (eventObj.httpVerb === POST_METHOD) {\n req = new XMLHttpRequest();\n req.open(POST_METHOD, url, true);\n req.setRequestHeader('Content-Type', 'application/json');\n req.onreadystatechange = function() {\n if (req.readyState === READYSTATE_COMPLETE && callback && typeof callback === 'function') {\n try {\n callback({ statusCode: req.status });\n } catch (e) {\n // TODO: Log this somehow (consider adding a logger to the EventDispatcher interface)\n }\n }\n };\n req.send(JSON.stringify(params));\n } else {\n // add param for cors headers to be sent by the log endpoint\n url += '?wxhr=true';\n if (params) {\n url += '&' + toQueryString(params);\n }\n\n req = new XMLHttpRequest();\n req.open(GET_METHOD, url, true);\n req.onreadystatechange = function() {\n if (req.readyState === READYSTATE_COMPLETE && callback && typeof callback === 'function') {\n try {\n callback({ statusCode: req.status });\n } catch (e) {\n // TODO: Log this somehow (consider adding a logger to the EventDispatcher interface)\n }\n }\n };\n req.send();\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst toQueryString = function(obj: any): string {\n return Object.keys(obj)\n .map(function(k) {\n return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);\n })\n .join('&');\n};\n\nexport default {\n dispatchEvent,\n};\n","/**\n * Copyright 2016-2017, 2020-2021, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ConsoleLogHandler, LogLevel } from '@optimizely/js-sdk-logging';\n\ntype ConsoleLogHandlerConfig = {\n logLevel?: LogLevel | string;\n logToConsole?: boolean;\n prefix?: string;\n}\n\nexport class NoOpLogger {\n log(): void { }\n}\n\nexport function createLogger(opts?: ConsoleLogHandlerConfig): ConsoleLogHandler { \n return new ConsoleLogHandler(opts);\n}\n\nexport function createNoOpLogger(): NoOpLogger {\n return new NoOpLogger();\n}\n","/**\n * Copyright 2020-2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ErrorHandler, LogHandler, LogLevel, LoggerFacade } from '@optimizely/js-sdk-logging';\nimport { EventProcessor } from '@optimizely/js-sdk-event-processor';\n\nimport {NotificationCenter as NotificationCenterImpl} from './core/notification_center'\nimport { NOTIFICATION_TYPES } from './utils/enums';\n\nexport interface BucketerParams {\n experimentId: string;\n experimentKey: string;\n userId: string;\n trafficAllocationConfig: TrafficAllocation[];\n experimentKeyMap: { [key: string]: Experiment };\n experimentIdMap: { [id: string]: Experiment };\n groupIdMap: { [key: string]: Group };\n variationIdMap: { [id: string]: Variation };\n logger: LogHandler;\n bucketingId: string;\n}\n\nexport interface DecisionResponse {\n readonly result: T;\n readonly reasons: (string | number)[][];\n}\n\nexport type UserAttributes = {\n // TODO[OASIS-6649]: Don't use any type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [name: string]: any;\n}\n\nexport interface ExperimentBucketMap {\n [experiment_id: string]:\n { variation_id: string }\n}\n\n// Information about past bucketing decisions for a user.\nexport interface UserProfile {\n user_id: string;\n experiment_bucket_map: ExperimentBucketMap;\n}\n\nexport type EventTags = {\n [key: string]: string | number | null;\n};\n\nexport interface UserProfileService {\n lookup(userId: string): UserProfile;\n save(profile: UserProfile): void;\n}\n\nexport interface DatafileManagerConfig {\n sdkKey: string,\n datafile?: string;\n}\n\nexport interface DatafileOptions {\n autoUpdate?: boolean;\n updateInterval?: number;\n urlTemplate?: string;\n datafileAccessToken?: string;\n}\n\nexport interface ListenerPayload {\n userId: string;\n attributes?: UserAttributes;\n}\n\nexport type NotificationListener = (notificationData: T) => void;\n\n// NotificationCenter-related types\nexport interface NotificationCenter {\n addNotificationListener(\n notificationType: string,\n callback: NotificationListener\n ): number;\n removeNotificationListener(listenerId: number): boolean;\n clearAllNotificationListeners(): void;\n clearNotificationListeners(notificationType: NOTIFICATION_TYPES): void;\n}\n\n// An event to be submitted to Optimizely, enabling tracking the reach and impact of\n// tests and feature rollouts.\nexport interface Event {\n // URL to which to send the HTTP request.\n url: string;\n // HTTP method with which to send the event.\n httpVerb: 'POST';\n // Value to send in the request body, JSON-serialized.\n // TODO[OASIS-6649]: Don't use any type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: any;\n}\n\nexport interface EventDispatcher {\n /**\n * @param event\n * Event being submitted for eventual dispatch.\n * @param callback\n * After the event has at least been queued for dispatch, call this function to return\n * control back to the Client.\n */\n dispatchEvent: (event: Event, callback: (response: { statusCode: number; }) => void) => void;\n}\n\nexport interface VariationVariable {\n id: string;\n value: string;\n}\n\nexport interface Variation {\n id: string;\n key: string;\n featureEnabled?: boolean;\n variablesMap: OptimizelyVariablesMap;\n variables?: VariationVariable[];\n}\n\nexport interface Experiment {\n id: string;\n key: string;\n variations: Variation[];\n variationKeyMap: { [key: string]: Variation };\n groupId?: string;\n layerId: string;\n status: string;\n audienceConditions: Array;\n audienceIds: string[];\n trafficAllocation: TrafficAllocation[];\n forcedVariations?: { [key: string]: string };\n}\n\nexport enum VariableType {\n BOOLEAN = 'boolean',\n DOUBLE = 'double',\n INTEGER = 'integer',\n STRING = 'string',\n JSON = 'json',\n}\n\nexport interface FeatureVariable {\n type: VariableType;\n key: string;\n id: string;\n defaultValue: string;\n subType?: string;\n}\n\nexport interface FeatureFlag {\n rolloutId: string;\n key: string;\n id: string;\n experimentIds: string[],\n variables: FeatureVariable[],\n variableKeyMap: { [key: string]: FeatureVariable }\n groupId?: string;\n}\n\nexport type Condition = {\n name: string;\n type: string;\n match?: string;\n value: string | number | boolean | null;\n}\n\nexport interface Audience {\n id: string;\n name: string;\n conditions: unknown[] | string;\n}\n\nexport interface TrafficAllocation {\n entityId: string;\n endOfRange: number;\n}\n\nexport interface Group {\n id: string;\n policy: string;\n trafficAllocation: TrafficAllocation[];\n experiments: Experiment[];\n}\n\nexport interface TrafficAllocation {\n entityId: string;\n endOfRange: number;\n}\n\nexport interface Group {\n id: string;\n policy: string;\n trafficAllocation: TrafficAllocation[];\n experiments: Experiment[];\n}\n\nexport interface FeatureKeyMap {\n [key: string]: FeatureFlag\n}\n\nexport interface OnReadyResult {\n success: boolean;\n reason?: string;\n}\n\nexport type ObjectWithUnknownProperties = {\n [key: string]: unknown;\n}\n\nexport interface Rollout {\n id: string;\n experiments: Experiment[];\n}\n\n//TODO: Move OptimizelyDecideOption to @optimizely/optimizely-sdk/lib/utils/enums\nexport enum OptimizelyDecideOption {\n DISABLE_DECISION_EVENT = 'DISABLE_DECISION_EVENT',\n ENABLED_FLAGS_ONLY = 'ENABLED_FLAGS_ONLY',\n IGNORE_USER_PROFILE_SERVICE = 'IGNORE_USER_PROFILE_SERVICE',\n INCLUDE_REASONS = 'INCLUDE_REASONS',\n EXCLUDE_VARIABLES = 'EXCLUDE_VARIABLES'\n}\n\n/**\n * options required to create optimizely object\n */\nexport interface OptimizelyOptions {\n UNSTABLE_conditionEvaluators?: unknown;\n clientEngine: string;\n clientVersion?: string;\n // TODO[OASIS-6649]: Don't use object type\n // eslint-disable-next-line @typescript-eslint/ban-types\n datafile?: string | object;\n datafileManager?: DatafileManager;\n errorHandler: ErrorHandler;\n eventProcessor: EventProcessor;\n isValidInstance: boolean;\n jsonSchemaValidator?: {\n validate(jsonObject: unknown): boolean,\n };\n logger: LoggerFacade;\n sdkKey?: string;\n userProfileService?: UserProfileService | null;\n defaultDecideOptions?: OptimizelyDecideOption[];\n notificationCenter: NotificationCenterImpl;\n}\n\n/**\n * Optimizely Config Entities\n */\nexport interface OptimizelyExperiment {\n id: string;\n key: string;\n audiences: string;\n variationsMap: {\n [variationKey: string]: OptimizelyVariation;\n };\n}\n\nexport interface OptimizelyVariable {\n id: string;\n key: string;\n type: string;\n value: string;\n}\n\nexport interface Client {\n notificationCenter: NotificationCenter;\n createUserContext(\n userId: string,\n attributes?: UserAttributes\n ): OptimizelyUserContext | null;\n activate(\n experimentKey: string,\n userId: string,\n attributes?: UserAttributes\n ): string | null;\n track(\n eventKey: string,\n userId: string,\n attributes?: UserAttributes,\n eventTags?: EventTags\n ): void;\n getVariation(\n experimentKey: string,\n userId: string,\n attributes?: UserAttributes\n ): string | null;\n setForcedVariation(experimentKey: string, userId: string, variationKey: string | null): boolean;\n getForcedVariation(experimentKey: string, userId: string): string | null;\n isFeatureEnabled(\n featureKey: string,\n userId: string,\n attributes?: UserAttributes\n ): boolean;\n getEnabledFeatures(\n userId: string,\n attributes?: UserAttributes\n ): string[];\n getFeatureVariable(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): unknown;\n getFeatureVariableBoolean(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): boolean | null;\n getFeatureVariableDouble(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): number | null;\n getFeatureVariableInteger(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): number | null;\n getFeatureVariableString(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): string | null;\n getFeatureVariableJSON(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): unknown;\n getAllFeatureVariables(\n featureKey: string,\n userId: string,\n attributes?: UserAttributes\n ): { [variableKey: string]: unknown } | null;\n getOptimizelyConfig(): OptimizelyConfig | null;\n onReady(options?: { timeout?: number }): Promise<{ success: boolean; reason?: string }>;\n close(): Promise<{ success: boolean; reason?: string }>;\n}\n\nexport interface ActivateListenerPayload extends ListenerPayload {\n experiment: import('./shared_types').Experiment;\n variation: import('./shared_types').Variation;\n logEvent: Event;\n}\n\nexport interface TrackListenerPayload extends ListenerPayload {\n eventKey: string;\n eventTags: EventTags;\n logEvent: Event;\n}\n\n/**\n * Entry level Config Entities\n * For compatibility with the previous declaration file\n */\n export interface Config extends ConfigLite {\n // options for Datafile Manager\n datafileOptions?: DatafileOptions;\n // limit of events to dispatch in a batch\n eventBatchSize?: number;\n // maximum time for an event to stay in the queue\n eventFlushInterval?: number;\n // maximum size for the event queue\n eventMaxQueueSize?: number;\n // sdk key\n sdkKey?: string;\n}\n\n/**\n * Entry level Config Entities for Lite bundle\n * For compatibility with the previous declaration file\n */\n export interface ConfigLite {\n // Datafile string\n // TODO[OASIS-6649]: Don't use object type\n // eslint-disable-next-line @typescript-eslint/ban-types\n datafile?: object | string;\n // errorHandler object for logging error\n errorHandler?: ErrorHandler;\n // event dispatcher function\n eventDispatcher?: EventDispatcher;\n // The object to validate against the schema\n jsonSchemaValidator?: {\n validate(jsonObject: unknown): boolean,\n };\n // level of logging i.e debug, info, error, warning etc\n logLevel?: LogLevel | string;\n // LogHandler object for logging\n logger?: LogHandler;\n // user profile that contains user information\n userProfileService?: UserProfileService;\n // dafault options for decide API\n defaultDecideOptions?: OptimizelyDecideOption[];\n clientEngine?: string;\n clientVersion?: string;\n}\n\nexport type OptimizelyExperimentsMap = {\n [experimentKey: string]: OptimizelyExperiment;\n}\n\nexport type OptimizelyVariablesMap = {\n [variableKey: string]: OptimizelyVariable;\n}\n\nexport type OptimizelyFeaturesMap = {\n [featureKey: string]: OptimizelyFeature;\n}\n\nexport type OptimizelyAttribute = {\n id: string;\n key: string;\n};\n\nexport type OptimizelyAudience = {\n id: string;\n name: string;\n conditions: string;\n};\n\nexport type OptimizelyEvent = {\n id: string;\n key: string;\n experimentsIds: string[];\n};\n\nexport interface OptimizelyFeature {\n id: string;\n key: string;\n experimentRules: OptimizelyExperiment[];\n deliveryRules: OptimizelyExperiment[];\n variablesMap: OptimizelyVariablesMap;\n\n /**\n * @deprecated Use experimentRules and deliveryRules\n */\n experimentsMap: OptimizelyExperimentsMap;\n}\n\nexport interface OptimizelyVariation {\n id: string;\n key: string;\n featureEnabled?: boolean;\n variablesMap: OptimizelyVariablesMap;\n}\n\nexport interface OptimizelyConfig {\n environmentKey: string;\n sdkKey: string;\n revision: string;\n\n /**\n * This experimentsMap is for experiments of legacy projects only.\n * For flag projects, experiment keys are not guaranteed to be unique\n * across multiple flags, so this map may not include all experiments\n * when keys conflict.\n */\n experimentsMap: OptimizelyExperimentsMap;\n\n featuresMap: OptimizelyFeaturesMap;\n attributes: OptimizelyAttribute[];\n audiences: OptimizelyAudience[];\n events: OptimizelyEvent[];\n getDatafile(): string;\n}\n\nexport interface OptimizelyUserContext {\n getUserId(): string;\n getAttributes(): UserAttributes;\n setAttribute(key: string, value: unknown): void;\n decide(\n key: string,\n options?: OptimizelyDecideOption[]\n ): OptimizelyDecision;\n decideForKeys(\n keys: string[],\n options?: OptimizelyDecideOption[],\n ): { [key: string]: OptimizelyDecision };\n decideAll(\n options?: OptimizelyDecideOption[],\n ): { [key: string]: OptimizelyDecision };\n trackEvent(eventName: string, eventTags?: EventTags): void;\n setForcedDecision(context: OptimizelyDecisionContext, decision: OptimizelyForcedDecision): boolean;\n getForcedDecision(context: OptimizelyDecisionContext): OptimizelyForcedDecision | null;\n removeForcedDecision(context: OptimizelyDecisionContext): boolean;\n removeAllForcedDecisions(): boolean;\n}\n\nexport interface OptimizelyDecision {\n variationKey: string | null;\n // The boolean value indicating if the flag is enabled or not\n enabled: boolean;\n // The collection of variables associated with the decision\n variables: { [variableKey: string]: unknown };\n // The rule key of the decision\n ruleKey: string | null;\n // The flag key for which the decision has been made for\n flagKey: string;\n // A copy of the user context for which the decision has been made for\n userContext: OptimizelyUserContext;\n // An array of error/info messages describing why the decision has been made.\n reasons: string[];\n}\n\nexport interface DatafileUpdate {\n datafile: string;\n}\n\nexport interface DatafileUpdateListener {\n (datafileUpdate: DatafileUpdate): void;\n}\n\n// TODO: Replace this with the one from js-sdk-models\ninterface Managed {\n start(): void;\n\n stop(): Promise;\n}\n\nexport interface DatafileManager extends Managed {\n get: () => string;\n on(eventName: string, listener: DatafileUpdateListener): () => void;\n onReady: () => Promise;\n}\n\nexport interface OptimizelyDecisionContext {\n flagKey: string;\n ruleKey?: string;\n}\n\nexport interface OptimizelyForcedDecision {\n variationKey: string;\n}\n","/****************************************************************************\n * Copyright 2020, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\nimport { OptimizelyUserContext, OptimizelyDecision } from '../shared_types';\n\nexport function newErrorDecision(key: string, user: OptimizelyUserContext, reasons: string[]): OptimizelyDecision {\n return {\n variationKey: null,\n enabled: false,\n variables: {},\n ruleKey: null,\n flagKey: key,\n userContext: user,\n reasons: reasons,\n };\n}\n","/****************************************************************************\n * Copyright 2020-2022, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\nimport Optimizely from '../../lib/optimizely';\nimport {\n EventTags,\n OptimizelyDecideOption,\n OptimizelyDecision,\n OptimizelyDecisionContext,\n OptimizelyForcedDecision,\n UserAttributes,\n} from '../../lib/shared_types';\nimport { CONTROL_ATTRIBUTES } from '../utils/enums';\n\nexport default class OptimizelyUserContext {\n private optimizely: Optimizely;\n private userId: string;\n private attributes: UserAttributes;\n private forcedDecisionsMap: { [key: string]: { [key: string]: OptimizelyForcedDecision } };\n\n constructor({\n optimizely,\n userId,\n attributes,\n }: {\n optimizely: Optimizely,\n userId: string,\n attributes?: UserAttributes,\n }) {\n this.optimizely = optimizely;\n this.userId = userId;\n this.attributes = { ...attributes } ?? {};\n this.forcedDecisionsMap = {};\n }\n\n /**\n * Sets an attribute for a given key.\n * @param {string} key An attribute key\n * @param {any} value An attribute value\n */\n setAttribute(key: string, value: unknown): void {\n this.attributes[key] = value;\n }\n\n getUserId(): string {\n return this.userId;\n }\n\n getAttributes(): UserAttributes {\n return { ...this.attributes };\n }\n\n getOptimizely(): Optimizely {\n return this.optimizely;\n }\n\n /**\n * Returns a decision result for a given flag key and a user context, which contains all data required to deliver the flag.\n * If the SDK finds an error, it will return a decision with null for variationKey. The decision will include an error message in reasons.\n * @param {string} key A flag key for which a decision will be made.\n * @param {OptimizelyDecideOption} options An array of options for decision-making.\n * @return {OptimizelyDecision} A decision result.\n */\n decide(\n key: string,\n options: OptimizelyDecideOption[] = []\n ): OptimizelyDecision {\n\n return this.optimizely.decide(this.cloneUserContext(), key, options);\n }\n\n /**\n * Returns an object of decision results for multiple flag keys and a user context.\n * If the SDK finds an error for a key, the response will include a decision for the key showing reasons for the error.\n * The SDK will always return key-mapped decisions. When it cannot process requests, it will return an empty map after logging the errors.\n * @param {string[]} keys An array of flag keys for which decisions will be made.\n * @param {OptimizelyDecideOption[]} options An array of options for decision-making.\n * @return {[key: string]: OptimizelyDecision} An object of decision results mapped by flag keys.\n */\n decideForKeys(\n keys: string[],\n options: OptimizelyDecideOption[] = [],\n ): { [key: string]: OptimizelyDecision } {\n\n return this.optimizely.decideForKeys(this.cloneUserContext(), keys, options);\n }\n\n /**\n * Returns an object of decision results for all active flag keys.\n * @param {OptimizelyDecideOption[]} options An array of options for decision-making.\n * @return {[key: string]: OptimizelyDecision} An object of all decision results mapped by flag keys.\n */\n decideAll(\n options: OptimizelyDecideOption[] = []\n ): { [key: string]: OptimizelyDecision } {\n\n return this.optimizely.decideAll(this.cloneUserContext(), options);\n }\n\n /**\n * Tracks an event.\n * @param {string} eventName The event name.\n * @param {EventTags} eventTags An optional map of event tag names to event tag values.\n */\n trackEvent(eventName: string, eventTags?: EventTags): void {\n this.optimizely.track(eventName, this.userId, this.attributes, eventTags);\n }\n\n /**\n * Sets the forced decision for specified optimizely decision context.\n * @param {OptimizelyDecisionContext} context OptimizelyDecisionContext containing flagKey and optional ruleKey.\n * @param {OptimizelyForcedDecision} decision OptimizelyForcedDecision containing forced variation key.\n * @return {boolean} true if the forced decision has been set successfully.\n */\n setForcedDecision(context: OptimizelyDecisionContext, decision: OptimizelyForcedDecision): boolean {\n const flagKey = context.flagKey;\n\n const ruleKey = context.ruleKey ?? CONTROL_ATTRIBUTES.FORCED_DECISION_NULL_RULE_KEY;\n const variationKey = decision.variationKey;\n const forcedDecision = { variationKey };\n\n if (!this.forcedDecisionsMap[flagKey]) {\n this.forcedDecisionsMap[flagKey] = {};\n }\n this.forcedDecisionsMap[flagKey][ruleKey] = forcedDecision;\n\n return true;\n }\n\n /**\n * Returns the forced decision for specified optimizely decision context.\n * @param {OptimizelyDecisionContext} context OptimizelyDecisionContext containing flagKey and optional ruleKey.\n * @return {OptimizelyForcedDecision|null} OptimizelyForcedDecision for specified context if exists or null.\n */\n getForcedDecision(context: OptimizelyDecisionContext): OptimizelyForcedDecision | null {\n return this.findForcedDecision(context);\n }\n\n /**\n * Removes the forced decision for specified optimizely decision context.\n * @param {OptimizelyDecisionContext} context OptimizelyDecisionContext containing flagKey and optional ruleKey.\n * @return {boolean} true if the forced decision has been removed successfully\n */\n removeForcedDecision(context: OptimizelyDecisionContext): boolean {\n const ruleKey = context.ruleKey ?? CONTROL_ATTRIBUTES.FORCED_DECISION_NULL_RULE_KEY;\n const flagKey = context.flagKey;\n\n let isForcedDecisionRemoved = false;\n\n if (this.forcedDecisionsMap.hasOwnProperty(flagKey)) {\n const forcedDecisionByRuleKey = this.forcedDecisionsMap[flagKey];\n if (forcedDecisionByRuleKey.hasOwnProperty(ruleKey)) {\n delete this.forcedDecisionsMap[flagKey][ruleKey];\n isForcedDecisionRemoved = true;\n }\n if (Object.keys(this.forcedDecisionsMap[flagKey]).length === 0) {\n delete this.forcedDecisionsMap[flagKey];\n }\n }\n\n return isForcedDecisionRemoved;\n }\n\n /**\n * Removes all forced decisions bound to this user context.\n * @return {boolean} true if the forced decision has been removed successfully\n */\n removeAllForcedDecisions(): boolean {\n this.forcedDecisionsMap = {};\n return true;\n }\n\n /**\n * Finds a forced decision in forcedDecisionsMap for provided optimizely decision context.\n * @param {OptimizelyDecisionContext} context OptimizelyDecisionContext containing flagKey and optional ruleKey.\n * @return {OptimizelyForcedDecision|null} OptimizelyForcedDecision for specified context if exists or null.\n */\n private findForcedDecision(context: OptimizelyDecisionContext): OptimizelyForcedDecision | null {\n let variationKey;\n const validRuleKey = context.ruleKey ?? CONTROL_ATTRIBUTES.FORCED_DECISION_NULL_RULE_KEY;\n const flagKey = context.flagKey;\n\n if (this.forcedDecisionsMap.hasOwnProperty(context.flagKey)) {\n const forcedDecisionByRuleKey = this.forcedDecisionsMap[flagKey];\n if (forcedDecisionByRuleKey.hasOwnProperty(validRuleKey)) {\n variationKey = forcedDecisionByRuleKey[validRuleKey].variationKey;\n return { variationKey };\n }\n }\n\n return null;\n }\n\n private cloneUserContext(): OptimizelyUserContext {\n const userContext = new OptimizelyUserContext({\n optimizely: this.getOptimizely(),\n userId: this.getUserId(),\n attributes: this.getAttributes(),\n });\n\n if (Object.keys(this.forcedDecisionsMap).length > 0) {\n userContext.forcedDecisionsMap = { ...this.forcedDecisionsMap };\n }\n\n return userContext;\n }\n}\n","/****************************************************************************\n * Copyright 2018, 2021, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\n\nconst AND_CONDITION = 'and';\nconst OR_CONDITION = 'or';\nconst NOT_CONDITION = 'not';\n\nexport const DEFAULT_OPERATOR_TYPES = [AND_CONDITION, OR_CONDITION, NOT_CONDITION];\nexport type ConditionTree = Leaf | unknown[];\n\ntype LeafEvaluator = (leaf: Leaf) => boolean | null;\n\n/**\n * Top level method to evaluate conditions\n * @param {ConditionTree} conditions Nested array of and/or conditions, or a single leaf\n * condition value of any type\n * Example: ['and', '0', ['or', '1', '2']]\n * @param {LeafEvaluator} leafEvaluator Function which will be called to evaluate leaf condition\n * values\n * @return {?boolean} Result of evaluating the conditions using the operator\n * rules and the leaf evaluator. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nexport function evaluate(conditions: ConditionTree, leafEvaluator: LeafEvaluator): boolean | null {\n if (Array.isArray(conditions)) {\n let firstOperator = conditions[0];\n let restOfConditions = conditions.slice(1);\n\n if (typeof firstOperator === 'string' && DEFAULT_OPERATOR_TYPES.indexOf(firstOperator) === -1) {\n // Operator to apply is not explicit - assume 'or'\n firstOperator = OR_CONDITION;\n restOfConditions = conditions;\n }\n\n switch (firstOperator) {\n case AND_CONDITION:\n return andEvaluator(restOfConditions, leafEvaluator);\n case NOT_CONDITION:\n return notEvaluator(restOfConditions, leafEvaluator);\n default:\n // firstOperator is OR_CONDITION\n return orEvaluator(restOfConditions, leafEvaluator);\n }\n }\n\n const leafCondition = conditions;\n return leafEvaluator(leafCondition);\n}\n\n/**\n * Evaluates an array of conditions as if the evaluator had been applied\n * to each entry and the results AND-ed together.\n * @param {unknown[]} conditions Array of conditions ex: [operand_1, operand_2]\n * @param {LeafEvaluator} leafEvaluator Function which will be called to evaluate leaf condition values\n * @return {?boolean} Result of evaluating the conditions. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nfunction andEvaluator(conditions: ConditionTree, leafEvaluator: LeafEvaluator): boolean | null {\n let sawNullResult = false;\n if (Array.isArray(conditions)) {\n for (let i = 0; i < conditions.length; i++) {\n const conditionResult = evaluate(conditions[i] as ConditionTree, leafEvaluator);\n if (conditionResult === false) {\n return false;\n }\n if (conditionResult === null) {\n sawNullResult = true;\n }\n }\n return sawNullResult ? null : true;\n }\n return null;\n}\n\n/**\n * Evaluates an array of conditions as if the evaluator had been applied\n * to a single entry and NOT was applied to the result.\n * @param {unknown[]} conditions Array of conditions ex: [operand_1]\n * @param {LeafEvaluator} leafEvaluator Function which will be called to evaluate leaf condition values\n * @return {?boolean} Result of evaluating the conditions. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nfunction notEvaluator(conditions: ConditionTree, leafEvaluator: LeafEvaluator): boolean | null {\n if (Array.isArray(conditions) && conditions.length > 0) {\n const result = evaluate(conditions[0] as ConditionTree, leafEvaluator);\n return result === null ? null : !result;\n }\n return null;\n}\n\n/**\n * Evaluates an array of conditions as if the evaluator had been applied\n * to each entry and the results OR-ed together.\n * @param {unknown[]} conditions Array of conditions ex: [operand_1, operand_2]\n * @param {LeafEvaluator} leafEvaluator Function which will be called to evaluate leaf condition values\n * @return {?boolean} Result of evaluating the conditions. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nfunction orEvaluator(conditions: ConditionTree, leafEvaluator: LeafEvaluator): boolean | null {\n let sawNullResult = false;\n if (Array.isArray(conditions)) {\n for (let i = 0; i < conditions.length; i++) {\n const conditionResult = evaluate(conditions[i] as ConditionTree, leafEvaluator);\n if (conditionResult === true) {\n return true;\n }\n if (conditionResult === null) {\n sawNullResult = true;\n }\n }\n return sawNullResult ? null : false;\n }\n return null;\n}\n","/**\n * Copyright 2020-2023, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ProjectConfig } from '../project_config';\nimport { DEFAULT_OPERATOR_TYPES } from '../condition_tree_evaluator';\nimport {\n Audience,\n Experiment,\n FeatureVariable,\n OptimizelyAttribute,\n OptimizelyAudience,\n OptimizelyEvent,\n OptimizelyExperiment,\n OptimizelyExperimentsMap,\n OptimizelyFeaturesMap,\n OptimizelyVariable,\n OptimizelyVariablesMap,\n OptimizelyVariation,\n Rollout,\n Variation,\n VariationVariable,\n} from '../../shared_types';\n\ninterface FeatureVariablesMap {\n [key: string]: FeatureVariable[];\n}\n\n/**\n * The OptimizelyConfig class\n * @param {ProjectConfig} configObj\n * @param {string} datafile\n */\nexport class OptimizelyConfig {\n public environmentKey: string;\n public sdkKey: string;\n public revision: string;\n\n /**\n * This experimentsMap is for experiments of legacy projects only.\n * For flag projects, experiment keys are not guaranteed to be unique\n * across multiple flags, so this map may not include all experiments\n * when keys conflict.\n */\n public experimentsMap: OptimizelyExperimentsMap;\n\n public featuresMap: OptimizelyFeaturesMap;\n public attributes: OptimizelyAttribute[];\n public audiences: OptimizelyAudience[];\n public events: OptimizelyEvent[];\n private datafile: string;\n\n constructor(configObj: ProjectConfig, datafile: string) {\n this.sdkKey = configObj.sdkKey ?? '';\n this.environmentKey = configObj.environmentKey ?? '';\n this.attributes = configObj.attributes;\n this.audiences = OptimizelyConfig.getAudiences(configObj);\n this.events = configObj.events;\n this.revision = configObj.revision;\n\n const featureIdVariablesMap = (configObj.featureFlags || []).reduce((resultMap: FeatureVariablesMap, feature) => {\n resultMap[feature.id] = feature.variables;\n return resultMap;\n }, {});\n\n const variableIdMap = OptimizelyConfig.getVariableIdMap(configObj);\n\n const experimentsMapById = OptimizelyConfig.getExperimentsMapById(\n configObj, featureIdVariablesMap, variableIdMap\n );\n this.experimentsMap = OptimizelyConfig.getExperimentsKeyMap(experimentsMapById);\n this.featuresMap = OptimizelyConfig.getFeaturesMap(\n configObj, featureIdVariablesMap, experimentsMapById, variableIdMap\n );\n this.datafile = datafile;\n }\n\n /**\n * Get the datafile\n * @returns {string} JSON string representation of the datafile that was used to create the current config object\n */\n getDatafile(): string {\n return this.datafile;\n }\n\n /**\n * Get Unique audiences list with typedAudiences as priority\n * @param {ProjectConfig} configObj\n * @returns {OptimizelyAudience[]} Array of unique audiences\n */\n static getAudiences(configObj: ProjectConfig): OptimizelyAudience[] {\n const audiences: OptimizelyAudience[] = [];\n const typedAudienceIds: string[] = [];\n\n (configObj.typedAudiences || []).forEach((typedAudience) => {\n audiences.push({\n id: typedAudience.id,\n conditions: JSON.stringify(typedAudience.conditions),\n name: typedAudience.name,\n });\n typedAudienceIds.push(typedAudience.id);\n });\n\n (configObj.audiences || []).forEach((audience) => {\n if (typedAudienceIds.indexOf(audience.id) === -1 && audience.id != '$opt_dummy_audience') {\n audiences.push({\n id: audience.id,\n conditions: JSON.stringify(audience.conditions),\n name: audience.name,\n });\n }\n });\n\n return audiences;\n }\n\n /**\n * Converts list of audience conditions to serialized audiences used in experiment\n * for examples:\n * 1. Input: [\"or\", \"1\", \"2\"]\n * Output: \"\\\"us\\\" OR \\\"female\\\"\"\n * 2. Input: [\"not\", \"1\"]\n * Output: \"NOT \\\"us\\\"\"\n * 3. Input: [\"or\", \"1\"]\n * Output: \"\\\"us\\\"\"\n * 4. Input: [\"and\", [\"or\", \"1\", [\"and\", \"2\", \"3\"]], [\"and\", \"11\", [\"or\", \"12\", \"13\"]]]\n * Output: \"(\\\"us\\\" OR (\\\"female\\\" AND \\\"adult\\\")) AND (\\\"fr\\\" AND (\\\"male\\\" OR \\\"kid\\\"))\"\n * @param {Array} conditions\n * @param {[id: string]: Audience} audiencesById\n * @returns {string} Serialized audiences condition string\n */\n static getSerializedAudiences(\n conditions: Array,\n audiencesById: { [id: string]: Audience }\n ): string {\n let serializedAudience = '';\n\n if (conditions) {\n let cond = '';\n conditions.forEach((item) => {\n let subAudience = '';\n // Checks if item is list of conditions means it is sub audience\n if (item instanceof Array) {\n subAudience = OptimizelyConfig.getSerializedAudiences(item, audiencesById);\n subAudience = `(${subAudience})`;\n } else if (DEFAULT_OPERATOR_TYPES.indexOf(item) > -1) {\n cond = item.toUpperCase();\n } else {\n // Checks if item is audience id\n const audienceName = audiencesById[item] ? audiencesById[item].name : item;\n // if audience condition is \"NOT\" then add \"NOT\" at start. Otherwise check if there is already audience id in serializedAudience then append condition between serializedAudience and item\n if (serializedAudience || cond === 'NOT') {\n cond = cond === '' ? 'OR' : cond;\n if (serializedAudience === '') {\n serializedAudience = `${cond} \"${audiencesById[item].name}\"`;\n } else {\n serializedAudience = serializedAudience.concat(` ${cond} \"${audienceName}\"`);\n }\n } else {\n serializedAudience = `\"${audienceName}\"`;\n }\n }\n // Checks if sub audience is empty or not\n if (subAudience !== '') {\n if (serializedAudience !== '' || cond === 'NOT') {\n cond = cond === '' ? 'OR' : cond;\n if (serializedAudience === '') {\n serializedAudience = `${cond} ${subAudience}`;\n } else {\n serializedAudience = serializedAudience.concat(` ${cond} ${subAudience}`);\n }\n } else {\n serializedAudience = serializedAudience.concat(subAudience);\n }\n }\n });\n }\n return serializedAudience;\n }\n\n /**\n * Get serialized audience condition string for experiment\n * @param {Experiment} experiment\n * @param {ProjectConfig} configObj\n * @returns {string} Serialized audiences condition string\n */\n static getExperimentAudiences(experiment: Experiment, configObj: ProjectConfig): string {\n if (!experiment.audienceConditions) {\n return '';\n }\n return OptimizelyConfig.getSerializedAudiences(experiment.audienceConditions, configObj.audiencesById);\n }\n\n /**\n * Make map of featureVariable which are associated with given feature experiment\n * @param {FeatureVariablesMap} featureIdVariableMap\n * @param {[id: string]: FeatureVariable} variableIdMap\n * @param {string} featureId\n * @param {VariationVariable[] | undefined} featureVariableUsages\n * @param {boolean | undefined} isFeatureEnabled\n * @returns {OptimizelyVariablesMap} FeatureVariables mapped by key\n */\n static mergeFeatureVariables(\n featureIdVariableMap: FeatureVariablesMap,\n variableIdMap: { [id: string]: FeatureVariable },\n featureId: string,\n featureVariableUsages: VariationVariable[] | undefined,\n isFeatureEnabled: boolean | undefined\n ): OptimizelyVariablesMap {\n const variablesMap = (featureIdVariableMap[featureId] || []).reduce(\n (optlyVariablesMap: OptimizelyVariablesMap, featureVariable) => {\n optlyVariablesMap[featureVariable.key] = {\n id: featureVariable.id,\n key: featureVariable.key,\n type: featureVariable.type,\n value: featureVariable.defaultValue,\n };\n return optlyVariablesMap;\n },\n {}\n );\n\n (featureVariableUsages || []).forEach((featureVariableUsage) => {\n const defaultVariable = variableIdMap[featureVariableUsage.id];\n const optimizelyVariable: OptimizelyVariable = {\n id: featureVariableUsage.id,\n key: defaultVariable.key,\n type: defaultVariable.type,\n value: isFeatureEnabled ? featureVariableUsage.value : defaultVariable.defaultValue,\n };\n variablesMap[defaultVariable.key] = optimizelyVariable;\n });\n return variablesMap;\n }\n\n /**\n * Gets Map of all experiment variations and variables including rollouts\n * @param {Variation[]} variations\n * @param {FeatureVariablesMap} featureIdVariableMap\n * @param {{[id: string]: FeatureVariable}} variableIdMap\n * @param {string} featureId\n * @returns {[key: string]: Variation} Variations mapped by key\n */\n static getVariationsMap(\n variations: Variation[],\n featureIdVariableMap: FeatureVariablesMap,\n variableIdMap: { [id: string]: FeatureVariable },\n featureId: string\n ): { [key: string]: Variation } {\n let variationsMap: { [key: string]: OptimizelyVariation } = {};\n variationsMap = variations.reduce((optlyVariationsMap: { [key: string]: OptimizelyVariation }, variation) => {\n const variablesMap = OptimizelyConfig.mergeFeatureVariables(\n featureIdVariableMap,\n variableIdMap,\n featureId,\n variation.variables,\n variation.featureEnabled\n );\n optlyVariationsMap[variation.key] = {\n id: variation.id,\n key: variation.key,\n featureEnabled: variation.featureEnabled,\n variablesMap: variablesMap,\n };\n return optlyVariationsMap;\n }, {});\n\n return variationsMap;\n }\n\n /**\n * Gets Map of FeatureVariable with respect to featureVariableId\n * @param {ProjectConfig} configObj\n * @returns {[id: string]: FeatureVariable} FeatureVariables mapped by id\n */\n static getVariableIdMap(configObj: ProjectConfig): { [id: string]: FeatureVariable } {\n let variablesIdMap: { [id: string]: FeatureVariable } = {};\n variablesIdMap = (configObj.featureFlags || []).reduce((resultMap: { [id: string]: FeatureVariable }, feature) => {\n feature.variables.forEach((variable) => {\n resultMap[variable.id] = variable;\n });\n return resultMap;\n }, {});\n\n return variablesIdMap;\n }\n\n /**\n * Gets list of rollout experiments\n * @param {ProjectConfig} configObj\n * @param {FeatureVariablesMap} featureVariableIdMap\n * @param {string} featureId\n * @param {Experiment[]} experiments\n * @param {{[id: string]: FeatureVariable}} variableIdMap\n * @returns {OptimizelyExperiment[]} List of Optimizely rollout experiments\n */\n static getDeliveryRules(\n configObj: ProjectConfig,\n featureVariableIdMap: FeatureVariablesMap,\n featureId: string,\n experiments: Experiment[],\n variableIdMap: {[id: string]: FeatureVariable}\n ): OptimizelyExperiment[] {\n return experiments.map((experiment) => {\n return {\n id: experiment.id,\n key: experiment.key,\n audiences: OptimizelyConfig.getExperimentAudiences(experiment, configObj),\n variationsMap: OptimizelyConfig.getVariationsMap(\n experiment.variations,\n featureVariableIdMap,\n variableIdMap,\n featureId\n ),\n };\n });\n }\n\n /**\n * Get Experiment Ids which are part of rollout\n * @param {Rollout[]} rollouts\n * @returns {string[]} Array of experiment Ids\n */\n static getRolloutExperimentIds(rollouts: Rollout[]): string[] {\n const experimentIds: string[] = [];\n (rollouts || []).forEach((rollout) => {\n rollout.experiments.forEach((e) => {\n experimentIds.push(e.id);\n });\n });\n return experimentIds;\n }\n\n /**\n * Get experiments mapped by their id's which are not part of a rollout\n * @param {ProjectConfig} configObj\n * @param {FeatureVariablesMap} featureIdVariableMap\n * @param {{[id: string]: FeatureVariable}} variableIdMap\n * @returns {[id: string]: OptimizelyExperiment} Experiments mapped by id\n */\n static getExperimentsMapById(\n configObj: ProjectConfig,\n featureIdVariableMap: FeatureVariablesMap,\n variableIdMap: {[id: string]: FeatureVariable}\n ): { [id: string]: OptimizelyExperiment } {\n const rolloutExperimentIds = this.getRolloutExperimentIds(configObj.rollouts);\n\n const experiments = configObj.experiments;\n\n return (experiments || []).reduce((experimentsMap: { [id: string]: OptimizelyExperiment }, experiment) => {\n if (rolloutExperimentIds.indexOf(experiment.id) === -1) {\n const featureIds = configObj.experimentFeatureMap[experiment.id];\n let featureId = '';\n if (featureIds && featureIds.length > 0) {\n featureId = featureIds[0];\n }\n const variationsMap = OptimizelyConfig.getVariationsMap(\n experiment.variations,\n featureIdVariableMap,\n variableIdMap,\n featureId.toString()\n );\n experimentsMap[experiment.id] = {\n id: experiment.id,\n key: experiment.key,\n audiences: OptimizelyConfig.getExperimentAudiences(experiment, configObj),\n variationsMap: variationsMap,\n };\n }\n return experimentsMap;\n }, {});\n }\n\n /**\n * Get experiments mapped by their keys\n * @param {OptimizelyExperimentsMap} experimentsMapById\n * @returns {OptimizelyExperimentsMap} Experiments mapped by key\n */\n static getExperimentsKeyMap(experimentsMapById: OptimizelyExperimentsMap): OptimizelyExperimentsMap {\n const experimentKeysMap: OptimizelyExperimentsMap = {};\n\n for (const id in experimentsMapById) {\n const experiment = experimentsMapById[id];\n experimentKeysMap[experiment.key] = experiment;\n }\n return experimentKeysMap;\n }\n\n /**\n * Gets Map of all FeatureFlags and associated experiment map inside it\n * @param {ProjectConfig} configObj\n * @param {FeatureVariablesMap} featureVariableIdMap\n * @param {OptimizelyExperimentsMap} experimentsMapById\n * @param {{[id: string]: FeatureVariable}} variableIdMap\n * @returns {OptimizelyFeaturesMap} OptimizelyFeature mapped by key\n */\n static getFeaturesMap(\n configObj: ProjectConfig,\n featureVariableIdMap: FeatureVariablesMap,\n experimentsMapById: OptimizelyExperimentsMap,\n variableIdMap: {[id: string]: FeatureVariable}\n ): OptimizelyFeaturesMap {\n const featuresMap: OptimizelyFeaturesMap = {};\n configObj.featureFlags.forEach((featureFlag) => {\n const featureExperimentMap: OptimizelyExperimentsMap = {};\n const experimentRules: OptimizelyExperiment[] = [];\n featureFlag.experimentIds.forEach(experimentId => {\n const experiment = experimentsMapById[experimentId];\n if (experiment) {\n featureExperimentMap[experiment.key] = experiment;\n }\n experimentRules.push(experimentsMapById[experimentId]);\n });\n const featureVariableMap = (featureFlag.variables || []).reduce((variables: OptimizelyVariablesMap, variable) => {\n variables[variable.key] = {\n id: variable.id,\n key: variable.key,\n type: variable.type,\n value: variable.defaultValue,\n };\n return variables;\n }, {});\n let deliveryRules: OptimizelyExperiment[] = [];\n const rollout = configObj.rolloutIdMap[featureFlag.rolloutId];\n if (rollout) {\n deliveryRules = OptimizelyConfig.getDeliveryRules(\n configObj,\n featureVariableIdMap,\n featureFlag.id,\n rollout.experiments,\n variableIdMap,\n );\n }\n featuresMap[featureFlag.key] = {\n id: featureFlag.id,\n key: featureFlag.key,\n experimentRules: experimentRules,\n deliveryRules: deliveryRules,\n experimentsMap: featureExperimentMap,\n variablesMap: featureVariableMap,\n };\n });\n return featuresMap;\n }\n}\n\n/**\n * Create an instance of OptimizelyConfig\n * @param {ProjectConfig} configObj\n * @param {string} datafile\n * @returns {OptimizelyConfig} An instance of OptimizelyConfig\n */\nexport function createOptimizelyConfig(configObj: ProjectConfig, datafile: string): OptimizelyConfig {\n return new OptimizelyConfig(configObj, datafile);\n}\n","/**\n * Copyright 2016-2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n find,\n objectEntries,\n objectValues,\n sprintf,\n assign,\n keyBy\n} from '../../utils/fns';\n\nimport {\n ERROR_MESSAGES,\n LOG_LEVEL,\n LOG_MESSAGES,\n FEATURE_VARIABLE_TYPES,\n} from '../../utils/enums';\nimport configValidator from '../../utils/config_validator';\n\nimport { LogHandler } from '@optimizely/js-sdk-logging';\nimport {\n Audience,\n Experiment,\n FeatureFlag,\n FeatureVariable,\n Group,\n OptimizelyVariation,\n Rollout,\n TrafficAllocation,\n Variation,\n VariableType,\n VariationVariable,\n} from '../../shared_types';\n\ninterface TryCreatingProjectConfigConfig {\n // TODO[OASIS-6649]: Don't use object type\n // eslint-disable-next-line @typescript-eslint/ban-types\n datafile: string | object;\n jsonSchemaValidator?: {\n validate(jsonObject: unknown): boolean,\n };\n logger: LogHandler;\n}\n\ninterface Event {\n key: string;\n id: string;\n experimentsIds: string[];\n}\n\ninterface VariableUsageMap {\n [id: string]: VariationVariable;\n}\n\nexport interface ProjectConfig {\n revision: string;\n projectId: string;\n sdkKey: string;\n environmentKey: string;\n sendFlagDecisions?: boolean;\n experimentKeyMap: { [key: string]: Experiment };\n featureKeyMap: {\n [key: string]: FeatureFlag;\n };\n rollouts: Rollout[];\n featureFlags: FeatureFlag[];\n experimentIdMap: { [id: string]: Experiment };\n experimentFeatureMap: { [key: string]: string[] };\n experiments: Experiment[];\n eventKeyMap: { [key: string]: Event };\n audiences: Audience[];\n attributeKeyMap: { [key: string]: { id: string } };\n variationIdMap: { [id: string]: OptimizelyVariation };\n variationVariableUsageMap: { [id: string]: VariableUsageMap };\n audiencesById: { [id: string]: Audience };\n __datafileStr: string;\n groupIdMap: { [id: string]: Group };\n groups: Group[];\n events: Event[];\n attributes: Array<{ id: string; key: string }>;\n typedAudiences: Audience[];\n rolloutIdMap: { [id: string]: Rollout };\n anonymizeIP?: boolean | null;\n botFiltering?: boolean;\n accountId: string;\n flagRulesMap: { [key: string]: Experiment[] };\n flagVariationsMap: { [key: string]: Variation[] };\n}\n\nconst EXPERIMENT_RUNNING_STATUS = 'Running';\nconst RESERVED_ATTRIBUTE_PREFIX = '$opt_';\nconst MODULE_NAME = 'PROJECT_CONFIG';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createMutationSafeDatafileCopy(datafile: any): ProjectConfig {\n const datafileCopy = assign({}, datafile);\n datafileCopy.audiences = (datafile.audiences || []).map((audience: Audience) => {\n return assign({}, audience);\n });\n datafileCopy.experiments = (datafile.experiments || []).map((experiment: Experiment) => {\n return assign({}, experiment);\n });\n datafileCopy.featureFlags = (datafile.featureFlags || []).map((featureFlag: FeatureFlag) => {\n return assign({}, featureFlag);\n });\n datafileCopy.groups = (datafile.groups || []).map((group: Group) => {\n const groupCopy = assign({}, group);\n groupCopy.experiments = (group.experiments || []).map((experiment) => {\n return assign({}, experiment);\n });\n return groupCopy;\n });\n datafileCopy.rollouts = (datafile.rollouts || []).map((rollout: Rollout) => {\n const rolloutCopy = assign({}, rollout);\n rolloutCopy.experiments = (rollout.experiments || []).map((experiment) => {\n return assign({}, experiment);\n });\n return rolloutCopy;\n });\n\n datafileCopy.environmentKey = datafile.environmentKey ?? '';\n datafileCopy.sdkKey = datafile.sdkKey ?? '';\n\n return datafileCopy;\n}\n\n/**\n * Creates projectConfig object to be used for quick project property lookup\n * @param {Object} datafileObj JSON datafile representing the project\n * @param {string|null} datafileStr JSON string representation of the datafile\n * @return {ProjectConfig} Object representing project configuration\n */\nexport const createProjectConfig = function(\n datafileObj?: JSON,\n datafileStr: string | null = null\n): ProjectConfig {\n const projectConfig = createMutationSafeDatafileCopy(datafileObj);\n\n projectConfig.__datafileStr = datafileStr === null ? JSON.stringify(datafileObj) : datafileStr;\n\n /*\n * Conditions of audiences in projectConfig.typedAudiences are not\n * expected to be string-encoded as they are here in projectConfig.audiences.\n */\n (projectConfig.audiences || []).forEach((audience) => {\n audience.conditions = JSON.parse(audience.conditions as string);\n });\n projectConfig.audiencesById = keyBy(projectConfig.audiences, 'id');\n assign(projectConfig.audiencesById, keyBy(projectConfig.typedAudiences, 'id'));\n\n projectConfig.attributeKeyMap = keyBy(projectConfig.attributes, 'key');\n projectConfig.eventKeyMap = keyBy(projectConfig.events, 'key');\n projectConfig.groupIdMap = keyBy(projectConfig.groups, 'id');\n\n let experiments;\n Object.keys(projectConfig.groupIdMap || {}).forEach((Id) => {\n experiments = projectConfig.groupIdMap[Id].experiments;\n (experiments || []).forEach((experiment) => {\n projectConfig.experiments.push(assign(experiment, { groupId: Id }));\n });\n });\n\n projectConfig.rolloutIdMap = keyBy(projectConfig.rollouts || [], 'id');\n objectValues(projectConfig.rolloutIdMap || {}).forEach(\n (rollout) => {\n (rollout.experiments || []).forEach((experiment) => {\n projectConfig.experiments.push(experiment);\n // Creates { : } map inside of the experiment\n experiment.variationKeyMap = keyBy(experiment.variations, 'key');\n });\n }\n );\n\n projectConfig.experimentKeyMap = keyBy(projectConfig.experiments, 'key');\n projectConfig.experimentIdMap = keyBy(projectConfig.experiments, 'id');\n\n projectConfig.variationIdMap = {};\n projectConfig.variationVariableUsageMap = {};\n (projectConfig.experiments || []).forEach((experiment) => {\n // Creates { : } map inside of the experiment\n experiment.variationKeyMap = keyBy(experiment.variations, 'key');\n\n // Creates { : { key: , id: } } mapping for quick lookup\n assign(projectConfig.variationIdMap, keyBy(experiment.variations, 'id'));\n objectValues(experiment.variationKeyMap || {}).forEach((variation) => {\n if (variation.variables) {\n projectConfig.variationVariableUsageMap[variation.id] = keyBy(variation.variables, 'id');\n }\n });\n });\n\n // Object containing experiment Ids that exist in any feature\n // for checking that experiment is a feature experiment or not.\n projectConfig.experimentFeatureMap = {};\n\n projectConfig.featureKeyMap = keyBy(projectConfig.featureFlags || [], 'key');\n objectValues(projectConfig.featureKeyMap || {}).forEach(\n (feature) => {\n // Json type is represented in datafile as a subtype of string for the sake of backwards compatibility.\n // Converting it to a first-class json type while creating Project Config\n feature.variables.forEach((variable) => {\n if (variable.type === FEATURE_VARIABLE_TYPES.STRING && variable.subType === FEATURE_VARIABLE_TYPES.JSON) {\n variable.type = FEATURE_VARIABLE_TYPES.JSON as VariableType;\n delete variable.subType;\n }\n });\n\n feature.variableKeyMap = keyBy(feature.variables, 'key');\n (feature.experimentIds || []).forEach((experimentId) => {\n // Add this experiment in experiment-feature map.\n if (projectConfig.experimentFeatureMap[experimentId]) {\n projectConfig.experimentFeatureMap[experimentId].push(feature.id);\n } else {\n projectConfig.experimentFeatureMap[experimentId] = [feature.id];\n }\n });\n }\n );\n\n // all rules (experiment rules and delivery rules) for each flag\n projectConfig.flagRulesMap = {};\n\n (projectConfig.featureFlags || []).forEach(featureFlag => {\n const flagRuleExperiments: Experiment[] = [];\n featureFlag.experimentIds.forEach(experimentId => {\n const experiment = projectConfig.experimentIdMap[experimentId];\n if (experiment) {\n flagRuleExperiments.push(experiment);\n }\n });\n\n const rollout = projectConfig.rolloutIdMap[featureFlag.rolloutId];\n if (rollout) {\n flagRuleExperiments.push(...rollout.experiments);\n }\n\n projectConfig.flagRulesMap[featureFlag.key] = flagRuleExperiments;\n });\n\n // all variations for each flag\n // - datafile does not contain a separate entity for this.\n // - we collect variations used in each rule (experiment rules and delivery rules)\n projectConfig.flagVariationsMap = {};\n\n objectEntries(projectConfig.flagRulesMap || {}).forEach(\n ([flagKey, rules]) => {\n const variations: OptimizelyVariation[] = [];\n rules.forEach(rule => {\n rule.variations.forEach(variation => {\n if (!find(variations, item => item.id === variation.id)) {\n variations.push(variation);\n }\n });\n });\n projectConfig.flagVariationsMap[flagKey] = variations;\n }\n );\n\n return projectConfig;\n};\n\n/**\n * Get experiment ID for the provided experiment key\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentKey Experiment key for which ID is to be determined\n * @return {string} Experiment ID corresponding to the provided experiment key\n * @throws If experiment key is not in datafile\n */\nexport const getExperimentId = function(projectConfig: ProjectConfig, experimentKey: string): string {\n const experiment = projectConfig.experimentKeyMap[experimentKey];\n if (!experiment) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));\n }\n return experiment.id;\n};\n\n/**\n * Get layer ID for the provided experiment key\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentId Experiment ID for which layer ID is to be determined\n * @return {string} Layer ID corresponding to the provided experiment key\n * @throws If experiment key is not in datafile\n */\nexport const getLayerId = function(projectConfig: ProjectConfig, experimentId: string): string {\n const experiment = projectConfig.experimentIdMap[experimentId];\n if (!experiment) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));\n }\n return experiment.layerId;\n};\n\n/**\n * Get attribute ID for the provided attribute key\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} attributeKey Attribute key for which ID is to be determined\n * @param {LogHandler} logger\n * @return {string|null} Attribute ID corresponding to the provided attribute key. Attribute key if it is a reserved attribute.\n */\nexport const getAttributeId = function(\n projectConfig: ProjectConfig,\n attributeKey: string,\n logger: LogHandler\n): string | null {\n const attribute = projectConfig.attributeKeyMap[attributeKey];\n const hasReservedPrefix = attributeKey.indexOf(RESERVED_ATTRIBUTE_PREFIX) === 0;\n if (attribute) {\n if (hasReservedPrefix) {\n logger.log(\n LOG_LEVEL.WARNING,\n 'Attribute %s unexpectedly has reserved prefix %s; using attribute ID instead of reserved attribute name.',\n attributeKey,\n RESERVED_ATTRIBUTE_PREFIX,\n );\n }\n return attribute.id;\n } else if (hasReservedPrefix) {\n return attributeKey;\n }\n\n logger.log(LOG_LEVEL.DEBUG, ERROR_MESSAGES.UNRECOGNIZED_ATTRIBUTE, MODULE_NAME, attributeKey);\n return null;\n};\n\n/**\n * Get event ID for the provided\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} eventKey Event key for which ID is to be determined\n * @return {string|null} Event ID corresponding to the provided event key\n */\nexport const getEventId = function(projectConfig: ProjectConfig, eventKey: string): string | null {\n const event = projectConfig.eventKeyMap[eventKey];\n if (event) {\n return event.id;\n }\n return null;\n};\n\n/**\n * Get experiment status for the provided experiment key\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentKey Experiment key for which status is to be determined\n * @return {string} Experiment status corresponding to the provided experiment key\n * @throws If experiment key is not in datafile\n */\nexport const getExperimentStatus = function(projectConfig: ProjectConfig, experimentKey: string): string {\n const experiment = projectConfig.experimentKeyMap[experimentKey];\n if (!experiment) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey));\n }\n return experiment.status;\n};\n\n/**\n * Returns whether experiment has a status of 'Running'\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentKey Experiment key for which status is to be compared with 'Running'\n * @return {boolean} True if experiment status is set to 'Running', false otherwise\n */\nexport const isActive = function(projectConfig: ProjectConfig, experimentKey: string): boolean {\n return getExperimentStatus(projectConfig, experimentKey) === EXPERIMENT_RUNNING_STATUS;\n};\n\n/**\n * Determine for given experiment if event is running, which determines whether should be dispatched or not\n * @param {ProjectConfig} configObj Object representing project configuration\n * @param {string} experimentKey Experiment key for which the status is to be determined\n * @return {boolean} True if the experiment is running\n * False if the experiment is not running\n *\n */\nexport const isRunning = function(projectConfig: ProjectConfig, experimentKey: string): boolean {\n return getExperimentStatus(projectConfig, experimentKey) === EXPERIMENT_RUNNING_STATUS;\n};\n\n/**\n * Get audience conditions for the experiment\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentId Experiment id for which audience conditions are to be determined\n * @return {Array} Audience conditions for the experiment - can be an array of audience IDs, or a\n * nested array of conditions\n * Examples: [\"5\", \"6\"], [\"and\", [\"or\", \"1\", \"2\"], \"3\"]\n * @throws If experiment key is not in datafile\n */\nexport const getExperimentAudienceConditions = function(\n projectConfig: ProjectConfig,\n experimentId: string\n): Array {\n const experiment = projectConfig.experimentIdMap[experimentId];\n if (!experiment) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));\n }\n\n return experiment.audienceConditions || experiment.audienceIds;\n};\n\n/**\n * Get variation key given experiment key and variation ID\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} variationId ID of the variation\n * @return {string|null} Variation key or null if the variation ID is not found\n */\nexport const getVariationKeyFromId = function(projectConfig: ProjectConfig, variationId: string): string | null {\n if (projectConfig.variationIdMap.hasOwnProperty(variationId)) {\n return projectConfig.variationIdMap[variationId].key;\n }\n\n return null;\n};\n\n/**\n * Get variation given variation ID\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} variationId ID of the variation\n * @return {Variation|null} Variation or null if the variation ID is not found\n */\n export const getVariationFromId = function(projectConfig: ProjectConfig, variationId: string): Variation | null {\n if (projectConfig.variationIdMap.hasOwnProperty(variationId)) {\n return projectConfig.variationIdMap[variationId];\n }\n\n return null;\n};\n\n/**\n * Get the variation ID given the experiment key and variation key\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentKey Key of the experiment the variation belongs to\n * @param {string} variationKey The variation key\n * @return {string|null} Variation ID or null\n */\nexport const getVariationIdFromExperimentAndVariationKey = function(\n projectConfig: ProjectConfig,\n experimentKey: string,\n variationKey: string\n): string | null {\n const experiment = projectConfig.experimentKeyMap[experimentKey];\n if (experiment.variationKeyMap.hasOwnProperty(variationKey)) {\n return experiment.variationKeyMap[variationKey].id;\n }\n\n return null;\n};\n\n/**\n * Get experiment from provided experiment key\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentKey Event key for which experiment IDs are to be retrieved\n * @return {Experiment} Experiment\n * @throws If experiment key is not in datafile\n */\nexport const getExperimentFromKey = function(projectConfig: ProjectConfig, experimentKey: string): Experiment {\n if (projectConfig.experimentKeyMap.hasOwnProperty(experimentKey)) {\n const experiment = projectConfig.experimentKeyMap[experimentKey];\n if (experiment) {\n return experiment;\n }\n }\n\n throw new Error(sprintf(ERROR_MESSAGES.EXPERIMENT_KEY_NOT_IN_DATAFILE, MODULE_NAME, experimentKey));\n};\n\n/**\n * Given an experiment id, returns the traffic allocation within that experiment\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentId Id representing the experiment\n * @return {TrafficAllocation[]} Traffic allocation for the experiment\n * @throws If experiment key is not in datafile\n */\nexport const getTrafficAllocation = function(projectConfig: ProjectConfig, experimentId: string): TrafficAllocation[] {\n const experiment = projectConfig.experimentIdMap[experimentId];\n if (!experiment) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId));\n }\n return experiment.trafficAllocation;\n};\n\n/**\n * Get experiment from provided experiment id. Log an error if no experiment\n * exists in the project config with the given ID.\n * @param {ProjectConfig} projectConfig Object representing project configuration\n * @param {string} experimentId ID of desired experiment object\n * @param {LogHandler} logger\n * @return {Experiment|null} Experiment object or null\n */\nexport const getExperimentFromId = function(\n projectConfig: ProjectConfig,\n experimentId: string,\n logger: LogHandler\n): Experiment | null {\n if (projectConfig.experimentIdMap.hasOwnProperty(experimentId)) {\n const experiment = projectConfig.experimentIdMap[experimentId];\n if (experiment) {\n return experiment;\n }\n }\n\n logger.log(LOG_LEVEL.ERROR, ERROR_MESSAGES.INVALID_EXPERIMENT_ID, MODULE_NAME, experimentId);\n return null;\n};\n\n/**\n* Returns flag variation for specified flagKey and variationKey\n* @param {flagKey} string\n* @param {variationKey} string\n* @return {Variation|null}\n*/\nexport const getFlagVariationByKey = function(projectConfig: ProjectConfig, flagKey: string, variationKey: string): Variation | null {\n if (!projectConfig) {\n return null;\n }\n\n const variations = projectConfig.flagVariationsMap[flagKey];\n const result = find(variations, item => item.key === variationKey)\n if (result) {\n return result;\n }\n\n return null;\n};\n\n/**\n * Get feature from provided feature key. Log an error if no feature exists in\n * the project config with the given key.\n * @param {ProjectConfig} projectConfig\n * @param {string} featureKey\n * @param {LogHandler} logger\n * @return {FeatureFlag|null} Feature object, or null if no feature with the given\n * key exists\n */\nexport const getFeatureFromKey = function(\n projectConfig: ProjectConfig,\n featureKey: string,\n logger: LogHandler\n): FeatureFlag | null {\n if (projectConfig.featureKeyMap.hasOwnProperty(featureKey)) {\n const feature = projectConfig.featureKeyMap[featureKey];\n if (feature) {\n return feature;\n }\n }\n\n logger.log(LOG_LEVEL.ERROR, ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, featureKey);\n return null;\n};\n\n/**\n * Get the variable with the given key associated with the feature with the\n * given key. If the feature key or the variable key are invalid, log an error\n * message.\n * @param {ProjectConfig} projectConfig\n * @param {string} featureKey\n * @param {string} variableKey\n * @param {LogHandler} logger\n * @return {FeatureVariable|null} Variable object, or null one or both of the given\n * feature and variable keys are invalid\n */\nexport const getVariableForFeature = function(\n projectConfig: ProjectConfig,\n featureKey: string,\n variableKey: string,\n logger: LogHandler\n): FeatureVariable | null {\n const feature = projectConfig.featureKeyMap[featureKey];\n if (!feature) {\n logger.log(LOG_LEVEL.ERROR, ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, featureKey);\n return null;\n }\n\n const variable = feature.variableKeyMap[variableKey];\n if (!variable) {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.VARIABLE_KEY_NOT_IN_DATAFILE,\n MODULE_NAME,\n variableKey,\n featureKey,\n );\n return null;\n }\n\n return variable;\n};\n\n/**\n * Get the value of the given variable for the given variation. If the given\n * variable has no value for the given variation, return null. Log an error message if the variation is invalid. If the\n * variable or variation are invalid, return null.\n * @param {ProjectConfig} projectConfig\n * @param {FeatureVariable} variable\n * @param {Variation} variation\n * @param {LogHandler} logger\n * @return {string|null} The value of the given variable for the given\n * variation, or null if the given variable has no value\n * for the given variation or if the variation or variable are invalid\n */\nexport const getVariableValueForVariation = function(\n projectConfig: ProjectConfig,\n variable: FeatureVariable,\n variation: Variation,\n logger: LogHandler\n): string | null {\n if (!variable || !variation) {\n return null;\n }\n\n if (!projectConfig.variationVariableUsageMap.hasOwnProperty(variation.id)) {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.VARIATION_ID_NOT_IN_DATAFILE_NO_EXPERIMENT,\n MODULE_NAME,\n variation.id,\n );\n return null;\n }\n\n const variableUsages = projectConfig.variationVariableUsageMap[variation.id];\n const variableUsage = variableUsages[variable.id];\n\n return variableUsage ? variableUsage.value : null;\n};\n\n/**\n * Given a variable value in string form, try to cast it to the argument type.\n * If the type cast succeeds, return the type casted value, otherwise log an\n * error and return null.\n * @param {string} variableValue Variable value in string form\n * @param {string} variableType Type of the variable whose value was passed\n * in the first argument. Must be one of\n * FEATURE_VARIABLE_TYPES in\n * lib/utils/enums/index.js. The return value's\n * type is determined by this argument (boolean\n * for BOOLEAN, number for INTEGER or DOUBLE,\n * and string for STRING).\n * @param {LogHandler} logger Logger instance\n * @returns {*} Variable value of the appropriate type, or\n * null if the type cast failed\n */\nexport const getTypeCastValue = function(\n variableValue: string,\n variableType: VariableType,\n logger: LogHandler\n): unknown {\n let castValue;\n\n switch (variableType) {\n case FEATURE_VARIABLE_TYPES.BOOLEAN:\n if (variableValue !== 'true' && variableValue !== 'false') {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.UNABLE_TO_CAST_VALUE,\n MODULE_NAME,\n variableValue,\n variableType,\n );\n castValue = null;\n } else {\n castValue = variableValue === 'true';\n }\n break;\n\n case FEATURE_VARIABLE_TYPES.INTEGER:\n castValue = parseInt(variableValue, 10);\n if (isNaN(castValue)) {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.UNABLE_TO_CAST_VALUE,\n MODULE_NAME,\n variableValue,\n variableType,\n );\n castValue = null;\n }\n break;\n\n case FEATURE_VARIABLE_TYPES.DOUBLE:\n castValue = parseFloat(variableValue);\n if (isNaN(castValue)) {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.UNABLE_TO_CAST_VALUE,\n MODULE_NAME,\n variableValue,\n variableType,\n );\n castValue = null;\n }\n break;\n\n case FEATURE_VARIABLE_TYPES.JSON:\n try {\n castValue = JSON.parse(variableValue);\n } catch (e) {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.UNABLE_TO_CAST_VALUE,\n MODULE_NAME,\n variableValue,\n variableType,\n );\n castValue = null;\n }\n break;\n\n default:\n // type is STRING\n castValue = variableValue;\n break;\n }\n\n return castValue;\n};\n\n/**\n * Returns an object containing all audiences in the project config. Keys are audience IDs\n * and values are audience objects.\n * @param {ProjectConfig} projectConfig\n * @returns {{ [id: string]: Audience }}\n */\nexport const getAudiencesById = function(projectConfig: ProjectConfig): { [id: string]: Audience } {\n return projectConfig.audiencesById;\n};\n\n/**\n * Returns true if an event with the given key exists in the datafile, and false otherwise\n * @param {ProjectConfig} projectConfig\n * @param {string} eventKey\n * @returns {boolean}\n */\nexport const eventWithKeyExists = function(projectConfig: ProjectConfig, eventKey: string): boolean {\n return projectConfig.eventKeyMap.hasOwnProperty(eventKey);\n};\n\n/**\n * Returns true if experiment belongs to any feature, false otherwise.\n * @param {ProjectConfig} projectConfig\n * @param {string} experimentId\n * @returns {boolean} \n */\nexport const isFeatureExperiment = function(projectConfig: ProjectConfig, experimentId: string): boolean {\n return projectConfig.experimentFeatureMap.hasOwnProperty(experimentId);\n};\n\n/**\n * Returns the JSON string representation of the datafile\n * @param {ProjectConfig} projectConfig\n * @returns {string}\n */\nexport const toDatafile = function(projectConfig: ProjectConfig): string {\n return projectConfig.__datafileStr;\n}\n\n/**\n * @typedef {Object}\n * @property {Object|null} configObj\n * @property {Error|null} error\n */\n\n/**\n * Try to create a project config object from the given datafile and\n * configuration properties.\n * Returns an object with configObj and error properties.\n * If successful, configObj is the project config object, and error is null.\n * Otherwise, configObj is null and error is an error with more information.\n * @param {Object} config\n * @param {Object|string} config.datafile\n * @param {Object} config.jsonSchemaValidator\n * @param {Object} config.logger\n * @returns {Object} Object containing configObj and error properties\n */\nexport const tryCreatingProjectConfig = function(\n config: TryCreatingProjectConfigConfig\n): { configObj: ProjectConfig | null; error: Error | null } {\n let newDatafileObj;\n try {\n newDatafileObj = configValidator.validateDatafile(config.datafile);\n } catch (error) {\n return { configObj: null, error };\n }\n\n if (config.jsonSchemaValidator) {\n try {\n config.jsonSchemaValidator.validate(newDatafileObj);\n config.logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.VALID_DATAFILE, MODULE_NAME);\n } catch (error) {\n return { configObj: null, error };\n }\n } else {\n config.logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.SKIPPING_JSON_VALIDATION, MODULE_NAME);\n }\n\n const createProjectConfigArgs = [newDatafileObj];\n if (typeof config.datafile === 'string') {\n // Since config.datafile was validated above, we know that it is a valid JSON string\n createProjectConfigArgs.push(config.datafile);\n }\n\n const newConfigObj = createProjectConfig(...createProjectConfigArgs);\n\n return {\n configObj: newConfigObj,\n error: null,\n };\n};\n\n/**\n * Get the send flag decisions value\n * @param {ProjectConfig} projectConfig\n * @return {boolean} A boolean value that indicates if we should send flag decisions\n */\nexport const getSendFlagDecisionsValue = function(projectConfig: ProjectConfig): boolean {\n return !!projectConfig.sendFlagDecisions;\n}\n\nexport default {\n createProjectConfig,\n getExperimentId,\n getLayerId,\n getAttributeId,\n getEventId,\n getExperimentStatus,\n isActive,\n isRunning,\n getExperimentAudienceConditions,\n getVariationFromId,\n getVariationKeyFromId,\n getVariationIdFromExperimentAndVariationKey,\n getExperimentFromKey,\n getTrafficAllocation,\n getExperimentFromId,\n getFlagVariationByKey,\n getFeatureFromKey,\n getVariableForFeature,\n getVariableValueForVariation,\n getTypeCastValue,\n getSendFlagDecisionsValue,\n getAudiencesById,\n eventWithKeyExists,\n isFeatureExperiment,\n toDatafile,\n tryCreatingProjectConfig,\n};\n","/**\n * Copyright 2019-2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getLogger } from '@optimizely/js-sdk-logging';\nimport { sprintf } from '../../utils/fns';\n\nimport { ERROR_MESSAGES } from '../../utils/enums';\nimport { createOptimizelyConfig } from '../optimizely_config';\nimport {\n OnReadyResult,\n OptimizelyConfig,\n DatafileManager,\n} from '../../shared_types';\nimport { ProjectConfig, toDatafile, tryCreatingProjectConfig } from '../project_config';\n\nconst logger = getLogger();\nconst MODULE_NAME = 'PROJECT_CONFIG_MANAGER';\n\ninterface ProjectConfigManagerConfig {\n // TODO[OASIS-6649]: Don't use object type\n // eslint-disable-next-line @typescript-eslint/ban-types\n datafile?: string | object,\n jsonSchemaValidator?: {\n validate(jsonObject: unknown): boolean,\n };\n sdkKey?: string,\n datafileManager?: DatafileManager\n}\n\n/**\n * Return an error message derived from a thrown value. If the thrown value is\n * an error, return the error's message property. Otherwise, return a default\n * provided by the second argument.\n * @param {Error|null} maybeError\n * @param {string} defaultMessage\n * @return {string}\n */\nfunction getErrorMessage(maybeError: Error | null, defaultMessage?: string): string {\n if (maybeError instanceof Error) {\n return maybeError.message;\n }\n return defaultMessage || 'Unknown error';\n}\n\n/**\n * ProjectConfigManager provides project config objects via its methods\n * getConfig and onUpdate. It uses a DatafileManager to fetch datafiles. It is\n * responsible for parsing and validating datafiles, and converting datafile\n * string into project config objects.\n * @param {ProjectConfigManagerConfig} config\n */\nexport class ProjectConfigManager {\n private updateListeners: Array<(config: ProjectConfig) => void> = [];\n private configObj: ProjectConfig | null = null;\n private optimizelyConfigObj: OptimizelyConfig | null = null;\n private readyPromise: Promise;\n public jsonSchemaValidator: { validate(jsonObject: unknown): boolean } | undefined;\n public datafileManager: DatafileManager | null = null;\n\n constructor(config: ProjectConfigManagerConfig) {\n try {\n this.jsonSchemaValidator = config.jsonSchemaValidator;\n\n if (!config.datafile && !config.sdkKey) {\n const datafileAndSdkKeyMissingError = new Error(sprintf(ERROR_MESSAGES.DATAFILE_AND_SDK_KEY_MISSING, MODULE_NAME));\n this.readyPromise = Promise.resolve({\n success: false,\n reason: getErrorMessage(datafileAndSdkKeyMissingError),\n });\n logger.error(datafileAndSdkKeyMissingError);\n return;\n }\n\n let handleNewDatafileException = null;\n if (config.datafile) {\n handleNewDatafileException = this.handleNewDatafile(config.datafile);\n }\n\n if (config.sdkKey && config.datafileManager) {\n this.datafileManager = config.datafileManager;\n this.datafileManager.start();\n this.readyPromise = this.datafileManager\n .onReady()\n .then(this.onDatafileManagerReadyFulfill.bind(this), this.onDatafileManagerReadyReject.bind(this));\n this.datafileManager.on('update', this.onDatafileManagerUpdate.bind(this));\n } else if (this.configObj) {\n this.readyPromise = Promise.resolve({\n success: true,\n });\n } else {\n this.readyPromise = Promise.resolve({\n success: false,\n reason: getErrorMessage(handleNewDatafileException, 'Invalid datafile'),\n });\n }\n } catch (ex) {\n logger.error(ex);\n this.readyPromise = Promise.resolve({\n success: false,\n reason: getErrorMessage(ex, 'Error in initialize'),\n });\n }\n }\n\n /**\n * Respond to datafile manager's onReady promise becoming fulfilled.\n * If there are validation or parse failures using the datafile provided by\n * DatafileManager, ProjectConfigManager's ready promise is resolved with an\n * unsuccessful result. Otherwise, ProjectConfigManager updates its own project\n * config object from the new datafile, and its ready promise is resolved with a\n * successful result.\n */\n private onDatafileManagerReadyFulfill(): OnReadyResult {\n if (this.datafileManager) {\n const newDatafileError = this.handleNewDatafile(this.datafileManager.get());\n if (newDatafileError) {\n return {\n success: false,\n reason: getErrorMessage(newDatafileError),\n };\n }\n return { success: true };\n }\n\n return {\n success: false,\n reason: getErrorMessage(null, 'Datafile manager is not provided'),\n }\n }\n\n /**\n * Respond to datafile manager's onReady promise becoming rejected.\n * When DatafileManager's onReady promise is rejected, there is no possibility\n * of obtaining a datafile. In this case, ProjectConfigManager's ready promise\n * is fulfilled with an unsuccessful result.\n * @param {Error} err\n * @returns {Object}\n */\n private onDatafileManagerReadyReject(err: Error): OnReadyResult {\n return {\n success: false,\n reason: getErrorMessage(err, 'Failed to become ready'),\n };\n }\n\n /**\n * Respond to datafile manager's update event. Attempt to update own config\n * object using latest datafile from datafile manager. Call own registered\n * update listeners if successful\n */\n private onDatafileManagerUpdate(): void {\n if (this.datafileManager) {\n this.handleNewDatafile(this.datafileManager.get());\n }\n }\n\n /**\n * Handle new datafile by attemping to create a new Project Config object. If successful and\n * the new config object's revision is newer than the current one, sets/updates the project config\n * and optimizely config object instance variables and returns null for the error. If unsuccessful,\n * the project config and optimizely config objects will not be updated, and the error is returned.\n * @param {string | object} newDatafile\n * @returns {Error|null} error or null\n */\n // TODO[OASIS-6649]: Don't use object type\n // eslint-disable-next-line @typescript-eslint/ban-types\n private handleNewDatafile(newDatafile: string | object): Error | null {\n const { configObj, error } = tryCreatingProjectConfig({\n datafile: newDatafile,\n jsonSchemaValidator: this.jsonSchemaValidator,\n logger: logger\n });\n\n if (error) {\n logger.error(error);\n } else {\n const oldRevision = this.configObj ? this.configObj.revision : 'null';\n if (configObj && oldRevision !== configObj.revision) {\n this.configObj = configObj;\n this.optimizelyConfigObj = null;\n this.updateListeners.forEach((listener) => listener(configObj));\n }\n }\n\n return error;\n }\n\n /**\n * Returns the current project config object, or null if no project config object\n * is available\n * @return {ProjectConfig|null}\n */\n getConfig(): ProjectConfig | null {\n return this.configObj;\n }\n\n /**\n * Returns the optimizely config object or null\n * @return {OptimizelyConfig|null}\n */\n getOptimizelyConfig(): OptimizelyConfig | null {\n if (!this.optimizelyConfigObj && this.configObj) {\n this.optimizelyConfigObj = createOptimizelyConfig(this.configObj, toDatafile(this.configObj));\n }\n return this.optimizelyConfigObj;\n }\n\n /**\n * Returns a Promise that fulfills when this ProjectConfigManager is ready to\n * use (meaning it has a valid project config object), or has failed to become\n * ready.\n *\n * Failure can be caused by the following:\n * - At least one of sdkKey or datafile is not provided in the constructor argument\n * - The provided datafile was invalid\n * - The datafile provided by the datafile manager was invalid\n * - The datafile manager failed to fetch a datafile\n *\n * The returned Promise is fulfilled with a result object containing these\n * properties:\n * - success (boolean): True if this instance is ready to use with a valid\n * project config object, or false if it failed to\n * become ready\n * - reason (string=): If success is false, this is a string property with\n * an explanatory message.\n * @return {Promise}\n */\n onReady(): Promise {\n return this.readyPromise;\n }\n\n /**\n * Add a listener for project config updates. The listener will be called\n * whenever this instance has a new project config object available.\n * Returns a dispose function that removes the subscription\n * @param {Function} listener\n * @return {Function}\n */\n onUpdate(listener: (config: ProjectConfig) => void): (() => void) {\n this.updateListeners.push(listener);\n return () => {\n const index = this.updateListeners.indexOf(listener);\n if (index > -1) {\n this.updateListeners.splice(index, 1);\n }\n };\n }\n\n /**\n * Stop the internal datafile manager and remove all update listeners\n */\n stop(): void {\n if (this.datafileManager) {\n this.datafileManager.stop();\n }\n this.updateListeners = [];\n }\n}\n\nexport function createProjectConfigManager(config: ProjectConfigManagerConfig): ProjectConfigManager {\n return new ProjectConfigManager(config);\n}\n","/**\n * Copyright 2016, 2019-2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Bucketer API for determining the variation id from the specified parameters\n */\nimport { sprintf } from '../../utils/fns';\nimport murmurhash from 'murmurhash';\nimport { LogHandler } from '@optimizely/js-sdk-logging';\nimport {\n DecisionResponse,\n BucketerParams,\n TrafficAllocation,\n Group,\n} from '../../shared_types';\n\nimport {\n ERROR_MESSAGES,\n LOG_LEVEL,\n LOG_MESSAGES,\n} from '../../utils/enums';\n\nconst HASH_SEED = 1;\nconst MAX_HASH_VALUE = Math.pow(2, 32);\nconst MAX_TRAFFIC_VALUE = 10000;\nconst MODULE_NAME = 'BUCKETER';\nconst RANDOM_POLICY = 'random';\n\n/**\n * Determines ID of variation to be shown for the given input params\n * @param {Object} bucketerParams\n * @param {string} bucketerParams.experimentId\n * @param {string} bucketerParams.experimentKey\n * @param {string} bucketerParams.userId\n * @param {Object[]} bucketerParams.trafficAllocationConfig\n * @param {Array} bucketerParams.experimentKeyMap\n * @param {Object} bucketerParams.groupIdMap\n * @param {Object} bucketerParams.variationIdMap\n * @param {string} bucketerParams.varationIdMap[].key\n * @param {Object} bucketerParams.logger\n * @param {string} bucketerParams.bucketingId\n * @return {Object} DecisionResponse DecisionResponse containing variation ID that user has been bucketed into,\n * null if user is not bucketed into any experiment and the decide reasons.\n */\nexport const bucket = function(bucketerParams: BucketerParams): DecisionResponse {\n const decideReasons: (string | number)[][] = [];\n // Check if user is in a random group; if so, check if user is bucketed into a specific experiment\n const experiment = bucketerParams.experimentIdMap[bucketerParams.experimentId];\n const groupId = experiment['groupId'];\n if (groupId) {\n const group = bucketerParams.groupIdMap[groupId];\n if (!group) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_GROUP_ID, MODULE_NAME, groupId));\n }\n if (group.policy === RANDOM_POLICY) {\n const bucketedExperimentId = bucketUserIntoExperiment(\n group,\n bucketerParams.bucketingId,\n bucketerParams.userId,\n bucketerParams.logger\n );\n\n // Return if user is not bucketed into any experiment\n if (bucketedExperimentId === null) {\n bucketerParams.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_NOT_IN_ANY_EXPERIMENT,\n MODULE_NAME,\n bucketerParams.userId,\n groupId,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_NOT_IN_ANY_EXPERIMENT,\n MODULE_NAME,\n bucketerParams.userId,\n groupId,\n ]);\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n // Return if user is bucketed into a different experiment than the one specified\n if (bucketedExperimentId !== bucketerParams.experimentId) { \n bucketerParams.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_NOT_BUCKETED_INTO_EXPERIMENT_IN_GROUP,\n MODULE_NAME,\n bucketerParams.userId,\n bucketerParams.experimentKey,\n groupId,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_NOT_BUCKETED_INTO_EXPERIMENT_IN_GROUP,\n MODULE_NAME,\n bucketerParams.userId,\n bucketerParams.experimentKey,\n groupId,\n ]);\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n // Continue bucketing if user is bucketed into specified experiment \n bucketerParams.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_BUCKETED_INTO_EXPERIMENT_IN_GROUP,\n MODULE_NAME,\n bucketerParams.userId,\n bucketerParams.experimentKey,\n groupId,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_BUCKETED_INTO_EXPERIMENT_IN_GROUP,\n MODULE_NAME,\n bucketerParams.userId,\n bucketerParams.experimentKey,\n groupId,\n ]);\n }\n }\n const bucketingId = `${bucketerParams.bucketingId}${bucketerParams.experimentId}`;\n const bucketValue = _generateBucketValue(bucketingId);\n \n bucketerParams.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_ASSIGNED_TO_EXPERIMENT_BUCKET,\n MODULE_NAME,\n bucketValue,\n bucketerParams.userId,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_ASSIGNED_TO_EXPERIMENT_BUCKET,\n MODULE_NAME,\n bucketValue,\n bucketerParams.userId,\n ]);\n\n const entityId = _findBucket(bucketValue, bucketerParams.trafficAllocationConfig);\n if (entityId !== null) {\n if (!bucketerParams.variationIdMap[entityId]) {\n if (entityId) { \n bucketerParams.logger.log(LOG_LEVEL.WARNING, LOG_MESSAGES.INVALID_VARIATION_ID, MODULE_NAME);\n decideReasons.push([LOG_MESSAGES.INVALID_VARIATION_ID, MODULE_NAME]);\n }\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n }\n\n return {\n result: entityId,\n reasons: decideReasons,\n };\n};\n\n/**\n * Returns bucketed experiment ID to compare against experiment user is being called into\n * @param {Group} group Group that experiment is in\n * @param {string} bucketingId Bucketing ID\n * @param {string} userId ID of user to be bucketed into experiment\n * @param {LogHandler} logger Logger implementation\n * @return {string|null} ID of experiment if user is bucketed into experiment within the group, null otherwise\n */\nexport const bucketUserIntoExperiment = function(\n group: Group,\n bucketingId: string,\n userId: string,\n logger: LogHandler\n): string | null {\n const bucketingKey = `${bucketingId}${group.id}`;\n const bucketValue = _generateBucketValue(bucketingKey);\n logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_ASSIGNED_TO_EXPERIMENT_BUCKET,\n MODULE_NAME,\n bucketValue,\n userId,\n );\n const trafficAllocationConfig = group.trafficAllocation;\n const bucketedExperimentId = _findBucket(bucketValue, trafficAllocationConfig);\n return bucketedExperimentId;\n};\n\n/**\n * Returns entity ID associated with bucket value\n * @param {number} bucketValue\n * @param {TrafficAllocation[]} trafficAllocationConfig\n * @param {number} trafficAllocationConfig[].endOfRange\n * @param {string} trafficAllocationConfig[].entityId\n * @return {string|null} Entity ID for bucketing if bucket value is within traffic allocation boundaries, null otherwise\n */\nexport const _findBucket = function(\n bucketValue: number,\n trafficAllocationConfig: TrafficAllocation[]\n): string | null {\n for (let i = 0; i < trafficAllocationConfig.length; i++) {\n if (bucketValue < trafficAllocationConfig[i].endOfRange) {\n return trafficAllocationConfig[i].entityId;\n }\n }\n\n return null;\n};\n\n/**\n * Helper function to generate bucket value in half-closed interval [0, MAX_TRAFFIC_VALUE)\n * @param {string} bucketingKey String value for bucketing\n * @return {number} The generated bucket value\n * @throws If bucketing value is not a valid string\n */\nexport const _generateBucketValue = function(bucketingKey: string): number {\n try {\n // NOTE: the mmh library already does cast the hash value as an unsigned 32bit int\n // https://github.com/perezd/node-murmurhash/blob/master/murmurhash.js#L115\n const hashValue = murmurhash.v3(bucketingKey, HASH_SEED);\n const ratio = hashValue / MAX_HASH_VALUE;\n return Math.floor(ratio * MAX_TRAFFIC_VALUE);\n } catch (ex) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_BUCKETING_ID, MODULE_NAME, bucketingKey, ex.message));\n }\n};\n\nexport default {\n bucket: bucket,\n bucketUserIntoExperiment: bucketUserIntoExperiment,\n _generateBucketValue: _generateBucketValue,\n};\n","/**\n * Copyright 2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getLogger } from '@optimizely/js-sdk-logging';\nimport { VERSION_TYPE, LOG_MESSAGES } from '../enums';\n\nconst MODULE_NAME = 'SEMANTIC VERSION';\nconst logger = getLogger();\n\n/**\n * Evaluate if provided string is number only\n * @param {unknown} content\n * @return {boolean} true if the string is number only\n *\n */\nfunction isNumber(content: string): boolean {\n return /^\\d+$/.test(content);\n}\n\n/**\n * Evaluate if provided version contains pre-release \"-\"\n * @param {unknown} version\n * @return {boolean} true if the version contains \"-\" and meets condition\n *\n */\nfunction isPreReleaseVersion(version: string): boolean {\n const preReleaseIndex = version.indexOf(VERSION_TYPE.PRE_RELEASE_VERSION_DELIMITER);\n const buildIndex = version.indexOf(VERSION_TYPE.BUILD_VERSION_DELIMITER);\n\n if (preReleaseIndex < 0) {\n return false;\n }\n\n if (buildIndex < 0) {\n return true;\n }\n\n return preReleaseIndex < buildIndex;\n}\n\n/**\n * Evaluate if provided version contains build \"+\"\n * @param {unknown} version\n * @return {boolean} true if the version contains \"+\" and meets condition\n *\n */\nfunction isBuildVersion(version: string): boolean {\n const preReleaseIndex = version.indexOf(VERSION_TYPE.PRE_RELEASE_VERSION_DELIMITER);\n const buildIndex = version.indexOf(VERSION_TYPE.BUILD_VERSION_DELIMITER);\n\n if (buildIndex < 0) {\n return false;\n }\n\n if (preReleaseIndex < 0) {\n return true;\n }\n\n return buildIndex < preReleaseIndex;\n}\n\n/**\n * check if there is any white spaces \" \" in version\n * @param {unknown} version\n * @return {boolean} true if the version contains \" \"\n *\n */\nfunction hasWhiteSpaces(version: string): boolean {\n return /\\s/.test(version);\n}\n\n/**\n * split version in parts\n * @param {unknown} version\n * @return {boolean} The array of version split into smaller parts i.e major, minor, patch etc\n * null if given version is in invalid format\n */\nfunction splitVersion(version: string): string[] | null {\n let targetPrefix = version;\n let targetSuffix = '';\n\n // check that version shouldn't have white space\n if (hasWhiteSpaces(version)) {\n logger.warn(LOG_MESSAGES.UNKNOWN_MATCH_TYPE, MODULE_NAME, version);\n return null;\n }\n //check for pre release e.g. 1.0.0-alpha where 'alpha' is a pre release\n //otherwise check for build e.g. 1.0.0+001 where 001 is a build metadata\n if (isPreReleaseVersion(version)) {\n targetPrefix = version.substring(0, version.indexOf(VERSION_TYPE.PRE_RELEASE_VERSION_DELIMITER));\n targetSuffix = version.substring(version.indexOf(VERSION_TYPE.PRE_RELEASE_VERSION_DELIMITER) + 1);\n } else if (isBuildVersion(version)) {\n targetPrefix = version.substring(0, version.indexOf(VERSION_TYPE.BUILD_VERSION_DELIMITER));\n targetSuffix = version.substring(version.indexOf(VERSION_TYPE.BUILD_VERSION_DELIMITER) + 1);\n }\n\n // check dot counts in target_prefix\n if (typeof targetPrefix !== 'string' || typeof targetSuffix !== 'string') {\n return null;\n }\n\n const dotCount = targetPrefix.split('.').length - 1;\n if (dotCount > 2) {\n logger.warn(LOG_MESSAGES.UNKNOWN_MATCH_TYPE, MODULE_NAME, version);\n return null;\n }\n\n const targetVersionParts = targetPrefix.split('.');\n if (targetVersionParts.length != dotCount + 1) {\n logger.warn(LOG_MESSAGES.UNKNOWN_MATCH_TYPE, MODULE_NAME, version);\n return null;\n }\n for (const part of targetVersionParts) {\n if (!isNumber(part)) {\n logger.warn(LOG_MESSAGES.UNKNOWN_MATCH_TYPE, MODULE_NAME, version);\n return null;\n }\n }\n\n if (targetSuffix) {\n targetVersionParts.push(targetSuffix);\n }\n\n return targetVersionParts;\n}\n\n/**\n * Compare user version with condition version\n * @param {string} conditionsVersion\n * @param {string} userProvidedVersion\n * @return {number | null} 0 if user version is equal to condition version\n * 1 if user version is greater than condition version\n * -1 if user version is less than condition version\n * null if invalid user or condition version is provided\n */\nexport function compareVersion(conditionsVersion: string, userProvidedVersion: string): number | null {\n const userVersionParts = splitVersion(userProvidedVersion);\n const conditionsVersionParts = splitVersion(conditionsVersion);\n\n if (!userVersionParts || !conditionsVersionParts) {\n return null;\n }\n\n const userVersionPartsLen = userVersionParts.length;\n\n for (let idx = 0; idx < conditionsVersionParts.length; idx++) {\n if (userVersionPartsLen <= idx) {\n return isPreReleaseVersion(conditionsVersion) || isBuildVersion(conditionsVersion) ? 1 : -1;\n } else if (!isNumber(userVersionParts[idx])) {\n if (userVersionParts[idx] < conditionsVersionParts[idx]) {\n return isPreReleaseVersion(conditionsVersion) && !isPreReleaseVersion(userProvidedVersion) ? 1 : -1;\n } else if (userVersionParts[idx] > conditionsVersionParts[idx]) {\n return !isPreReleaseVersion(conditionsVersion) && isPreReleaseVersion(userProvidedVersion) ? -1 : 1;\n }\n } else {\n const userVersionPart = parseInt(userVersionParts[idx]);\n const conditionsVersionPart = parseInt(conditionsVersionParts[idx]);\n if (userVersionPart > conditionsVersionPart) {\n return 1;\n } else if (userVersionPart < conditionsVersionPart) {\n return -1;\n }\n }\n }\n\n // check if user version contains release and target version does not\n if (isPreReleaseVersion(userProvidedVersion) && !isPreReleaseVersion(conditionsVersion)) {\n return -1;\n }\n\n return 0;\n}\n","/****************************************************************************\n * Copyright 2018-2019, 2020 Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\nimport { getLogger } from '@optimizely/js-sdk-logging';\nimport { UserAttributes, Condition } from '../../shared_types';\n\nimport fns from '../../utils/fns';\nimport { LOG_MESSAGES } from '../../utils/enums';\nimport { compareVersion } from '../../utils/semantic_version';\n\nconst MODULE_NAME = 'CUSTOM_ATTRIBUTE_CONDITION_EVALUATOR';\n\nconst logger = getLogger();\n\nconst EXACT_MATCH_TYPE = 'exact';\nconst EXISTS_MATCH_TYPE = 'exists';\nconst GREATER_OR_EQUAL_THAN_MATCH_TYPE = 'ge';\nconst GREATER_THAN_MATCH_TYPE = 'gt';\nconst LESS_OR_EQUAL_THAN_MATCH_TYPE = 'le';\nconst LESS_THAN_MATCH_TYPE = 'lt';\nconst SEMVER_EXACT_MATCH_TYPE = 'semver_eq';\nconst SEMVER_GREATER_OR_EQUAL_THAN_MATCH_TYPE = 'semver_ge';\nconst SEMVER_GREATER_THAN_MATCH_TYPE = 'semver_gt';\nconst SEMVER_LESS_OR_EQUAL_THAN_MATCH_TYPE = 'semver_le';\nconst SEMVER_LESS_THAN_MATCH_TYPE = 'semver_lt';\nconst SUBSTRING_MATCH_TYPE = 'substring';\n\nconst MATCH_TYPES = [\n EXACT_MATCH_TYPE,\n EXISTS_MATCH_TYPE,\n GREATER_THAN_MATCH_TYPE,\n GREATER_OR_EQUAL_THAN_MATCH_TYPE,\n LESS_THAN_MATCH_TYPE,\n LESS_OR_EQUAL_THAN_MATCH_TYPE,\n SUBSTRING_MATCH_TYPE,\n SEMVER_EXACT_MATCH_TYPE,\n SEMVER_LESS_THAN_MATCH_TYPE,\n SEMVER_LESS_OR_EQUAL_THAN_MATCH_TYPE,\n SEMVER_GREATER_THAN_MATCH_TYPE,\n SEMVER_GREATER_OR_EQUAL_THAN_MATCH_TYPE\n];\n\ntype ConditionEvaluator = (condition: Condition, userAttributes: UserAttributes) => boolean | null;\n\nconst EVALUATORS_BY_MATCH_TYPE: { [conditionType: string]: ConditionEvaluator | undefined } = {};\nEVALUATORS_BY_MATCH_TYPE[EXACT_MATCH_TYPE] = exactEvaluator;\nEVALUATORS_BY_MATCH_TYPE[EXISTS_MATCH_TYPE] = existsEvaluator;\nEVALUATORS_BY_MATCH_TYPE[GREATER_THAN_MATCH_TYPE] = greaterThanEvaluator;\nEVALUATORS_BY_MATCH_TYPE[GREATER_OR_EQUAL_THAN_MATCH_TYPE] = greaterThanOrEqualEvaluator;\nEVALUATORS_BY_MATCH_TYPE[LESS_THAN_MATCH_TYPE] = lessThanEvaluator;\nEVALUATORS_BY_MATCH_TYPE[LESS_OR_EQUAL_THAN_MATCH_TYPE] = lessThanOrEqualEvaluator;\nEVALUATORS_BY_MATCH_TYPE[SUBSTRING_MATCH_TYPE] = substringEvaluator;\nEVALUATORS_BY_MATCH_TYPE[SEMVER_EXACT_MATCH_TYPE] = semverEqualEvaluator;\nEVALUATORS_BY_MATCH_TYPE[SEMVER_GREATER_THAN_MATCH_TYPE] = semverGreaterThanEvaluator;\nEVALUATORS_BY_MATCH_TYPE[SEMVER_GREATER_OR_EQUAL_THAN_MATCH_TYPE] = semverGreaterThanOrEqualEvaluator;\nEVALUATORS_BY_MATCH_TYPE[SEMVER_LESS_THAN_MATCH_TYPE] = semverLessThanEvaluator;\nEVALUATORS_BY_MATCH_TYPE[SEMVER_LESS_OR_EQUAL_THAN_MATCH_TYPE] = semverLessThanOrEqualEvaluator;\n\n/**\n * Given a custom attribute audience condition and user attributes, evaluate the\n * condition against the attributes.\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @return {?boolean} true/false if the given user attributes match/don't match the given condition,\n * null if the given user attributes and condition can't be evaluated\n * TODO: Change to accept and object with named properties\n */\nexport function evaluate(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const conditionMatch = condition.match;\n if (typeof conditionMatch !== 'undefined' && MATCH_TYPES.indexOf(conditionMatch) === -1) {\n logger.warn(LOG_MESSAGES.UNKNOWN_MATCH_TYPE, MODULE_NAME, JSON.stringify(condition));\n return null;\n }\n\n const attributeKey = condition.name;\n if (!userAttributes.hasOwnProperty(attributeKey) && conditionMatch != EXISTS_MATCH_TYPE) {\n logger.debug(\n LOG_MESSAGES.MISSING_ATTRIBUTE_VALUE, MODULE_NAME, JSON.stringify(condition), attributeKey\n );\n return null;\n }\n\n let evaluatorForMatch;\n if (!conditionMatch) {\n evaluatorForMatch = exactEvaluator;\n } else {\n evaluatorForMatch = EVALUATORS_BY_MATCH_TYPE[conditionMatch] || exactEvaluator;\n }\n\n return evaluatorForMatch(condition, userAttributes);\n}\n\n/**\n * Returns true if the value is valid for exact conditions. Valid values include\n * strings, booleans, and numbers that aren't NaN, -Infinity, or Infinity.\n * @param value\n * @returns {boolean}\n */\nfunction isValueTypeValidForExactConditions(value: unknown): boolean {\n return typeof value === 'string' || typeof value === 'boolean' || fns.isNumber(value);\n}\n\n/**\n * Evaluate the given exact match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @return {?boolean} true if the user attribute value is equal (===) to the condition value,\n * false if the user attribute value is not equal (!==) to the condition value,\n * null if the condition value or user attribute value has an invalid type, or\n * if there is a mismatch between the user attribute type and the condition value\n * type\n */\nfunction exactEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const conditionValue = condition.value;\n const conditionValueType = typeof conditionValue;\n const conditionName = condition.name;\n const userValue = userAttributes[conditionName];\n const userValueType = typeof userValue;\n\n if (\n !isValueTypeValidForExactConditions(conditionValue) ||\n (fns.isNumber(conditionValue) && !fns.isSafeInteger(conditionValue))\n ) {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_CONDITION_VALUE, MODULE_NAME, JSON.stringify(condition)\n );\n return null;\n }\n\n if (userValue === null) {\n logger.debug(\n LOG_MESSAGES.UNEXPECTED_TYPE_NULL, MODULE_NAME, JSON.stringify(condition), conditionName\n );\n return null;\n }\n\n if (!isValueTypeValidForExactConditions(userValue) || conditionValueType !== userValueType) {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_TYPE, MODULE_NAME, JSON.stringify(condition), userValueType, conditionName\n );\n return null;\n }\n\n if (fns.isNumber(userValue) && !fns.isSafeInteger(userValue)) {\n logger.warn(\n LOG_MESSAGES.OUT_OF_BOUNDS, MODULE_NAME, JSON.stringify(condition), conditionName\n );\n return null;\n }\n\n return conditionValue === userValue;\n}\n\n/**\n * Evaluate the given exists match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @returns {boolean} true if both:\n * 1) the user attributes have a value for the given condition, and\n * 2) the user attribute value is neither null nor undefined\n * Returns false otherwise\n */\nfunction existsEvaluator(condition: Condition, userAttributes: UserAttributes): boolean {\n const userValue = userAttributes[condition.name];\n return typeof userValue !== 'undefined' && userValue !== null;\n}\n\n/**\n * Validate user and condition values\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @returns {?boolean} true if values are valid,\n * false if values are not valid\n */\nfunction validateValuesForNumericCondition(condition: Condition, userAttributes: UserAttributes): boolean {\n const conditionName = condition.name;\n const userValue = userAttributes[conditionName];\n const userValueType = typeof userValue;\n const conditionValue = condition.value;\n\n if (conditionValue === null || !fns.isSafeInteger(conditionValue)) {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_CONDITION_VALUE, MODULE_NAME, JSON.stringify(condition)\n );\n return false;\n }\n\n if (userValue === null) {\n logger.debug(\n LOG_MESSAGES.UNEXPECTED_TYPE_NULL, MODULE_NAME, JSON.stringify(condition), conditionName\n );\n return false;\n }\n\n if (!fns.isNumber(userValue)) {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_TYPE, MODULE_NAME, JSON.stringify(condition), userValueType, conditionName\n );\n return false;\n }\n\n if (!fns.isSafeInteger(userValue)) {\n logger.warn(\n LOG_MESSAGES.OUT_OF_BOUNDS, MODULE_NAME, JSON.stringify(condition), conditionName\n );\n return false;\n }\n return true;\n}\n\n/**\n * Evaluate the given greater than match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?boolean} true if the user attribute value is greater than the condition value,\n * false if the user attribute value is less than or equal to the condition value,\n * null if the condition value isn't a number or the user attribute value\n * isn't a number\n */\nfunction greaterThanEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const userValue = userAttributes[condition.name];\n const conditionValue = condition.value;\n\n if (!validateValuesForNumericCondition(condition, userAttributes) || conditionValue === null) {\n return null;\n }\n return userValue > conditionValue;\n}\n\n/**\n * Evaluate the given greater or equal than match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute value is greater or equal than the condition value,\n * false if the user attribute value is less than to the condition value,\n * null if the condition value isn't a number or the user attribute value isn't a\n * number\n */\nfunction greaterThanOrEqualEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const userValue = userAttributes[condition.name];\n const conditionValue = condition.value;\n\n if (!validateValuesForNumericCondition(condition, userAttributes) || conditionValue === null) {\n return null;\n }\n\n return userValue >= conditionValue;\n}\n\n/**\n * Evaluate the given less than match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?boolean} true if the user attribute value is less than the condition value,\n * false if the user attribute value is greater than or equal to the condition value,\n * null if the condition value isn't a number or the user attribute value isn't a\n * number\n */\nfunction lessThanEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const userValue = userAttributes[condition.name];\n const conditionValue = condition.value;\n\n if (!validateValuesForNumericCondition(condition, userAttributes) || conditionValue === null) {\n return null;\n }\n\n return userValue < conditionValue;\n}\n\n/**\n * Evaluate the given less or equal than match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute value is less or equal than the condition value,\n * false if the user attribute value is greater than to the condition value,\n * null if the condition value isn't a number or the user attribute value isn't a\n * number\n */\nfunction lessThanOrEqualEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const userValue = userAttributes[condition.name];\n const conditionValue = condition.value;\n\n if (!validateValuesForNumericCondition(condition, userAttributes) || conditionValue === null) {\n return null;\n }\n\n return userValue <= conditionValue;\n}\n\n/**\n * Evaluate the given substring match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the condition value is a substring of the user attribute value,\n * false if the condition value is not a substring of the user attribute value,\n * null if the condition value isn't a string or the user attribute value\n * isn't a string\n */\nfunction substringEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const conditionName = condition.name;\n const userValue = userAttributes[condition.name];\n const userValueType = typeof userValue;\n const conditionValue = condition.value;\n\n if (typeof conditionValue !== 'string') {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_CONDITION_VALUE, MODULE_NAME, JSON.stringify(condition)\n );\n return null;\n }\n\n if (userValue === null) {\n logger.debug(\n LOG_MESSAGES.UNEXPECTED_TYPE_NULL, MODULE_NAME, JSON.stringify(condition), conditionName\n );\n return null;\n }\n\n if (typeof userValue !== 'string') {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_TYPE, MODULE_NAME, JSON.stringify(condition), userValueType, conditionName\n );\n return null;\n }\n\n return userValue.indexOf(conditionValue) !== -1;\n}\n\n/**\n * Evaluate the given semantic version match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?number} returns compareVersion result\n * null if the user attribute version has an invalid type\n */\nfunction evaluateSemanticVersion(condition: Condition, userAttributes: UserAttributes): number | null {\n const conditionName = condition.name;\n const userValue = userAttributes[conditionName];\n const userValueType = typeof userValue;\n const conditionValue = condition.value;\n\n if (typeof conditionValue !== 'string') {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_CONDITION_VALUE, MODULE_NAME, JSON.stringify(condition)\n );\n return null;\n }\n\n if (userValue === null) {\n logger.debug(\n LOG_MESSAGES.UNEXPECTED_TYPE_NULL, MODULE_NAME, JSON.stringify(condition), conditionName\n );\n return null;\n }\n\n if (typeof userValue !== 'string') {\n logger.warn(\n LOG_MESSAGES.UNEXPECTED_TYPE, MODULE_NAME, JSON.stringify(condition), userValueType, conditionName\n );\n return null;\n }\n \n return compareVersion(conditionValue, userValue);\n}\n\n/**\n * Evaluate the given version match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute version is equal (===) to the condition version,\n * false if the user attribute version is not equal (!==) to the condition version,\n * null if the user attribute version has an invalid type\n */\nfunction semverEqualEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const result = evaluateSemanticVersion(condition, userAttributes);\n if (result === null ) {\n return null;\n }\n return result === 0;\n}\n\n/**\n * Evaluate the given version match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute version is greater (>) than the condition version,\n * false if the user attribute version is not greater than the condition version,\n * null if the user attribute version has an invalid type\n */\nfunction semverGreaterThanEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const result = evaluateSemanticVersion(condition, userAttributes);\n if (result === null ) {\n return null;\n }\n return result > 0;\n}\n\n/**\n * Evaluate the given version match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute version is less (<) than the condition version,\n * false if the user attribute version is not less than the condition version,\n * null if the user attribute version has an invalid type\n */\nfunction semverLessThanEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const result = evaluateSemanticVersion(condition, userAttributes);\n if (result === null ) {\n return null;\n }\n return result < 0;\n}\n\n/**\n * Evaluate the given version match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute version is greater than or equal (>=) to the condition version,\n * false if the user attribute version is not greater than or equal to the condition version,\n * null if the user attribute version has an invalid type\n */\nfunction semverGreaterThanOrEqualEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const result = evaluateSemanticVersion(condition, userAttributes);\n if (result === null ) {\n return null;\n }\n return result >= 0;\n}\n\n/**\n * Evaluate the given version match condition for the given user attributes\n * @param {Condition} condition\n * @param {UserAttributes} userAttributes\n * @param {LoggerFacade} logger\n * @returns {?Boolean} true if the user attribute version is less than or equal (<=) to the condition version,\n * false if the user attribute version is not less than or equal to the condition version,\n * null if the user attribute version has an invalid type\n */\nfunction semverLessThanOrEqualEvaluator(condition: Condition, userAttributes: UserAttributes): boolean | null {\n const result = evaluateSemanticVersion(condition, userAttributes);\n if (result === null ) {\n return null;\n }\n return result <= 0;\n \n}\n","/**\n * Copyright 2016, 2018-2021, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getLogger } from '@optimizely/js-sdk-logging';\n\nimport fns from '../../utils/fns';\nimport {\n LOG_LEVEL,\n LOG_MESSAGES,\n ERROR_MESSAGES,\n} from '../../utils/enums';\nimport * as conditionTreeEvaluator from '../condition_tree_evaluator';\nimport * as customAttributeConditionEvaluator from '../custom_attribute_condition_evaluator';\nimport { UserAttributes, Audience, Condition } from '../../shared_types';\n\nconst logger = getLogger();\nconst MODULE_NAME = 'AUDIENCE_EVALUATOR';\n\nexport class AudienceEvaluator {\n private typeToEvaluatorMap: {\n [key: string]: {\n [key: string]: (condition: Condition, userAttributes: UserAttributes) => boolean | null\n };\n };\n\n /**\n * Construct an instance of AudienceEvaluator with given options\n * @param {Object=} UNSTABLE_conditionEvaluators A map of condition evaluators provided by the consumer. This enables matching\n * condition types which are not supported natively by the SDK. Note that built in\n * Optimizely evaluators cannot be overridden.\n * @constructor\n */\n constructor(UNSTABLE_conditionEvaluators: unknown) {\n this.typeToEvaluatorMap = fns.assign({}, UNSTABLE_conditionEvaluators, {\n custom_attribute: customAttributeConditionEvaluator,\n });\n }\n\n /**\n * Determine if the given user attributes satisfy the given audience conditions\n * @param {Array,\n audiencesById: { [id: string]: Audience },\n userAttributes: UserAttributes = {}\n ): boolean {\n // if there are no audiences, return true because that means ALL users are included in the experiment\n if (!audienceConditions || audienceConditions.length === 0) {\n return true;\n }\n\n const evaluateAudience = (audienceId: string) => {\n const audience = audiencesById[audienceId];\n if (audience) {\n logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.EVALUATING_AUDIENCE, MODULE_NAME, audienceId, JSON.stringify(audience.conditions)\n );\n const result = conditionTreeEvaluator.evaluate(\n audience.conditions as unknown[] ,\n this.evaluateConditionWithUserAttributes.bind(this, userAttributes)\n );\n const resultText = result === null ? 'UNKNOWN' : result.toString().toUpperCase();\n logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.AUDIENCE_EVALUATION_RESULT, MODULE_NAME, audienceId, resultText);\n return result;\n }\n return null;\n };\n\n return !!conditionTreeEvaluator.evaluate(audienceConditions, evaluateAudience);\n }\n\n /**\n * Wrapper around evaluator.evaluate that is passed to the conditionTreeEvaluator.\n * Evaluates the condition provided given the user attributes if an evaluator has been defined for the condition type.\n * @param {UserAttributes} userAttributes A map of user attributes.\n * @param {Condition} condition A single condition object to evaluate.\n * @return {boolean|null} true if the condition is satisfied, null if a matcher is not found.\n */\n evaluateConditionWithUserAttributes(userAttributes: UserAttributes, condition: Condition): boolean | null {\n const evaluator = this.typeToEvaluatorMap[condition.type];\n if (!evaluator) {\n logger.log(LOG_LEVEL.WARNING, LOG_MESSAGES.UNKNOWN_CONDITION_TYPE, MODULE_NAME, JSON.stringify(condition));\n return null;\n }\n try {\n return evaluator.evaluate(condition, userAttributes);\n } catch (err) {\n logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.CONDITION_EVALUATOR_ERROR, MODULE_NAME, condition.type, err.message\n );\n }\n\n return null;\n }\n}\n\nexport default AudienceEvaluator;\n\nexport const createAudienceEvaluator = function(UNSTABLE_conditionEvaluators: unknown): AudienceEvaluator {\n return new AudienceEvaluator(UNSTABLE_conditionEvaluators);\n};\n","/**\n * Copyright 2018, 2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Validates provided value is a non-empty string\n * @param {unknown} input\n * @return {boolean} true for non-empty string, false otherwise\n */\nexport function validate(input: unknown): boolean {\n return typeof input === 'string' && input !== '';\n}\n","/****************************************************************************\n * Copyright 2017-2022 Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\nimport { LogHandler } from '@optimizely/js-sdk-logging';\nimport { sprintf } from '../../utils/fns';\n\nimport fns from '../../utils/fns';\nimport { bucket } from '../bucketer';\nimport {\n AUDIENCE_EVALUATION_TYPES,\n CONTROL_ATTRIBUTES,\n DECISION_SOURCES,\n ERROR_MESSAGES,\n LOG_LEVEL,\n LOG_MESSAGES,\n} from '../../utils/enums';\nimport {\n getAudiencesById,\n getExperimentAudienceConditions,\n getExperimentFromId,\n getExperimentFromKey,\n getFlagVariationByKey,\n getTrafficAllocation,\n getVariationIdFromExperimentAndVariationKey,\n getVariationFromId,\n getVariationKeyFromId,\n isActive,\n ProjectConfig,\n} from '../project_config';\nimport { AudienceEvaluator, createAudienceEvaluator } from '../audience_evaluator';\nimport * as stringValidator from '../../utils/string_value_validator';\nimport {\n BucketerParams,\n DecisionResponse,\n Experiment,\n ExperimentBucketMap,\n FeatureFlag,\n OptimizelyDecideOption,\n OptimizelyUserContext,\n UserAttributes,\n UserProfile,\n UserProfileService,\n Variation,\n} from '../../shared_types';\n\nconst MODULE_NAME = 'DECISION_SERVICE';\n\nexport interface DecisionObj {\n experiment: Experiment | null;\n variation: Variation | null;\n decisionSource: string;\n}\n\ninterface DecisionServiceOptions {\n userProfileService: UserProfileService | null;\n logger: LogHandler;\n UNSTABLE_conditionEvaluators: unknown;\n}\n\ninterface DeliveryRuleResponse extends DecisionResponse {\n skipToEveryoneElse: K;\n}\n\n/**\n * Optimizely's decision service that determines which variation of an experiment the user will be allocated to.\n *\n * The decision service contains all logic around how a user decision is made. This includes all of the following (in order):\n * 1. Checking experiment status\n * 2. Checking forced bucketing\n * 3. Checking whitelisting\n * 4. Checking user profile service for past bucketing decisions (sticky bucketing)\n * 5. Checking audience targeting\n * 6. Using Murmurhash3 to bucket the user.\n *\n * @constructor\n * @param {DecisionServiceOptions} options\n * @returns {DecisionService}\n */\nexport class DecisionService {\n private logger: LogHandler;\n private audienceEvaluator: AudienceEvaluator;\n private forcedVariationMap: { [key: string]: { [id: string]: string } };\n private userProfileService: UserProfileService | null;\n\n constructor(options: DecisionServiceOptions) {\n this.audienceEvaluator = createAudienceEvaluator(options.UNSTABLE_conditionEvaluators);\n this.forcedVariationMap = {};\n this.logger = options.logger;\n this.userProfileService = options.userProfileService || null;\n }\n\n /**\n * Gets variation where visitor will be bucketed.\n * @param {ProjectConfig} configObj The parsed project configuration object\n * @param {Experiment} experiment\n * @param {OptimizelyUserContext} user A user context\n * @param {[key: string]: boolean} options Optional map of decide options\n * @return {DecisionResponse} DecisionResponse containing the variation the user is bucketed into\n * and the decide reasons.\n */\n getVariation(\n configObj: ProjectConfig,\n experiment: Experiment,\n user: OptimizelyUserContext,\n options: { [key: string]: boolean } = {}\n ): DecisionResponse {\n const userId = user.getUserId();\n const attributes = user.getAttributes();\n // by default, the bucketing ID should be the user ID\n const bucketingId = this.getBucketingId(userId, attributes);\n const decideReasons: (string | number)[][] = [];\n const experimentKey = experiment.key;\n if (!this.checkIfExperimentIsActive(configObj, experimentKey)) {\n this.logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.EXPERIMENT_NOT_RUNNING, MODULE_NAME, experimentKey);\n decideReasons.push([LOG_MESSAGES.EXPERIMENT_NOT_RUNNING, MODULE_NAME, experimentKey]);\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n const decisionForcedVariation = this.getForcedVariation(configObj, experimentKey, userId);\n decideReasons.push(...decisionForcedVariation.reasons);\n const forcedVariationKey = decisionForcedVariation.result;\n\n if (forcedVariationKey) {\n return {\n result: forcedVariationKey,\n reasons: decideReasons,\n };\n }\n const decisionWhitelistedVariation = this.getWhitelistedVariation(experiment, userId);\n decideReasons.push(...decisionWhitelistedVariation.reasons);\n let variation = decisionWhitelistedVariation.result;\n if (variation) {\n return {\n result: variation.key,\n reasons: decideReasons,\n };\n }\n\n const shouldIgnoreUPS = options[OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE];\n const experimentBucketMap = this.resolveExperimentBucketMap(userId, attributes);\n\n // check for sticky bucketing if decide options do not include shouldIgnoreUPS\n if (!shouldIgnoreUPS) {\n variation = this.getStoredVariation(configObj, experiment, userId, experimentBucketMap);\n if (variation) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.RETURNING_STORED_VARIATION,\n MODULE_NAME,\n variation.key,\n experimentKey,\n userId,\n );\n decideReasons.push([\n LOG_MESSAGES.RETURNING_STORED_VARIATION,\n MODULE_NAME,\n variation.key,\n experimentKey,\n userId,\n ]);\n return {\n result: variation.key,\n reasons: decideReasons,\n };\n }\n }\n\n // Perform regular targeting and bucketing\n const decisionifUserIsInAudience = this.checkIfUserIsInAudience(\n configObj,\n experiment,\n AUDIENCE_EVALUATION_TYPES.EXPERIMENT,\n attributes,\n ''\n );\n decideReasons.push(...decisionifUserIsInAudience.reasons);\n if (!decisionifUserIsInAudience.result) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_NOT_IN_EXPERIMENT,\n MODULE_NAME,\n userId,\n experimentKey,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_NOT_IN_EXPERIMENT,\n MODULE_NAME,\n userId,\n experimentKey,\n ]);\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n const bucketerParams = this.buildBucketerParams(configObj, experiment, bucketingId, userId);\n const decisionVariation = bucket(bucketerParams);\n decideReasons.push(...decisionVariation.reasons);\n const variationId = decisionVariation.result;\n if (variationId) {\n variation = configObj.variationIdMap[variationId];\n }\n if (!variation) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_HAS_NO_VARIATION,\n MODULE_NAME,\n userId,\n experimentKey,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_NO_VARIATION,\n MODULE_NAME,\n userId,\n experimentKey,\n ]);\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_HAS_VARIATION,\n MODULE_NAME,\n userId,\n variation.key,\n experimentKey,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_VARIATION,\n MODULE_NAME,\n userId,\n variation.key,\n experimentKey,\n ]);\n // persist bucketing if decide options do not include shouldIgnoreUPS\n if (!shouldIgnoreUPS) {\n this.saveUserProfile(experiment, variation, userId, experimentBucketMap);\n }\n\n return {\n result: variation.key,\n reasons: decideReasons,\n };\n }\n\n /**\n * Merges attributes from attributes[STICKY_BUCKETING_KEY] and userProfileService\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @return {ExperimentBucketMap} finalized copy of experiment_bucket_map\n */\n private resolveExperimentBucketMap(\n userId: string,\n attributes?: UserAttributes\n ): ExperimentBucketMap {\n attributes = attributes || {};\n\n const userProfile = this.getUserProfile(userId) || {} as UserProfile;\n const attributeExperimentBucketMap = attributes[CONTROL_ATTRIBUTES.STICKY_BUCKETING_KEY];\n return fns.assign({}, userProfile.experiment_bucket_map, attributeExperimentBucketMap);\n }\n\n /**\n * Checks whether the experiment is running\n * @param {ProjectConfig} configObj The parsed project configuration object\n * @param {string} experimentKey Key of experiment being validated\n * @return {boolean} True if experiment is running\n */\n private checkIfExperimentIsActive(configObj: ProjectConfig, experimentKey: string): boolean {\n return isActive(configObj, experimentKey);\n }\n\n /**\n * Checks if user is whitelisted into any variation and return that variation if so\n * @param {Experiment} experiment\n * @param {string} userId\n * @return {DecisionResponse} DecisionResponse containing the forced variation if it exists\n * or user ID and the decide reasons.\n */\n private getWhitelistedVariation(\n experiment: Experiment,\n userId: string\n ): DecisionResponse {\n const decideReasons: (string | number)[][] = [];\n if (experiment.forcedVariations && experiment.forcedVariations.hasOwnProperty(userId)) {\n const forcedVariationKey = experiment.forcedVariations[userId];\n if (experiment.variationKeyMap.hasOwnProperty(forcedVariationKey)) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_FORCED_IN_VARIATION,\n MODULE_NAME,\n userId,\n forcedVariationKey,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_FORCED_IN_VARIATION,\n MODULE_NAME,\n userId,\n forcedVariationKey,\n ]);\n return {\n result: experiment.variationKeyMap[forcedVariationKey],\n reasons: decideReasons,\n };\n } else {\n this.logger.log(\n LOG_LEVEL.ERROR,\n LOG_MESSAGES.FORCED_BUCKETING_FAILED,\n MODULE_NAME,\n forcedVariationKey,\n userId,\n );\n decideReasons.push([\n LOG_MESSAGES.FORCED_BUCKETING_FAILED,\n MODULE_NAME,\n forcedVariationKey,\n userId,\n ]);\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n }\n\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n /**\n * Checks whether the user is included in experiment audience\n * @param {ProjectConfig} configObj The parsed project configuration object\n * @param {string} experimentKey Key of experiment being validated\n * @param {string} evaluationAttribute String representing experiment key or rule\n * @param {string} userId ID of user\n * @param {UserAttributes} attributes Optional parameter for user's attributes\n * @param {string} loggingKey String representing experiment key or rollout rule. To be used in log messages only.\n * @return {DecisionResponse} DecisionResponse DecisionResponse containing result true if user meets audience conditions and\n * the decide reasons.\n */\n private checkIfUserIsInAudience(\n configObj: ProjectConfig,\n experiment: Experiment,\n evaluationAttribute: string,\n attributes?: UserAttributes,\n loggingKey?: string | number,\n ): DecisionResponse {\n const decideReasons: (string | number)[][] = [];\n const experimentAudienceConditions = getExperimentAudienceConditions(configObj, experiment.id);\n const audiencesById = getAudiencesById(configObj);\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.EVALUATING_AUDIENCES_COMBINED,\n MODULE_NAME,\n evaluationAttribute,\n loggingKey || experiment.key,\n JSON.stringify(experimentAudienceConditions),\n );\n decideReasons.push([\n LOG_MESSAGES.EVALUATING_AUDIENCES_COMBINED,\n MODULE_NAME,\n evaluationAttribute,\n loggingKey || experiment.key,\n JSON.stringify(experimentAudienceConditions),\n ]);\n const result = this.audienceEvaluator.evaluate(experimentAudienceConditions, audiencesById, attributes);\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.AUDIENCE_EVALUATION_RESULT_COMBINED,\n MODULE_NAME,\n evaluationAttribute,\n loggingKey || experiment.key,\n result.toString().toUpperCase(),\n );\n decideReasons.push([\n LOG_MESSAGES.AUDIENCE_EVALUATION_RESULT_COMBINED,\n MODULE_NAME,\n evaluationAttribute,\n loggingKey || experiment.key,\n result.toString().toUpperCase(),\n ]);\n\n return {\n result: result,\n reasons: decideReasons,\n };\n }\n\n /**\n * Given an experiment key and user ID, returns params used in bucketer call\n * @param {ProjectConfig} configObj The parsed project configuration object\n * @param {string} experimentKey Experiment key used for bucketer\n * @param {string} bucketingId ID to bucket user into\n * @param {string} userId ID of user to be bucketed\n * @return {BucketerParams}\n */\n private buildBucketerParams(\n configObj: ProjectConfig,\n experiment: Experiment,\n bucketingId: string,\n userId: string\n ): BucketerParams {\n return {\n bucketingId,\n experimentId: experiment.id,\n experimentKey: experiment.key,\n experimentIdMap: configObj.experimentIdMap,\n experimentKeyMap: configObj.experimentKeyMap,\n groupIdMap: configObj.groupIdMap,\n logger: this.logger,\n trafficAllocationConfig: getTrafficAllocation(configObj, experiment.id),\n userId,\n variationIdMap: configObj.variationIdMap,\n }\n }\n\n /**\n * Pull the stored variation out of the experimentBucketMap for an experiment/userId\n * @param {ProjectConfig} configObj The parsed project configuration object\n * @param {Experiment} experiment\n * @param {string} userId\n * @param {ExperimentBucketMap} experimentBucketMap mapping experiment => { variation_id: }\n * @return {Variation|null} the stored variation or null if the user profile does not have one for the given experiment\n */\n private getStoredVariation(\n configObj: ProjectConfig,\n experiment: Experiment,\n userId: string,\n experimentBucketMap: ExperimentBucketMap\n ): Variation | null {\n if (experimentBucketMap.hasOwnProperty(experiment.id)) {\n const decision = experimentBucketMap[experiment.id];\n const variationId = decision.variation_id;\n if (configObj.variationIdMap.hasOwnProperty(variationId)) {\n return configObj.variationIdMap[decision.variation_id];\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.SAVED_VARIATION_NOT_FOUND,\n MODULE_NAME, userId,\n variationId,\n experiment.key,\n );\n }\n }\n\n return null;\n }\n\n /**\n * Get the user profile with the given user ID\n * @param {string} userId\n * @return {UserProfile|null} the stored user profile or null if one isn't found\n */\n private getUserProfile(userId: string): UserProfile | null {\n const userProfile = {\n user_id: userId,\n experiment_bucket_map: {},\n };\n\n if (!this.userProfileService) {\n return userProfile;\n }\n\n try {\n return this.userProfileService.lookup(userId);\n } catch (ex) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.USER_PROFILE_LOOKUP_ERROR,\n MODULE_NAME,\n userId,\n ex.message,\n );\n }\n\n return null;\n }\n\n /**\n * Saves the bucketing decision to the user profile\n * @param {Experiment} experiment\n * @param {Variation} variation\n * @param {string} userId\n * @param {ExperimentBucketMap} experimentBucketMap\n */\n private saveUserProfile(\n experiment: Experiment,\n variation: Variation,\n userId: string,\n experimentBucketMap: ExperimentBucketMap\n ): void {\n if (!this.userProfileService) {\n return;\n }\n\n try {\n experimentBucketMap[experiment.id] = {\n variation_id: variation.id\n };\n\n this.userProfileService.save({\n user_id: userId,\n experiment_bucket_map: experimentBucketMap,\n });\n\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.SAVED_VARIATION,\n MODULE_NAME,\n variation.key,\n experiment.key,\n userId,\n );\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ERROR_MESSAGES.USER_PROFILE_SAVE_ERROR, MODULE_NAME, userId, ex.message);\n }\n }\n\n /**\n * Given a feature, user ID, and attributes, returns a decision response containing \n * an object representing a decision and decide reasons. If the user was bucketed into\n * a variation for the given feature and attributes, the decision object will have variation and\n * experiment properties (both objects), as well as a decisionSource property.\n * decisionSource indicates whether the decision was due to a rollout or an\n * experiment.\n * @param {ProjectConfig} configObj The parsed project configuration object\n * @param {FeatureFlag} feature A feature flag object from project configuration\n * @param {OptimizelyUserContext} user A user context\n * @param {[key: string]: boolean} options Map of decide options\n * @return {DecisionResponse} DecisionResponse DecisionResponse containing an object with experiment, variation, and decisionSource\n * properties and decide reasons. If the user was not bucketed into a variation, the variation\n * property in decision object is null.\n */\n getVariationForFeature(\n configObj: ProjectConfig,\n feature: FeatureFlag,\n user: OptimizelyUserContext,\n options: { [key: string]: boolean } = {}\n ): DecisionResponse {\n\n const decideReasons: (string | number)[][] = [];\n const decisionVariation = this.getVariationForFeatureExperiment(configObj, feature, user, options);\n decideReasons.push(...decisionVariation.reasons);\n const experimentDecision = decisionVariation.result;\n\n if (experimentDecision.variation !== null) {\n return {\n result: experimentDecision,\n reasons: decideReasons,\n };\n }\n\n const decisionRolloutVariation = this.getVariationForRollout(configObj, feature, user);\n decideReasons.push(...decisionRolloutVariation.reasons);\n const rolloutDecision = decisionRolloutVariation.result;\n const userId = user.getUserId();\n if (rolloutDecision.variation) {\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.USER_IN_ROLLOUT, MODULE_NAME, userId, feature.key);\n decideReasons.push([LOG_MESSAGES.USER_IN_ROLLOUT, MODULE_NAME, userId, feature.key]);\n return {\n result: rolloutDecision,\n reasons: decideReasons,\n };\n }\n\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.USER_NOT_IN_ROLLOUT, MODULE_NAME, userId, feature.key);\n decideReasons.push([LOG_MESSAGES.USER_NOT_IN_ROLLOUT, MODULE_NAME, userId, feature.key]);\n return {\n result: rolloutDecision,\n reasons: decideReasons,\n };\n }\n\n private getVariationForFeatureExperiment(\n configObj: ProjectConfig,\n feature: FeatureFlag,\n user: OptimizelyUserContext,\n options: { [key: string]: boolean } = {}\n ): DecisionResponse {\n\n const decideReasons: (string | number)[][] = [];\n let variationKey = null;\n let decisionVariation;\n let index;\n let variationForFeatureExperiment;\n\n // Check if the feature flag is under an experiment and the the user is bucketed into one of these experiments\n if (feature.experimentIds.length > 0) {\n // Evaluate each experiment ID and return the first bucketed experiment variation\n for (index = 0; index < feature.experimentIds.length; index++) {\n const experiment = getExperimentFromId(configObj, feature.experimentIds[index], this.logger);\n if (experiment) {\n decisionVariation = this.getVariationFromExperimentRule(configObj, feature.key, experiment, user, options);\n decideReasons.push(...decisionVariation.reasons);\n variationKey = decisionVariation.result;\n if (variationKey) {\n let variation = null;\n variation = experiment.variationKeyMap[variationKey];\n if (!variation) {\n variation = getFlagVariationByKey(configObj, feature.key, variationKey);\n }\n variationForFeatureExperiment = {\n experiment: experiment,\n variation: variation,\n decisionSource: DECISION_SOURCES.FEATURE_TEST,\n };\n\n return {\n result: variationForFeatureExperiment,\n reasons: decideReasons,\n }\n }\n }\n }\n } else {\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.FEATURE_HAS_NO_EXPERIMENTS, MODULE_NAME, feature.key);\n decideReasons.push([LOG_MESSAGES.FEATURE_HAS_NO_EXPERIMENTS, MODULE_NAME, feature.key]);\n }\n\n variationForFeatureExperiment = {\n experiment: null,\n variation: null,\n decisionSource: DECISION_SOURCES.FEATURE_TEST,\n };\n\n return {\n result: variationForFeatureExperiment,\n reasons: decideReasons,\n };\n }\n\n private getVariationForRollout(\n configObj: ProjectConfig,\n feature: FeatureFlag,\n user: OptimizelyUserContext,\n ): DecisionResponse {\n const decideReasons: (string | number)[][] = [];\n let decisionObj: DecisionObj;\n if (!feature.rolloutId) {\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.NO_ROLLOUT_EXISTS, MODULE_NAME, feature.key);\n decideReasons.push([LOG_MESSAGES.NO_ROLLOUT_EXISTS, MODULE_NAME, feature.key]);\n decisionObj = {\n experiment: null,\n variation: null,\n decisionSource: DECISION_SOURCES.ROLLOUT,\n };\n\n return {\n result: decisionObj,\n reasons: decideReasons,\n };\n }\n\n const rollout = configObj.rolloutIdMap[feature.rolloutId];\n if (!rollout) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.INVALID_ROLLOUT_ID,\n MODULE_NAME,\n feature.rolloutId,\n feature.key,\n );\n decideReasons.push([ERROR_MESSAGES.INVALID_ROLLOUT_ID, MODULE_NAME, feature.rolloutId, feature.key]);\n decisionObj = {\n experiment: null,\n variation: null,\n decisionSource: DECISION_SOURCES.ROLLOUT,\n };\n return {\n result: decisionObj,\n reasons: decideReasons,\n };\n }\n\n const rolloutRules = rollout.experiments;\n if (rolloutRules.length === 0) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n LOG_MESSAGES.ROLLOUT_HAS_NO_EXPERIMENTS,\n MODULE_NAME,\n feature.rolloutId,\n );\n decideReasons.push([LOG_MESSAGES.ROLLOUT_HAS_NO_EXPERIMENTS, MODULE_NAME, feature.rolloutId]);\n decisionObj = {\n experiment: null,\n variation: null,\n decisionSource: DECISION_SOURCES.ROLLOUT,\n };\n return {\n result: decisionObj,\n reasons: decideReasons,\n };\n }\n let decisionVariation;\n let skipToEveryoneElse;\n let variation;\n let rolloutRule;\n let index = 0;\n while (index < rolloutRules.length) {\n decisionVariation = this.getVariationFromDeliveryRule(configObj, feature.key, rolloutRules, index, user);\n decideReasons.push(...decisionVariation.reasons);\n variation = decisionVariation.result;\n skipToEveryoneElse = decisionVariation.skipToEveryoneElse;\n if (variation) {\n rolloutRule = configObj.experimentIdMap[rolloutRules[index].id];\n decisionObj = {\n experiment: rolloutRule,\n variation: variation,\n decisionSource: DECISION_SOURCES.ROLLOUT\n };\n return {\n result: decisionObj,\n reasons: decideReasons,\n };\n }\n // the last rule is special for \"Everyone Else\"\n index = skipToEveryoneElse ? (rolloutRules.length - 1) : (index + 1);\n }\n\n decisionObj = {\n experiment: null,\n variation: null,\n decisionSource: DECISION_SOURCES.ROLLOUT,\n };\n\n return {\n result: decisionObj,\n reasons: decideReasons,\n };\n }\n\n /**\n * Get bucketing Id from user attributes.\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @returns {string} Bucketing Id if it is a string type in attributes, user Id otherwise.\n */\n private getBucketingId(userId: string, attributes?: UserAttributes): string {\n let bucketingId = userId;\n\n // If the bucketing ID key is defined in attributes, than use that in place of the userID for the murmur hash key\n if (\n attributes != null &&\n typeof attributes === 'object' &&\n attributes.hasOwnProperty(CONTROL_ATTRIBUTES.BUCKETING_ID)\n ) {\n if (typeof attributes[CONTROL_ATTRIBUTES.BUCKETING_ID] === 'string') {\n bucketingId = attributes[CONTROL_ATTRIBUTES.BUCKETING_ID];\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.VALID_BUCKETING_ID, MODULE_NAME, bucketingId);\n } else {\n this.logger.log(LOG_LEVEL.WARNING, LOG_MESSAGES.BUCKETING_ID_NOT_STRING, MODULE_NAME);\n }\n }\n\n return bucketingId;\n }\n\n /**\n * Finds a validated forced decision for specific flagKey and optional ruleKey.\n * @param {ProjectConfig} config A projectConfig.\n * @param {OptimizelyUserContext} user A Optimizely User Context.\n * @param {string} flagKey A flagKey.\n * @param {ruleKey} ruleKey A ruleKey (optional).\n * @return {DecisionResponse} DecisionResponse object containing valid variation object and decide reasons.\n */\n findValidatedForcedDecision(\n config: ProjectConfig,\n user: OptimizelyUserContext,\n flagKey: string,\n ruleKey?: string\n ): DecisionResponse {\n\n const decideReasons: (string | number)[][] = [];\n const forcedDecision = user.getForcedDecision({ flagKey, ruleKey });\n let variation = null;\n let variationKey;\n const userId = user.getUserId()\n if (config && forcedDecision) {\n variationKey = forcedDecision.variationKey;\n variation = getFlagVariationByKey(config, flagKey, variationKey);\n if (variation) {\n if (ruleKey) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,\n variationKey,\n flagKey,\n ruleKey,\n userId\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED,\n variationKey,\n flagKey,\n ruleKey,\n userId\n ]);\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED,\n variationKey,\n flagKey,\n userId\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED,\n variationKey,\n flagKey,\n userId\n ])\n }\n } else {\n if (ruleKey) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,\n flagKey,\n ruleKey,\n userId\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID,\n flagKey,\n ruleKey,\n userId\n ]);\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID,\n flagKey,\n userId\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID,\n flagKey,\n userId\n ])\n }\n }\n }\n\n return {\n result: variation,\n reasons: decideReasons,\n }\n }\n\n /**\n * Removes forced variation for given userId and experimentKey\n * @param {string} userId String representing the user id\n * @param {string} experimentId Number representing the experiment id\n * @param {string} experimentKey Key representing the experiment id\n * @throws If the user id is not valid or not in the forced variation map\n */\n removeForcedVariation(userId: string, experimentId: string, experimentKey: string): void {\n if (!userId) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_ID, MODULE_NAME));\n }\n\n if (this.forcedVariationMap.hasOwnProperty(userId)) {\n delete this.forcedVariationMap[userId][experimentId];\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.VARIATION_REMOVED_FOR_USER,\n MODULE_NAME,\n experimentKey,\n userId,\n );\n } else {\n throw new Error(sprintf(ERROR_MESSAGES.USER_NOT_IN_FORCED_VARIATION, MODULE_NAME, userId));\n }\n }\n\n /**\n * Sets forced variation for given userId and experimentKey\n * @param {string} userId String representing the user id\n * @param {string} experimentId Number representing the experiment id\n * @param {number} variationId Number representing the variation id\n * @throws If the user id is not valid\n */\n private setInForcedVariationMap(userId: string, experimentId: string, variationId: string): void {\n if (this.forcedVariationMap.hasOwnProperty(userId)) {\n this.forcedVariationMap[userId][experimentId] = variationId;\n } else {\n this.forcedVariationMap[userId] = {};\n this.forcedVariationMap[userId][experimentId] = variationId;\n }\n\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_MAPPED_TO_FORCED_VARIATION,\n MODULE_NAME,\n variationId,\n experimentId,\n userId,\n );\n }\n\n /**\n * Gets the forced variation key for the given user and experiment.\n * @param {ProjectConfig} configObj Object representing project configuration\n * @param {string} experimentKey Key for experiment.\n * @param {string} userId The user Id.\n * @return {DecisionResponse} DecisionResponse containing variation which the given user and experiment\n * should be forced into and the decide reasons.\n */\n getForcedVariation(\n configObj: ProjectConfig,\n experimentKey: string,\n userId: string\n ): DecisionResponse {\n const decideReasons: (string | number)[][] = [];\n const experimentToVariationMap = this.forcedVariationMap[userId];\n if (!experimentToVariationMap) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_HAS_NO_FORCED_VARIATION,\n MODULE_NAME,\n userId,\n );\n\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n let experimentId;\n try {\n const experiment = getExperimentFromKey(configObj, experimentKey);\n if (experiment.hasOwnProperty('id')) {\n experimentId = experiment['id'];\n } else {\n // catching improperly formatted experiments\n this.logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.IMPROPERLY_FORMATTED_EXPERIMENT,\n MODULE_NAME,\n experimentKey,\n );\n decideReasons.push([\n ERROR_MESSAGES.IMPROPERLY_FORMATTED_EXPERIMENT,\n MODULE_NAME,\n experimentKey,\n ]);\n\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n } catch (ex) {\n // catching experiment not in datafile\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n decideReasons.push(ex.message);\n\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n const variationId = experimentToVariationMap[experimentId];\n if (!variationId) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_HAS_NO_FORCED_VARIATION_FOR_EXPERIMENT,\n MODULE_NAME,\n experimentKey,\n userId,\n );\n return {\n result: null,\n reasons: decideReasons,\n };\n }\n\n const variationKey = getVariationKeyFromId(configObj, variationId);\n if (variationKey) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_HAS_FORCED_VARIATION,\n MODULE_NAME,\n variationKey,\n experimentKey,\n userId,\n );\n decideReasons.push([\n LOG_MESSAGES.USER_HAS_FORCED_VARIATION,\n MODULE_NAME,\n variationKey,\n experimentKey,\n userId,\n ]);\n } else {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_HAS_NO_FORCED_VARIATION_FOR_EXPERIMENT,\n MODULE_NAME,\n experimentKey,\n userId,\n );\n }\n\n return {\n result: variationKey,\n reasons: decideReasons,\n };\n }\n\n /**\n * Sets the forced variation for a user in a given experiment\n * @param {ProjectConfig} configObj Object representing project configuration\n * @param {string} experimentKey Key for experiment.\n * @param {string} userId The user Id.\n * @param {string|null} variationKey Key for variation. If null, then clear the existing experiment-to-variation mapping\n * @return {boolean} A boolean value that indicates if the set completed successfully.\n */\n setForcedVariation(\n configObj: ProjectConfig,\n experimentKey: string,\n userId: string,\n variationKey: string | null\n ): boolean {\n if (variationKey != null && !stringValidator.validate(variationKey)) {\n this.logger.log(LOG_LEVEL.ERROR, ERROR_MESSAGES.INVALID_VARIATION_KEY, MODULE_NAME);\n return false;\n }\n\n let experimentId;\n try {\n const experiment = getExperimentFromKey(configObj, experimentKey);\n if (experiment.hasOwnProperty('id')) {\n experimentId = experiment['id'];\n } else {\n // catching improperly formatted experiments\n this.logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.IMPROPERLY_FORMATTED_EXPERIMENT,\n MODULE_NAME,\n experimentKey,\n );\n return false;\n }\n } catch (ex) {\n // catching experiment not in datafile\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n return false;\n }\n\n if (variationKey == null) {\n try {\n this.removeForcedVariation(userId, experimentId, experimentKey);\n return true;\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n return false;\n }\n }\n\n const variationId = getVariationIdFromExperimentAndVariationKey(configObj, experimentKey, variationKey);\n\n if (!variationId) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n ERROR_MESSAGES.NO_VARIATION_FOR_EXPERIMENT_KEY,\n MODULE_NAME,\n variationKey,\n experimentKey,\n );\n return false;\n }\n\n try {\n this.setInForcedVariationMap(userId, experimentId, variationId);\n return true;\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n return false;\n }\n }\n\n getVariationFromExperimentRule(\n configObj: ProjectConfig,\n flagKey: string,\n rule: Experiment,\n user: OptimizelyUserContext,\n options: { [key: string]: boolean } = {}\n ): DecisionResponse {\n const decideReasons: (string | number)[][] = [];\n\n // check forced decision first\n const forcedDecisionResponse = this.findValidatedForcedDecision(configObj, user, flagKey, rule.key);\n decideReasons.push(...forcedDecisionResponse.reasons);\n\n const forcedVariaton = forcedDecisionResponse.result;\n if (forcedVariaton) {\n return {\n result: forcedVariaton.key,\n reasons: decideReasons,\n };\n }\n const decisionVariation = this.getVariation(configObj, rule, user, options);\n decideReasons.push(...decisionVariation.reasons);\n const variationKey = decisionVariation.result;\n\n return {\n result: variationKey,\n reasons: decideReasons,\n };\n }\n\n getVariationFromDeliveryRule(\n configObj: ProjectConfig,\n flagKey: string,\n rules: Experiment[],\n ruleIndex: number,\n user: OptimizelyUserContext\n ): DeliveryRuleResponse {\n const decideReasons: (string | number)[][] = [];\n let skipToEveryoneElse = false;\n\n // check forced decision first\n const rule = rules[ruleIndex];\n const forcedDecisionResponse = this.findValidatedForcedDecision(configObj, user, flagKey, rule.key);\n decideReasons.push(...forcedDecisionResponse.reasons);\n\n const forcedVariaton = forcedDecisionResponse.result;\n if (forcedVariaton) {\n return {\n result: forcedVariaton,\n reasons: decideReasons,\n skipToEveryoneElse,\n };\n }\n\n const userId = user.getUserId();\n const attributes = user.getAttributes();\n const bucketingId = this.getBucketingId(userId, attributes);\n const everyoneElse = ruleIndex === rules.length - 1;\n const loggingKey = everyoneElse ? \"Everyone Else\" : ruleIndex + 1;\n\n let bucketedVariation = null;\n let bucketerVariationId;\n let bucketerParams;\n let decisionVariation;\n const decisionifUserIsInAudience = this.checkIfUserIsInAudience(\n configObj,\n rule,\n AUDIENCE_EVALUATION_TYPES.RULE,\n attributes,\n loggingKey\n );\n decideReasons.push(...decisionifUserIsInAudience.reasons);\n if (decisionifUserIsInAudience.result) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_MEETS_CONDITIONS_FOR_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n );\n decideReasons.push([\n LOG_MESSAGES.USER_MEETS_CONDITIONS_FOR_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n ]);\n\n bucketerParams = this.buildBucketerParams(configObj, rule, bucketingId, userId);\n decisionVariation = bucket(bucketerParams);\n decideReasons.push(...decisionVariation.reasons);\n bucketerVariationId = decisionVariation.result;\n if (bucketerVariationId) {\n bucketedVariation = getVariationFromId(configObj, bucketerVariationId);\n }\n if (bucketedVariation) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_BUCKETED_INTO_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n );\n decideReasons.push([\n LOG_MESSAGES.USER_BUCKETED_INTO_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey]);\n } else if (!everyoneElse) {\n // skip this logging for EveryoneElse since this has a message not for EveryoneElse\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_NOT_BUCKETED_INTO_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n );\n decideReasons.push([\n LOG_MESSAGES.USER_NOT_BUCKETED_INTO_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n ]);\n\n // skip the rest of rollout rules to the everyone-else rule if audience matches but not bucketed\n skipToEveryoneElse = true;\n }\n } else {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n );\n decideReasons.push([\n LOG_MESSAGES.USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE,\n MODULE_NAME,\n userId,\n loggingKey\n ]);\n }\n\n return {\n result: bucketedVariation,\n reasons: decideReasons,\n skipToEveryoneElse,\n };\n }\n}\n\n/**\n * Creates an instance of the DecisionService.\n * @param {DecisionServiceOptions} options Configuration options\n * @return {Object} An instance of the DecisionService\n */\nexport function createDecisionService(options: DecisionServiceOptions): DecisionService {\n return new DecisionService(options);\n}\n","/**\n * Copyright 2017, 2019-2020 Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { EventTags } from '@optimizely/js-sdk-event-processor';\nimport { LoggerFacade } from '@optimizely/js-sdk-logging';\n\nimport {\n LOG_LEVEL,\n LOG_MESSAGES,\n RESERVED_EVENT_KEYWORDS,\n} from '../enums';\n\n/**\n * Provides utility method for parsing event tag values\n */\nconst MODULE_NAME = 'EVENT_TAG_UTILS';\nconst REVENUE_EVENT_METRIC_NAME = RESERVED_EVENT_KEYWORDS.REVENUE;\nconst VALUE_EVENT_METRIC_NAME = RESERVED_EVENT_KEYWORDS.VALUE;\n\n/**\n * Grab the revenue value from the event tags. \"revenue\" is a reserved keyword.\n * @param {EventTags} eventTags\n * @param {LoggerFacade} logger\n * @return {number|null}\n */\nexport function getRevenueValue(eventTags: EventTags, logger: LoggerFacade): number | null {\n if (eventTags.hasOwnProperty(REVENUE_EVENT_METRIC_NAME)) {\n const rawValue = eventTags[REVENUE_EVENT_METRIC_NAME];\n let parsedRevenueValue;\n if (typeof rawValue === 'string') {\n parsedRevenueValue = parseInt(rawValue);\n if (isNaN(parsedRevenueValue)) {\n logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.FAILED_TO_PARSE_REVENUE, MODULE_NAME, rawValue);\n return null;\n }\n logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.PARSED_REVENUE_VALUE, MODULE_NAME, parsedRevenueValue);\n return parsedRevenueValue;\n }\n if (typeof rawValue === 'number') {\n parsedRevenueValue = rawValue;\n logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.PARSED_REVENUE_VALUE, MODULE_NAME, parsedRevenueValue);\n return parsedRevenueValue;\n }\n return null;\n }\n return null;\n}\n\n/**\n * Grab the event value from the event tags. \"value\" is a reserved keyword.\n * @param {EventTags} eventTags\n * @param {LoggerFacade} logger\n * @return {number|null}\n */\nexport function getEventValue(eventTags: EventTags, logger: LoggerFacade): number | null {\n if (eventTags.hasOwnProperty(VALUE_EVENT_METRIC_NAME)) {\n const rawValue = eventTags[VALUE_EVENT_METRIC_NAME];\n let parsedEventValue;\n if (typeof rawValue === 'string') {\n parsedEventValue = parseFloat(rawValue);\n if (isNaN(parsedEventValue)) {\n logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.FAILED_TO_PARSE_VALUE, MODULE_NAME, rawValue);\n return null;\n }\n logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.PARSED_NUMERIC_VALUE, MODULE_NAME, parsedEventValue);\n return parsedEventValue;\n }\n if (typeof rawValue === 'number') {\n parsedEventValue = rawValue;\n logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.PARSED_NUMERIC_VALUE, MODULE_NAME, parsedEventValue);\n return parsedEventValue;\n }\n return null;\n }\n return null;\n}\n","/**\n * Copyright 2016, 2018-2020, 2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { sprintf } from '../../utils/fns';\nimport { ObjectWithUnknownProperties } from '../../shared_types';\n\nimport fns from '../../utils/fns';\nimport { ERROR_MESSAGES } from '../enums';\n\nconst MODULE_NAME = 'ATTRIBUTES_VALIDATOR';\n\n/**\n * Validates user's provided attributes\n * @param {unknown} attributes\n * @return {boolean} true if the attributes are valid\n * @throws If the attributes are not valid\n */\n\nexport function validate(attributes: unknown): boolean {\n if (typeof attributes === 'object' && !Array.isArray(attributes) && attributes !== null) {\n Object.keys(attributes).forEach(function(key) {\n if (typeof (attributes as ObjectWithUnknownProperties)[key] === 'undefined') {\n throw new Error(sprintf(ERROR_MESSAGES.UNDEFINED_ATTRIBUTE, MODULE_NAME, key));\n }\n });\n return true;\n } else {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_ATTRIBUTES, MODULE_NAME));\n }\n}\n\n/**\n * Validates user's provided attribute\n * @param {unknown} attributeKey\n * @param {unknown} attributeValue\n * @return {boolean} true if the attribute is valid\n */\nexport function isAttributeValid(attributeKey: unknown, attributeValue: unknown): boolean {\n return (\n typeof attributeKey === 'string' &&\n (typeof attributeValue === 'string' ||\n typeof attributeValue === 'boolean' ||\n (fns.isNumber(attributeValue) && fns.isSafeInteger(attributeValue)))\n );\n}\n","/**\n * Copyright 2016-2021, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { LoggerFacade } from '@optimizely/js-sdk-logging';\nimport { EventV1 as CommonEventParams } from '@optimizely/js-sdk-event-processor';\n\nimport fns from '../../utils/fns';\nimport { CONTROL_ATTRIBUTES, RESERVED_EVENT_KEYWORDS } from '../../utils/enums';\nimport {\n getAttributeId,\n getEventId,\n getLayerId,\n getVariationKeyFromId,\n ProjectConfig,\n} from '../project_config';\nimport * as eventTagUtils from '../../utils/event_tag_utils';\nimport { isAttributeValid } from '../../utils/attributes_validator';\nimport { EventTags, UserAttributes, Event as EventLoggingEndpoint } from '../../shared_types';\n\nconst ACTIVATE_EVENT_KEY = 'campaign_activated';\nconst CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom';\nconst ENDPOINT = 'https://logx.optimizely.com/v1/events';\nconst HTTP_VERB = 'POST';\n\ninterface ImpressionOptions {\n // Object representing user attributes and values which need to be recorded\n attributes?: UserAttributes;\n // The client we are using: node or javascript\n clientEngine: string;\n // The version of the client\n clientVersion: string;\n // Object representing project configuration, including datafile information and mappings for quick lookup\n configObj: ProjectConfig;\n // Experiment for which impression needs to be recorded\n experimentId: string | null;\n // Key of an experiment for which impression needs to be recorded\n ruleKey: string;\n // Key for a feature flag\n flagKey: string;\n // Boolean representing if feature is enabled\n enabled: boolean;\n // Type for the decision source\n ruleType: string;\n // Event key representing the event which needs to be recorded\n eventKey?: string;\n // ID for variation which would be presented to user\n variationId: string | null;\n // Logger object\n logger: LoggerFacade;\n // ID for user\n userId: string;\n}\n\ninterface ConversionEventOptions {\n // Object representing user attributes and values which need to be recorded\n attributes?: UserAttributes;\n // The client we are using: node or javascript\n clientEngine: string;\n // The version of the client\n clientVersion: string;\n // Object representing project configuration, including datafile information and mappings for quick lookup\n configObj: ProjectConfig;\n // Event key representing the event which needs to be recorded\n eventKey: string;\n // Logger object\n logger: LoggerFacade;\n // ID for user\n userId: string;\n // Object with event-specific tags\n eventTags?: EventTags;\n}\n\ntype Metadata = {\n flag_key: string;\n rule_key: string;\n rule_type: string;\n variation_key: string;\n enabled: boolean;\n}\n\ntype Decision = {\n campaign_id: string | null;\n experiment_id: string | null;\n variation_id: string | null;\n metadata: Metadata;\n}\n\ntype SnapshotEvent = {\n entity_id: string | null;\n timestamp: number;\n uuid: string;\n key: string;\n revenue?: number;\n value?: number;\n tags?: EventTags;\n}\n\ninterface Snapshot {\n decisions?: Decision[];\n events: SnapshotEvent[];\n}\n\n/**\n * Get params which are used same in both conversion and impression events\n * @param {ImpressionOptions|ConversionEventOptions} options Object containing values needed to build impression/conversion event\n * @return {CommonEventParams} Common params with properties that are used in both conversion and impression events\n */\nfunction getCommonEventParams({\n attributes,\n userId,\n clientEngine,\n clientVersion,\n configObj,\n logger,\n}: ImpressionOptions | ConversionEventOptions): CommonEventParams {\n\n const anonymize_ip = configObj.anonymizeIP ? configObj.anonymizeIP : false;\n const botFiltering = configObj.botFiltering;\n\n const visitor = {\n snapshots: [],\n visitor_id: userId,\n attributes: [],\n };\n\n const commonParams: CommonEventParams = {\n account_id: configObj.accountId,\n project_id: configObj.projectId,\n visitors: [visitor],\n revision: configObj.revision,\n client_name: clientEngine,\n client_version: clientVersion,\n anonymize_ip: anonymize_ip,\n enrich_decisions: true,\n };\n\n if (attributes) {\n // Omit attribute values that are not supported by the log endpoint.\n Object.keys(attributes || {}).forEach(function(attributeKey) {\n const attributeValue = attributes[attributeKey];\n if (isAttributeValid(attributeKey, attributeValue)) {\n const attributeId = getAttributeId(configObj, attributeKey, logger);\n if (attributeId) {\n commonParams.visitors[0].attributes.push({\n entity_id: attributeId,\n key: attributeKey,\n type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,\n value: attributes[attributeKey],\n });\n }\n }\n });\n }\n\n\n if (typeof botFiltering === 'boolean') {\n commonParams.visitors[0].attributes.push({\n entity_id: CONTROL_ATTRIBUTES.BOT_FILTERING,\n key: CONTROL_ATTRIBUTES.BOT_FILTERING,\n type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,\n value: botFiltering,\n });\n }\n\n return commonParams;\n}\n\n/**\n * Creates object of params specific to impression events\n * @param {ProjectConfig} configObj Object representing project configuration\n * @param {string|null} experimentId ID of experiment for which impression needs to be recorded\n * @param {string|null} variationId ID for variation which would be presented to user\n * @param {string} ruleKey Key of experiment for which impression needs to be recorded\n * @param {string} ruleType Type for the decision source\n * @param {string} flagKey Key for a feature flag\n * @param {boolean} enabled Boolean representing if feature is enabled\n * @return {Snapshot} Impression event params\n */\nfunction getImpressionEventParams(\n configObj: ProjectConfig,\n experimentId: string | null,\n variationId: string | null,\n ruleKey: string,\n ruleType: string,\n flagKey: string,\n enabled: boolean\n): Snapshot {\n\n const campaignId = experimentId ? getLayerId(configObj, experimentId) : null;\n\n let variationKey = variationId ? getVariationKeyFromId(configObj, variationId) : null;\n variationKey = variationKey || '';\n\n const impressionEventParams = {\n decisions: [\n {\n campaign_id: campaignId,\n experiment_id: experimentId,\n variation_id: variationId,\n metadata: {\n flag_key: flagKey,\n rule_key: ruleKey,\n rule_type: ruleType,\n variation_key: variationKey,\n enabled: enabled,\n }\n },\n ],\n events: [\n {\n entity_id: campaignId,\n timestamp: fns.currentTimestamp(),\n key: ACTIVATE_EVENT_KEY,\n uuid: fns.uuid(),\n },\n ],\n };\n\n return impressionEventParams;\n}\n\n/**\n * Creates object of params specific to conversion events\n * @param {ProjectConfig} configObj Object representing project configuration\n * @param {string} eventKey Event key representing the event which needs to be recorded\n * @param {LoggerFacade} logger Logger object\n * @param {EventTags} eventTags Values associated with the event.\n * @return {Snapshot} Conversion event params\n */\nfunction getVisitorSnapshot(\n configObj: ProjectConfig,\n eventKey: string,\n logger: LoggerFacade,\n eventTags?: EventTags,\n): Snapshot {\n const snapshot: Snapshot = {\n events: [],\n };\n\n const eventDict: SnapshotEvent = {\n entity_id: getEventId(configObj, eventKey),\n timestamp: fns.currentTimestamp(),\n uuid: fns.uuid(),\n key: eventKey,\n };\n\n if (eventTags) {\n const revenue = eventTagUtils.getRevenueValue(eventTags, logger);\n if (revenue !== null) {\n eventDict[RESERVED_EVENT_KEYWORDS.REVENUE] = revenue;\n }\n\n const eventValue = eventTagUtils.getEventValue(eventTags, logger);\n if (eventValue !== null) {\n eventDict[RESERVED_EVENT_KEYWORDS.VALUE] = eventValue;\n }\n\n eventDict['tags'] = eventTags;\n }\n snapshot.events.push(eventDict);\n\n return snapshot;\n}\n\n/**\n * Create impression event params to be sent to the logging endpoint\n * @param {ImpressionOptions} options Object containing values needed to build impression event\n * @return {EventLoggingEndpoint} Params to be used in impression event logging endpoint call\n */\nexport function getImpressionEvent(options: ImpressionOptions): EventLoggingEndpoint {\n const commonParams = getCommonEventParams(options);\n const impressionEventParams = getImpressionEventParams(\n options.configObj,\n options.experimentId,\n options.variationId,\n options.ruleKey,\n options.ruleType,\n options.flagKey,\n options.enabled,\n );\n commonParams.visitors[0].snapshots.push(impressionEventParams);\n\n const impressionEvent: EventLoggingEndpoint = {\n httpVerb: HTTP_VERB,\n url: ENDPOINT,\n params: commonParams,\n }\n\n return impressionEvent;\n}\n\n/**\n * Create conversion event params to be sent to the logging endpoint\n * @param {ConversionEventOptions} options Object containing values needed to build conversion event\n * @return {EventLoggingEndpoint} Params to be used in conversion event logging endpoint call\n */\nexport function getConversionEvent(options: ConversionEventOptions): EventLoggingEndpoint {\n\n const commonParams = getCommonEventParams(options);\n const snapshot = getVisitorSnapshot(options.configObj, options.eventKey, options.logger, options.eventTags);\n commonParams.visitors[0].snapshots = [snapshot];\n\n const conversionEvent: EventLoggingEndpoint = {\n httpVerb: HTTP_VERB,\n url: ENDPOINT,\n params: commonParams,\n }\n\n return conversionEvent;\n}\n","/**\n * Copyright 2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DecisionObj } from '../decision_service';\n\n/**\n * Get experiment key from the provided decision object\n * @param {DecisionObj} decisionObj Object representing decision\n * @returns {string} Experiment key or empty string if experiment is null\n */\nexport function getExperimentKey(decisionObj: DecisionObj): string {\n return decisionObj.experiment?.key ?? '';\n}\n\n/**\n * Get variation key from the provided decision object\n * @param {DecisionObj} decisionObj Object representing decision\n * @returns {string} Variation key or empty string if variation is null\n */\nexport function getVariationKey(decisionObj: DecisionObj): string {\n return decisionObj.variation?.key ?? '';\n}\n\n/**\n * Get featureEnabled from variation in the provided decision object\n * @param {DecisionObj} decisionObj Object representing decision\n * @returns {boolean} featureEnabled boolean or false if variation is null\n */\nexport function getFeatureEnabledFromVariation(decisionObj: DecisionObj): boolean {\n return decisionObj.variation?.featureEnabled ?? false;\n}\n\n/**\n * Get experiment id from the provided decision object\n * @param {DecisionObj} decisionObj Object representing decision\n * @returns {string} Experiment id or null if experiment is null\n */\nexport function getExperimentId(decisionObj: DecisionObj): string | null {\n return decisionObj.experiment?.id ?? null;\n}\n\n/**\n * Get variation id from the provided decision object\n * @param {DecisionObj} decisionObj Object representing decision\n * @returns {string} Variation id or null if variation is null\n */\nexport function getVariationId(decisionObj: DecisionObj): string | null {\n return decisionObj.variation?.id ?? null;\n}\n","/**\n * Copyright 2019-2021, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { getLogger } from '@optimizely/js-sdk-logging';\n\nimport fns from '../../utils/fns';\nimport * as eventTagUtils from '../../utils/event_tag_utils';\nimport * as attributesValidator from '../../utils/attributes_validator';\nimport * as decision from '../decision';\n\nimport { EventTags, UserAttributes } from '../../shared_types';\nimport { DecisionObj } from '../decision_service';\nimport {\n getAttributeId,\n getEventId,\n getLayerId,\n ProjectConfig,\n} from '../project_config';\n\nconst logger = getLogger('EVENT_BUILDER');\n\ninterface ImpressionConfig {\n decisionObj: DecisionObj;\n userId: string;\n flagKey: string;\n enabled: boolean;\n userAttributes?: UserAttributes;\n clientEngine: string;\n clientVersion: string;\n configObj: ProjectConfig;\n}\n\ntype VisitorAttribute = {\n entityId: string;\n key: string;\n value: string | number | boolean;\n}\n\ninterface ImpressionEvent {\n type: 'impression';\n timestamp: number;\n uuid: string;\n user: {\n id: string;\n attributes: VisitorAttribute[];\n };\n context: EventContext;\n layer: {\n id: string | null;\n };\n experiment: {\n id: string | null;\n key: string;\n } | null;\n variation: {\n id: string | null;\n key: string;\n } | null;\n\n ruleKey: string,\n flagKey: string,\n ruleType: string,\n enabled: boolean,\n}\n\ntype EventContext = {\n accountId: string;\n projectId: string;\n revision: string;\n clientName: string;\n clientVersion: string;\n anonymizeIP: boolean;\n botFiltering: boolean | undefined;\n}\n\ninterface ConversionConfig {\n eventKey: string;\n eventTags?: EventTags;\n userId: string;\n userAttributes?: UserAttributes;\n clientEngine: string;\n clientVersion: string;\n configObj: ProjectConfig;\n}\n\ninterface ConversionEvent {\n type: 'conversion';\n timestamp: number;\n uuid: string;\n user: {\n id: string;\n attributes: VisitorAttribute[];\n };\n context: EventContext;\n event: {\n id: string | null;\n key: string;\n };\n revenue: number | null;\n value: number | null;\n tags: EventTags | undefined;\n}\n\n\n/**\n * Creates an ImpressionEvent object from decision data\n * @param {ImpressionConfig} config\n * @return {ImpressionEvent} an ImpressionEvent object\n */\nexport const buildImpressionEvent = function({\n configObj,\n decisionObj,\n userId,\n flagKey,\n enabled,\n userAttributes,\n clientEngine,\n clientVersion,\n}: ImpressionConfig): ImpressionEvent {\n\n const ruleType = decisionObj.decisionSource;\n const experimentKey = decision.getExperimentKey(decisionObj);\n const experimentId = decision.getExperimentId(decisionObj);\n const variationKey = decision.getVariationKey(decisionObj);\n const variationId = decision.getVariationId(decisionObj);\n\n const layerId = experimentId !== null ? getLayerId(configObj, experimentId) : null;\n\n return {\n type: 'impression',\n timestamp: fns.currentTimestamp(),\n uuid: fns.uuid(),\n\n user: {\n id: userId,\n attributes: buildVisitorAttributes(configObj, userAttributes),\n },\n\n context: {\n accountId: configObj.accountId,\n projectId: configObj.projectId,\n revision: configObj.revision,\n clientName: clientEngine,\n clientVersion: clientVersion,\n anonymizeIP: configObj.anonymizeIP || false,\n botFiltering: configObj.botFiltering,\n },\n\n layer: {\n id: layerId,\n },\n\n experiment: {\n id: experimentId,\n key: experimentKey,\n },\n\n variation: {\n id: variationId,\n key: variationKey,\n },\n\n ruleKey: experimentKey,\n flagKey: flagKey,\n ruleType: ruleType,\n enabled: enabled,\n };\n};\n\n/**\n * Creates a ConversionEvent object from track\n * @param {ConversionConfig} config\n * @return {ConversionEvent} a ConversionEvent object\n */\nexport const buildConversionEvent = function({\n configObj,\n userId,\n userAttributes,\n clientEngine,\n clientVersion,\n eventKey,\n eventTags,\n}: ConversionConfig): ConversionEvent {\n\n const eventId = getEventId(configObj, eventKey);\n\n const revenue = eventTags ? eventTagUtils.getRevenueValue(eventTags, logger) : null;\n const eventValue = eventTags ? eventTagUtils.getEventValue(eventTags, logger) : null;\n\n return {\n type: 'conversion',\n timestamp: fns.currentTimestamp(),\n uuid: fns.uuid(),\n\n user: {\n id: userId,\n attributes: buildVisitorAttributes(configObj, userAttributes),\n },\n\n context: {\n accountId: configObj.accountId,\n projectId: configObj.projectId,\n revision: configObj.revision,\n clientName: clientEngine,\n clientVersion: clientVersion,\n anonymizeIP: configObj.anonymizeIP || false,\n botFiltering: configObj.botFiltering,\n },\n\n event: {\n id: eventId,\n key: eventKey,\n },\n\n revenue: revenue,\n value: eventValue,\n tags: eventTags,\n };\n};\n\nfunction buildVisitorAttributes(\n configObj: ProjectConfig,\n attributes?: UserAttributes\n): VisitorAttribute[] {\n const builtAttributes: VisitorAttribute[] = [];\n // Omit attribute values that are not supported by the log endpoint.\n if (attributes) {\n Object.keys(attributes || {}).forEach(function(attributeKey) {\n const attributeValue = attributes[attributeKey];\n if (attributesValidator.isAttributeValid(attributeKey, attributeValue)) {\n const attributeId = getAttributeId(configObj, attributeKey, logger);\n if (attributeId) {\n builtAttributes.push({\n entityId: attributeId,\n key: attributeKey,\n value: attributes[attributeKey],\n });\n }\n }\n });\n }\n\n return builtAttributes;\n}\n","/****************************************************************************\n * Copyright 2017, 2020, 2022, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\n\n/**\n * Provides utility method for validating that the given user profile service implementation is valid.\n */\n\nimport { sprintf } from '../../utils/fns';\nimport { ObjectWithUnknownProperties } from '../../shared_types';\n\nimport { ERROR_MESSAGES } from '../enums';\n\nconst MODULE_NAME = 'USER_PROFILE_SERVICE_VALIDATOR';\n\n/**\n * Validates user's provided user profile service instance\n * @param {unknown} userProfileServiceInstance\n * @return {boolean} true if the instance is valid\n * @throws If the instance is not valid\n */\n\nexport function validate(userProfileServiceInstance: unknown): boolean {\n if (typeof userProfileServiceInstance === 'object' && userProfileServiceInstance !== null) {\n if (typeof (userProfileServiceInstance as ObjectWithUnknownProperties)['lookup'] !== 'function') {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME, \"Missing function 'lookup'\"));\n } else if (typeof (userProfileServiceInstance as ObjectWithUnknownProperties)['save'] !== 'function') {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME, \"Missing function 'save'\"));\n }\n return true;\n }\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME));\n}\n","/****************************************************************************\n * Copyright 2020-2022, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\nimport { LoggerFacade, ErrorHandler } from '@optimizely/js-sdk-logging';\nimport { sprintf, objectValues } from '../utils/fns';\nimport { NotificationCenter } from '../core/notification_center';\nimport { EventProcessor } from '@optimizely/js-sdk-event-processor';\n\nimport {\n UserAttributes,\n EventTags,\n OptimizelyConfig,\n OnReadyResult,\n UserProfileService,\n Variation,\n FeatureFlag,\n FeatureVariable,\n OptimizelyOptions,\n OptimizelyDecideOption,\n OptimizelyDecision\n} from '../shared_types';\nimport { newErrorDecision } from '../optimizely_decision';\nimport OptimizelyUserContext from '../optimizely_user_context';\nimport { createProjectConfigManager, ProjectConfigManager } from '../core/project_config/project_config_manager';\nimport { createDecisionService, DecisionService, DecisionObj } from '../core/decision_service';\nimport { getImpressionEvent, getConversionEvent } from '../core/event_builder';\nimport { buildImpressionEvent, buildConversionEvent } from '../core/event_builder/event_helpers';\nimport fns from '../utils/fns'\nimport { validate } from '../utils/attributes_validator';\nimport * as enums from '../utils/enums';\nimport * as eventTagsValidator from '../utils/event_tags_validator';\nimport * as projectConfig from '../core/project_config';\nimport * as userProfileServiceValidator from '../utils/user_profile_service_validator';\nimport * as stringValidator from '../utils/string_value_validator';\nimport * as decision from '../core/decision';\nimport {\n ERROR_MESSAGES,\n LOG_LEVEL,\n LOG_MESSAGES,\n DECISION_SOURCES,\n DECISION_MESSAGES,\n FEATURE_VARIABLE_TYPES,\n DECISION_NOTIFICATION_TYPES,\n NOTIFICATION_TYPES\n} from '../utils/enums';\n\nconst MODULE_NAME = 'OPTIMIZELY';\n\nconst DEFAULT_ONREADY_TIMEOUT = 30000;\n\n// TODO: Make feature_key, user_id, variable_key, experiment_key, event_key camelCase\ntype InputKey = 'feature_key' | 'user_id' | 'variable_key' | 'experiment_key' | 'event_key' | 'variation_id';\n\ntype StringInputs = Partial>;\n\nexport default class Optimizely {\n private isOptimizelyConfigValid: boolean;\n private disposeOnUpdate: (() => void) | null;\n private readyPromise: Promise<{ success: boolean; reason?: string }>;\n // readyTimeout is specified as any to make this work in both browser & Node\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readyTimeouts: { [key: string]: { readyTimeout: any; onClose: () => void } };\n private nextReadyTimeoutId: number;\n private clientEngine: string;\n private clientVersion: string;\n private errorHandler: ErrorHandler;\n private logger: LoggerFacade;\n private projectConfigManager: ProjectConfigManager;\n private decisionService: DecisionService;\n private eventProcessor: EventProcessor;\n private defaultDecideOptions: { [key: string]: boolean };\n public notificationCenter: NotificationCenter;\n\n constructor(config: OptimizelyOptions) {\n let clientEngine = config.clientEngine;\n if (!clientEngine) {\n config.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.INVALID_CLIENT_ENGINE,\n MODULE_NAME,\n clientEngine,\n );\n clientEngine = enums.NODE_CLIENT_ENGINE;\n }\n\n this.clientEngine = clientEngine;\n this.clientVersion = config.clientVersion || enums.NODE_CLIENT_VERSION;\n this.errorHandler = config.errorHandler;\n this.isOptimizelyConfigValid = config.isValidInstance;\n this.logger = config.logger;\n\n let decideOptionsArray = config.defaultDecideOptions ?? [];\n if (!Array.isArray(decideOptionsArray)) {\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.INVALID_DEFAULT_DECIDE_OPTIONS, MODULE_NAME);\n decideOptionsArray = [];\n }\n\n const defaultDecideOptions: { [key: string]: boolean } = {};\n decideOptionsArray.forEach((option) => {\n // Filter out all provided default decide options that are not in OptimizelyDecideOption[]\n if (OptimizelyDecideOption[option]) {\n defaultDecideOptions[option] = true;\n } else {\n this.logger.log(\n LOG_LEVEL.WARNING,\n LOG_MESSAGES.UNRECOGNIZED_DECIDE_OPTION,\n MODULE_NAME,\n option,\n );\n }\n });\n this.defaultDecideOptions = defaultDecideOptions;\n this.projectConfigManager = createProjectConfigManager({\n datafile: config.datafile,\n jsonSchemaValidator: config.jsonSchemaValidator,\n sdkKey: config.sdkKey,\n datafileManager: config.datafileManager\n });\n\n this.disposeOnUpdate = this.projectConfigManager.onUpdate(\n (configObj: projectConfig.ProjectConfig) => {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.UPDATED_OPTIMIZELY_CONFIG,\n MODULE_NAME,\n configObj.revision,\n configObj.projectId,\n );\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.OPTIMIZELY_CONFIG_UPDATE);\n }\n );\n\n const projectConfigManagerReadyPromise = this.projectConfigManager.onReady();\n\n let userProfileService: UserProfileService | null = null;\n if (config.userProfileService) {\n try {\n if (userProfileServiceValidator.validate(config.userProfileService)) {\n userProfileService = config.userProfileService;\n this.logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.VALID_USER_PROFILE_SERVICE, MODULE_NAME);\n }\n } catch (ex) {\n this.logger.log(LOG_LEVEL.WARNING, ex.message);\n }\n }\n\n this.decisionService = createDecisionService({\n userProfileService: userProfileService,\n logger: this.logger,\n UNSTABLE_conditionEvaluators: config.UNSTABLE_conditionEvaluators,\n });\n\n this.notificationCenter = config.notificationCenter;\n\n this.eventProcessor = config.eventProcessor;\n\n const eventProcessorStartedPromise = this.eventProcessor.start();\n\n this.readyPromise = Promise.all([projectConfigManagerReadyPromise, eventProcessorStartedPromise]).then(function(promiseResults) {\n // Only return status from project config promise because event processor promise does not return any status.\n return promiseResults[0];\n })\n\n this.readyTimeouts = {};\n this.nextReadyTimeoutId = 0;\n }\n\n /**\n * Returns a truthy value if this instance currently has a valid project config\n * object, and the initial configuration object that was passed into the\n * constructor was also valid.\n * @return {boolean}\n */\n isValidInstance(): boolean {\n return this.isOptimizelyConfigValid && !!this.projectConfigManager.getConfig();\n }\n\n /**\n * Buckets visitor and sends impression event to Optimizely.\n * @param {string} experimentKey\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @return {string|null} variation key\n */\n activate(experimentKey: string, userId: string, attributes?: UserAttributes): string | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'activate');\n return null;\n }\n\n if (!this.validateInputs({ experiment_key: experimentKey, user_id: userId }, attributes)) {\n return this.notActivatingExperiment(experimentKey, userId);\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n\n try {\n const variationKey = this.getVariation(experimentKey, userId, attributes);\n if (variationKey === null) {\n return this.notActivatingExperiment(experimentKey, userId);\n }\n\n // If experiment is not set to 'Running' status, log accordingly and return variation key\n if (!projectConfig.isRunning(configObj, experimentKey)) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n LOG_MESSAGES.SHOULD_NOT_DISPATCH_ACTIVATE,\n MODULE_NAME,\n experimentKey,\n );\n return variationKey;\n }\n\n const experiment = projectConfig.getExperimentFromKey(configObj, experimentKey);\n const variation = experiment.variationKeyMap[variationKey];\n const decisionObj = {\n experiment: experiment,\n variation: variation,\n decisionSource: enums.DECISION_SOURCES.EXPERIMENT\n }\n\n this.sendImpressionEvent(\n decisionObj,\n '',\n userId,\n true,\n attributes\n );\n return variationKey;\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.NOT_ACTIVATING_USER,\n MODULE_NAME,\n userId,\n experimentKey,\n );\n this.errorHandler.handleError(ex);\n return null;\n }\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Create an impression event and call the event dispatcher's dispatch method to\n * send this event to Optimizely. Then use the notification center to trigger\n * any notification listeners for the ACTIVATE notification type.\n * @param {DecisionObj} decisionObj Decision Object\n * @param {string} flagKey Key for a feature flag\n * @param {string} userId ID of user to whom the variation was shown\n * @param {UserAttributes} attributes Optional user attributes\n * @param {boolean} enabled Boolean representing if feature is enabled\n */\n private sendImpressionEvent(\n decisionObj: DecisionObj,\n flagKey: string,\n userId: string,\n enabled: boolean,\n attributes?: UserAttributes,\n ): void {\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return;\n }\n const impressionEvent = buildImpressionEvent({\n decisionObj: decisionObj,\n flagKey: flagKey,\n enabled: enabled,\n userId: userId,\n userAttributes: attributes,\n clientEngine: this.clientEngine,\n clientVersion: this.clientVersion,\n configObj: configObj,\n });\n // TODO is it okay to not pass a projectConfig as second argument\n this.eventProcessor.process(impressionEvent);\n this.emitNotificationCenterActivate(decisionObj, flagKey, userId, enabled, attributes);\n }\n\n /**\n * Emit the ACTIVATE notification on the notificationCenter\n * @param {DecisionObj} decisionObj Decision object\n * @param {string} flagKey Key for a feature flag\n * @param {string} userId ID of user to whom the variation was shown\n * @param {boolean} enabled Boolean representing if feature is enabled\n * @param {UserAttributes} attributes Optional user attributes\n */\n private emitNotificationCenterActivate(\n decisionObj: DecisionObj,\n flagKey: string,\n userId: string,\n enabled: boolean,\n attributes?: UserAttributes\n ): void {\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return;\n }\n\n const ruleType = decisionObj.decisionSource;\n const experimentKey = decision.getExperimentKey(decisionObj);\n const experimentId = decision.getExperimentId(decisionObj);\n const variationKey = decision.getVariationKey(decisionObj);\n const variationId = decision.getVariationId(decisionObj);\n\n let experiment;\n\n if (experimentId !== null && variationKey !== '') {\n experiment = configObj.experimentIdMap[experimentId];\n }\n\n const impressionEventOptions = {\n attributes: attributes,\n clientEngine: this.clientEngine,\n clientVersion: this.clientVersion,\n configObj: configObj,\n experimentId: experimentId,\n ruleKey: experimentKey,\n flagKey: flagKey,\n ruleType: ruleType,\n userId: userId,\n enabled: enabled,\n variationId: variationId,\n logger: this.logger,\n };\n const impressionEvent = getImpressionEvent(impressionEventOptions);\n let variation;\n if (experiment && experiment.variationKeyMap && variationKey !== '') {\n variation = experiment.variationKeyMap[variationKey];\n }\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.ACTIVATE, {\n experiment: experiment,\n userId: userId,\n attributes: attributes,\n variation: variation,\n logEvent: impressionEvent,\n });\n }\n\n /**\n * Sends conversion event to Optimizely.\n * @param {string} eventKey\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @param {EventTags} eventTags Values associated with the event.\n */\n track(eventKey: string, userId: string, attributes?: UserAttributes, eventTags?: EventTags): void {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'track');\n return;\n }\n\n if (!this.validateInputs({ user_id: userId, event_key: eventKey }, attributes, eventTags)) {\n return;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return;\n }\n\n if (!projectConfig.eventWithKeyExists(configObj, eventKey)) {\n this.logger.log(\n LOG_LEVEL.WARNING,\n enums.LOG_MESSAGES.EVENT_KEY_NOT_FOUND,\n MODULE_NAME,\n eventKey,\n );\n this.logger.log(LOG_LEVEL.WARNING, LOG_MESSAGES.NOT_TRACKING_USER, MODULE_NAME, userId);\n return;\n }\n\n // remove null values from eventTags\n eventTags = this.filterEmptyValues(eventTags);\n const conversionEvent = buildConversionEvent({\n eventKey: eventKey,\n eventTags: eventTags,\n userId: userId,\n userAttributes: attributes,\n clientEngine: this.clientEngine,\n clientVersion: this.clientVersion,\n configObj: configObj,\n });\n this.logger.log(LOG_LEVEL.INFO, enums.LOG_MESSAGES.TRACK_EVENT, MODULE_NAME, eventKey, userId);\n // TODO is it okay to not pass a projectConfig as second argument\n this.eventProcessor.process(conversionEvent);\n this.emitNotificationCenterTrack(eventKey, userId, attributes, eventTags);\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.NOT_TRACKING_USER, MODULE_NAME, userId);\n }\n }\n /**\n * Send TRACK event to notificationCenter\n * @param {string} eventKey\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @param {EventTags} eventTags Values associated with the event.\n */\n private emitNotificationCenterTrack(eventKey: string, userId: string, attributes?: UserAttributes, eventTags?: EventTags): void {\n try {\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return;\n }\n\n const conversionEventOptions = {\n attributes: attributes,\n clientEngine: this.clientEngine,\n clientVersion: this.clientVersion,\n configObj: configObj,\n eventKey: eventKey,\n eventTags: eventTags,\n logger: this.logger,\n userId: userId,\n };\n const conversionEvent = getConversionEvent(conversionEventOptions);\n\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.TRACK, {\n eventKey: eventKey,\n userId: userId,\n attributes: attributes,\n eventTags: eventTags,\n logEvent: conversionEvent,\n });\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n this.errorHandler.handleError(ex);\n }\n }\n\n /**\n * Gets variation where visitor will be bucketed.\n * @param {string} experimentKey\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @return {string|null} variation key\n */\n getVariation(experimentKey: string, userId: string, attributes?: UserAttributes): string | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getVariation');\n return null;\n }\n\n try {\n if (!this.validateInputs({ experiment_key: experimentKey, user_id: userId }, attributes)) {\n return null;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n\n const experiment = configObj.experimentKeyMap[experimentKey];\n if (!experiment) {\n this.logger.log(\n LOG_LEVEL.DEBUG,\n ERROR_MESSAGES.INVALID_EXPERIMENT_KEY,\n MODULE_NAME,\n experimentKey,\n );\n return null;\n }\n\n const variationKey = this.decisionService.getVariation(\n configObj,\n experiment,\n this.createUserContext(userId, attributes) as OptimizelyUserContext\n ).result;\n const decisionNotificationType = projectConfig.isFeatureExperiment(configObj, experiment.id)\n ? DECISION_NOTIFICATION_TYPES.FEATURE_TEST\n : DECISION_NOTIFICATION_TYPES.AB_TEST;\n\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.DECISION, {\n type: decisionNotificationType,\n userId: userId,\n attributes: attributes || {},\n decisionInfo: {\n experimentKey: experimentKey,\n variationKey: variationKey,\n },\n });\n\n return variationKey;\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n this.errorHandler.handleError(ex);\n return null;\n }\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Force a user into a variation for a given experiment.\n * @param {string} experimentKey\n * @param {string} userId\n * @param {string|null} variationKey user will be forced into. If null,\n * then clear the existing experiment-to-variation mapping.\n * @return {boolean} A boolean value that indicates if the set completed successfully.\n */\n setForcedVariation(experimentKey: string, userId: string, variationKey: string | null): boolean {\n if (!this.validateInputs({ experiment_key: experimentKey, user_id: userId })) {\n return false;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return false;\n }\n\n try {\n return this.decisionService.setForcedVariation(configObj, experimentKey, userId, variationKey);\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n this.errorHandler.handleError(ex);\n return false;\n }\n }\n\n /**\n * Gets the forced variation for a given user and experiment.\n * @param {string} experimentKey\n * @param {string} userId\n * @return {string|null} The forced variation key.\n */\n getForcedVariation(experimentKey: string, userId: string): string | null {\n if (!this.validateInputs({ experiment_key: experimentKey, user_id: userId })) {\n return null;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n\n try {\n return this.decisionService.getForcedVariation(configObj, experimentKey, userId).result;\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n this.errorHandler.handleError(ex);\n return null;\n }\n }\n\n /**\n * Validate string inputs, user attributes and event tags.\n * @param {StringInputs} stringInputs Map of string keys and associated values\n * @param {unknown} userAttributes Optional parameter for user's attributes\n * @param {unknown} eventTags Optional parameter for event tags\n * @return {boolean} True if inputs are valid\n *\n */\n private validateInputs(\n stringInputs: StringInputs,\n userAttributes?: unknown,\n eventTags?: unknown\n ): boolean {\n try {\n if (stringInputs.hasOwnProperty('user_id')) {\n const userId = stringInputs['user_id'];\n if (typeof userId !== 'string' || userId === null || userId === 'undefined') {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_INPUT_FORMAT, MODULE_NAME, 'user_id'));\n }\n\n delete stringInputs['user_id'];\n }\n Object.keys(stringInputs).forEach(key => {\n if (!stringValidator.validate(stringInputs[key as InputKey])) {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_INPUT_FORMAT, MODULE_NAME, key));\n }\n })\n if (userAttributes) {\n validate(userAttributes);\n }\n if (eventTags) {\n eventTagsValidator.validate(eventTags);\n }\n return true;\n\n } catch (ex) {\n this.logger.log(LOG_LEVEL.ERROR, ex.message);\n this.errorHandler.handleError(ex);\n return false;\n }\n\n }\n\n /**\n * Shows failed activation log message and returns null when user is not activated in experiment\n * @param {string} experimentKey\n * @param {string} userId\n * @return {null}\n */\n private notActivatingExperiment(experimentKey: string, userId: string): null {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.NOT_ACTIVATING_USER,\n MODULE_NAME,\n userId,\n experimentKey,\n );\n return null;\n }\n\n /**\n * Filters out attributes/eventTags with null or undefined values\n * @param {EventTags | undefined} map\n * @returns {EventTags | undefined}\n */\n private filterEmptyValues(map: EventTags | undefined): EventTags | undefined {\n for (const key in map) {\n if (map.hasOwnProperty(key) && (map[key] === null || map[key] === undefined)) {\n delete map[key];\n }\n }\n return map;\n }\n\n /**\n * Returns true if the feature is enabled for the given user.\n * @param {string} featureKey Key of feature which will be checked\n * @param {string} userId ID of user which will be checked\n * @param {UserAttributes} attributes Optional user attributes\n * @return {boolean} true if the feature is enabled for the user, false otherwise\n */\n isFeatureEnabled(featureKey: string, userId: string, attributes?: UserAttributes): boolean {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n LOG_MESSAGES.INVALID_OBJECT,\n MODULE_NAME,\n 'isFeatureEnabled',\n );\n return false;\n }\n\n if (!this.validateInputs({ feature_key: featureKey, user_id: userId }, attributes)) {\n return false;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return false;\n }\n\n const feature = projectConfig.getFeatureFromKey(configObj, featureKey, this.logger);\n if (!feature) {\n return false;\n }\n\n let sourceInfo = {};\n const user = this.createUserContext(userId, attributes) as OptimizelyUserContext;\n const decisionObj = this.decisionService.getVariationForFeature(configObj, feature, user).result;\n const decisionSource = decisionObj.decisionSource;\n const experimentKey = decision.getExperimentKey(decisionObj);\n const variationKey = decision.getVariationKey(decisionObj);\n\n let featureEnabled = decision.getFeatureEnabledFromVariation(decisionObj);\n\n if (decisionSource === DECISION_SOURCES.FEATURE_TEST) {\n sourceInfo = {\n experimentKey: experimentKey,\n variationKey: variationKey,\n };\n }\n\n if (\n decisionSource === DECISION_SOURCES.FEATURE_TEST ||\n decisionSource === DECISION_SOURCES.ROLLOUT && projectConfig.getSendFlagDecisionsValue(configObj)\n ) {\n this.sendImpressionEvent(\n decisionObj,\n feature.key,\n userId,\n featureEnabled,\n attributes\n );\n }\n\n if (featureEnabled === true) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.FEATURE_ENABLED_FOR_USER,\n MODULE_NAME,\n featureKey,\n userId,\n );\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.FEATURE_NOT_ENABLED_FOR_USER,\n MODULE_NAME,\n featureKey,\n userId,\n );\n featureEnabled = false;\n }\n\n const featureInfo = {\n featureKey: featureKey,\n featureEnabled: featureEnabled,\n source: decisionObj.decisionSource,\n sourceInfo: sourceInfo,\n };\n\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.DECISION, {\n type: DECISION_NOTIFICATION_TYPES.FEATURE,\n userId: userId,\n attributes: attributes || {},\n decisionInfo: featureInfo,\n });\n\n return featureEnabled;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return false;\n }\n }\n\n /**\n * Returns an Array containing the keys of all features in the project that are\n * enabled for the given user.\n * @param {string} userId\n * @param {UserAttributes} attributes\n * @return {string[]} Array of feature keys (strings)\n */\n getEnabledFeatures(userId: string, attributes?: UserAttributes): string[] {\n try {\n const enabledFeatures: string[] = [];\n if (!this.isValidInstance()) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n LOG_MESSAGES.INVALID_OBJECT,\n MODULE_NAME,\n 'getEnabledFeatures',\n );\n return enabledFeatures;\n }\n\n if (!this.validateInputs({ user_id: userId })) {\n return enabledFeatures;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return enabledFeatures;\n }\n\n objectValues(configObj.featureKeyMap).forEach(\n (feature: FeatureFlag) => {\n if (this.isFeatureEnabled(feature.key, userId, attributes)) {\n enabledFeatures.push(feature.key);\n }\n }\n );\n\n return enabledFeatures;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return [];\n }\n }\n\n /**\n * Returns dynamically-typed value of the variable attached to the given\n * feature flag. Returns null if the feature key or variable key is invalid.\n *\n * @param {string} featureKey Key of the feature whose variable's\n * value is being accessed\n * @param {string} variableKey Key of the variable whose value is\n * being accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {unknown} Value of the variable cast to the appropriate\n * type, or null if the feature key is invalid or\n * the variable key is invalid\n */\n getFeatureVariable(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): unknown {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getFeatureVariable');\n return null;\n }\n return this.getFeatureVariableForType(featureKey, variableKey, null, userId, attributes);\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Helper method to get the value for a variable of a certain type attached to a\n * feature flag. Returns null if the feature key is invalid, the variable key is\n * invalid, the given variable type does not match the variable's actual type,\n * or the variable value cannot be cast to the required type. If the given variable\n * type is null, the value of the variable cast to the appropriate type is returned.\n *\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {string} variableKey Key of the variable whose value is being\n * accessed\n * @param {string|null} variableType Type of the variable whose value is being\n * accessed (must be one of FEATURE_VARIABLE_TYPES\n * in lib/utils/enums/index.js), or null to return the\n * value of the variable cast to the appropriate type\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {unknown} Value of the variable cast to the appropriate\n * type, or null if the feature key is invalid, thevariable\n * key is invalid, or there is a mismatch with the type of\n * the variable\n */\n private getFeatureVariableForType(\n featureKey: string,\n variableKey: string,\n variableType: string | null,\n userId: string,\n attributes?: UserAttributes): unknown {\n if (!this.validateInputs({ feature_key: featureKey, variable_key: variableKey, user_id: userId }, attributes)) {\n return null;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n\n const featureFlag = projectConfig.getFeatureFromKey(configObj, featureKey, this.logger);\n if (!featureFlag) {\n return null;\n }\n\n const variable = projectConfig.getVariableForFeature(configObj, featureKey, variableKey, this.logger);\n if (!variable) {\n return null;\n }\n\n if (variableType && variable.type !== variableType) {\n this.logger.log(\n LOG_LEVEL.WARNING,\n LOG_MESSAGES.VARIABLE_REQUESTED_WITH_WRONG_TYPE,\n MODULE_NAME,\n variableType,\n variable.type,\n );\n return null;\n }\n\n const user = this.createUserContext(userId, attributes) as OptimizelyUserContext;\n const decisionObj = this.decisionService.getVariationForFeature(configObj, featureFlag, user).result;\n const featureEnabled = decision.getFeatureEnabledFromVariation(decisionObj);\n const variableValue = this.getFeatureVariableValueFromVariation(featureKey, featureEnabled, decisionObj.variation, variable, userId);\n let sourceInfo = {};\n if (\n decisionObj.decisionSource === DECISION_SOURCES.FEATURE_TEST &&\n decisionObj.experiment !== null &&\n decisionObj.variation !== null\n ) {\n sourceInfo = {\n experimentKey: decisionObj.experiment.key,\n variationKey: decisionObj.variation.key,\n };\n }\n\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.DECISION, {\n type: DECISION_NOTIFICATION_TYPES.FEATURE_VARIABLE,\n userId: userId,\n attributes: attributes || {},\n decisionInfo: {\n featureKey: featureKey,\n featureEnabled: featureEnabled,\n source: decisionObj.decisionSource,\n variableKey: variableKey,\n variableValue: variableValue,\n variableType: variable.type,\n sourceInfo: sourceInfo,\n },\n });\n return variableValue;\n }\n\n /**\n * Helper method to get the non type-casted value for a variable attached to a\n * feature flag. Returns appropriate variable value depending on whether there\n * was a matching variation, feature was enabled or not or varible was part of the\n * available variation or not. Also logs the appropriate message explaining how it\n * evaluated the value of the variable.\n *\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {boolean} featureEnabled Boolean indicating if feature is enabled or not\n * @param {Variation} variation variation returned by decision service\n * @param {FeatureVariable} variable varible whose value is being evaluated\n * @param {string} userId ID for the user\n * @return {unknown} Value of the variable or null if the\n * config Obj is null\n */\n private getFeatureVariableValueFromVariation(\n featureKey: string,\n featureEnabled: boolean,\n variation: Variation | null,\n variable: FeatureVariable,\n userId: string\n ): unknown {\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n\n let variableValue = variable.defaultValue;\n if (variation !== null) {\n const value = projectConfig.getVariableValueForVariation(configObj, variable, variation, this.logger);\n if (value !== null) {\n if (featureEnabled) {\n variableValue = value;\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_RECEIVED_VARIABLE_VALUE,\n MODULE_NAME,\n variableValue,\n variable.key,\n featureKey,\n );\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.FEATURE_NOT_ENABLED_RETURN_DEFAULT_VARIABLE_VALUE,\n MODULE_NAME,\n featureKey,\n userId,\n variableValue,\n );\n }\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.VARIABLE_NOT_USED_RETURN_DEFAULT_VARIABLE_VALUE,\n MODULE_NAME,\n variable.key,\n variation.key,\n );\n }\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.USER_RECEIVED_DEFAULT_VARIABLE_VALUE,\n MODULE_NAME,\n userId,\n variable.key,\n featureKey,\n );\n }\n\n return projectConfig.getTypeCastValue(variableValue, variable.type, this.logger);\n }\n\n /**\n * Returns value for the given boolean variable attached to the given feature\n * flag.\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {string} variableKey Key of the variable whose value is being\n * accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {boolean|null} Boolean value of the variable, or null if the\n * feature key is invalid, the variable key is invalid,\n * or there is a mismatch with the type of the variable.\n */\n getFeatureVariableBoolean(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): boolean | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getFeatureVariableBoolean');\n return null;\n }\n return this.getFeatureVariableForType(featureKey, variableKey, FEATURE_VARIABLE_TYPES.BOOLEAN, userId, attributes) as boolean | null;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Returns value for the given double variable attached to the given feature\n * flag.\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {string} variableKey Key of the variable whose value is being\n * accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {number|null} Number value of the variable, or null if the\n * feature key is invalid, the variable key is\n * invalid, or there is a mismatch with the type\n * of the variable\n */\n getFeatureVariableDouble(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): number | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getFeatureVariableDouble');\n return null;\n }\n return this.getFeatureVariableForType(featureKey, variableKey, FEATURE_VARIABLE_TYPES.DOUBLE, userId, attributes) as number | null;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Returns value for the given integer variable attached to the given feature\n * flag.\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {string} variableKey Key of the variable whose value is being\n * accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {number|null} Number value of the variable, or null if the\n * feature key is invalid, the variable key is\n * invalid, or there is a mismatch with the type\n * of the variable\n */\n getFeatureVariableInteger(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): number | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getFeatureVariableInteger');\n return null;\n }\n return this.getFeatureVariableForType(featureKey, variableKey, FEATURE_VARIABLE_TYPES.INTEGER, userId, attributes) as number | null;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Returns value for the given string variable attached to the given feature\n * flag.\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {string} variableKey Key of the variable whose value is being\n * accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {string|null} String value of the variable, or null if the\n * feature key is invalid, the variable key is\n * invalid, or there is a mismatch with the type\n * of the variable\n */\n getFeatureVariableString(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes?: UserAttributes\n ): string | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getFeatureVariableString');\n return null;\n }\n return this.getFeatureVariableForType(featureKey, variableKey, FEATURE_VARIABLE_TYPES.STRING, userId, attributes) as string | null;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Returns value for the given json variable attached to the given feature\n * flag.\n * @param {string} featureKey Key of the feature whose variable's value is\n * being accessed\n * @param {string} variableKey Key of the variable whose value is being\n * accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {unknown} Object value of the variable, or null if the\n * feature key is invalid, the variable key is\n * invalid, or there is a mismatch with the type\n * of the variable\n */\n getFeatureVariableJSON(\n featureKey: string,\n variableKey: string,\n userId: string,\n attributes: UserAttributes\n ): unknown {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getFeatureVariableJSON');\n return null;\n }\n return this.getFeatureVariableForType(featureKey, variableKey, FEATURE_VARIABLE_TYPES.JSON, userId, attributes);\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Returns values for all the variables attached to the given feature\n * flag.\n * @param {string} featureKey Key of the feature whose variables are being\n * accessed\n * @param {string} userId ID for the user\n * @param {UserAttributes} attributes Optional user attributes\n * @return {object|null} Object containing all the variables, or null if the\n * feature key is invalid\n */\n getAllFeatureVariables(\n featureKey: string,\n userId: string,\n attributes?: UserAttributes\n ): { [variableKey: string]: unknown } | null {\n try {\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'getAllFeatureVariables');\n return null;\n }\n\n if (!this.validateInputs({ feature_key: featureKey, user_id: userId }, attributes)) {\n return null;\n }\n\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n\n const featureFlag = projectConfig.getFeatureFromKey(configObj, featureKey, this.logger);\n if (!featureFlag) {\n return null;\n }\n\n const user = this.createUserContext(userId, attributes) as OptimizelyUserContext;\n\n const decisionObj = this.decisionService.getVariationForFeature(configObj, featureFlag, user).result;\n const featureEnabled = decision.getFeatureEnabledFromVariation(decisionObj);\n const allVariables: { [variableKey: string]: unknown } = {};\n\n featureFlag.variables.forEach((variable: FeatureVariable) => {\n allVariables[variable.key] = this.getFeatureVariableValueFromVariation(featureKey, featureEnabled, decisionObj.variation, variable, userId);\n });\n\n let sourceInfo = {};\n if (decisionObj.decisionSource === DECISION_SOURCES.FEATURE_TEST &&\n decisionObj.experiment !== null &&\n decisionObj.variation !== null\n ) {\n sourceInfo = {\n experimentKey: decisionObj.experiment.key,\n variationKey: decisionObj.variation.key,\n };\n }\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.DECISION, {\n type: DECISION_NOTIFICATION_TYPES.ALL_FEATURE_VARIABLES,\n userId: userId,\n attributes: attributes || {},\n decisionInfo: {\n featureKey: featureKey,\n featureEnabled: featureEnabled,\n source: decisionObj.decisionSource,\n variableValues: allVariables,\n sourceInfo: sourceInfo,\n },\n });\n\n return allVariables;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Returns OptimizelyConfig object containing experiments and features data\n * @return {OptimizelyConfig|null}\n *\n * OptimizelyConfig Object Schema\n * {\n * 'experimentsMap': {\n * 'my-fist-experiment': {\n * 'id': '111111',\n * 'key': 'my-fist-experiment'\n * 'variationsMap': {\n * 'variation_1': {\n * 'id': '121212',\n * 'key': 'variation_1',\n * 'variablesMap': {\n * 'age': {\n * 'id': '222222',\n * 'key': 'age',\n * 'type': 'integer',\n * 'value': '0',\n * }\n * }\n * }\n * }\n * }\n * },\n * 'featuresMap': {\n * 'awesome-feature': {\n * 'id': '333333',\n * 'key': 'awesome-feature',\n * 'experimentsMap': Object,\n * 'variationsMap': Object,\n * }\n * }\n * }\n */\n getOptimizelyConfig(): OptimizelyConfig | null {\n try {\n const configObj = this.projectConfigManager.getConfig();\n if (!configObj) {\n return null;\n }\n return this.projectConfigManager.getOptimizelyConfig();\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return null;\n }\n }\n\n /**\n * Stop background processes belonging to this instance, including:\n *\n * - Active datafile requests\n * - Pending datafile requests\n * - Pending event queue flushes\n *\n * In-flight datafile requests will be aborted. Any events waiting to be sent\n * as part of a batched event request will be immediately flushed to the event\n * dispatcher.\n *\n * Returns a Promise that fulfills after all in-flight event dispatcher requests\n * (including any final request resulting from flushing the queue as described\n * above) are complete. If there are no in-flight event dispatcher requests and\n * no queued events waiting to be sent, returns an immediately-fulfilled Promise.\n *\n * Returned Promises are fulfilled with result objects containing these\n * properties:\n * - success (boolean): true if the event dispatcher signaled completion of\n * all in-flight and final requests, or if there were no\n * queued events and no in-flight requests. false if an\n * unexpected error was encountered during the close\n * process.\n * - reason (string=): If success is false, this is a string property with\n * an explanatory message.\n *\n * NOTE: After close is called, this instance is no longer usable - any events\n * generated will no longer be sent to the event dispatcher.\n *\n * @return {Promise}\n */\n close(): Promise<{ success: boolean; reason?: string }> {\n try {\n const eventProcessorStoppedPromise = this.eventProcessor.stop();\n if (this.disposeOnUpdate) {\n this.disposeOnUpdate();\n this.disposeOnUpdate = null;\n }\n if (this.projectConfigManager) {\n this.projectConfigManager.stop();\n }\n Object.keys(this.readyTimeouts).forEach(\n (readyTimeoutId: string) => {\n const readyTimeoutRecord = this.readyTimeouts[readyTimeoutId];\n clearTimeout(readyTimeoutRecord.readyTimeout);\n readyTimeoutRecord.onClose();\n }\n );\n this.readyTimeouts = {};\n return eventProcessorStoppedPromise.then(\n function() {\n return {\n success: true,\n };\n },\n function(err) {\n return {\n success: false,\n reason: String(err),\n };\n }\n );\n } catch (err) {\n this.logger.log(LOG_LEVEL.ERROR, err.message);\n this.errorHandler.handleError(err);\n return Promise.resolve({\n success: false,\n reason: String(err),\n });\n }\n }\n\n /**\n * Returns a Promise that fulfills when this instance is ready to use (meaning\n * it has a valid datafile), or has failed to become ready within a period of\n * time (configurable by the timeout property of the options argument), or when\n * this instance is closed via the close method.\n *\n * If a valid datafile was provided in the constructor, the returned Promise is\n * immediately fulfilled. If an sdkKey was provided, a manager will be used to\n * fetch a datafile, and the returned promise will fulfill if that fetch\n * succeeds or fails before the timeout. The default timeout is 30 seconds,\n * which will be used if no timeout is provided in the argument options object.\n *\n * The returned Promise is fulfilled with a result object containing these\n * properties:\n * - success (boolean): True if this instance is ready to use with a valid\n * datafile, or false if this instance failed to become\n * ready or was closed prior to becoming ready.\n * - reason (string=): If success is false, this is a string property with\n * an explanatory message. Failure could be due to\n * expiration of the timeout, network errors,\n * unsuccessful responses, datafile parse errors,\n * datafile validation errors, or the instance being\n * closed\n * @param {Object=} options\n * @param {number|undefined} options.timeout\n * @return {Promise}\n */\n onReady(options?: { timeout?: number }): Promise {\n let timeoutValue: number | undefined;\n if (typeof options === 'object' && options !== null) {\n if (options.timeout !== undefined) {\n timeoutValue = options.timeout;\n }\n }\n if (!fns.isSafeInteger(timeoutValue)) {\n timeoutValue = DEFAULT_ONREADY_TIMEOUT;\n }\n\n let resolveTimeoutPromise: (value: OnReadyResult) => void;\n const timeoutPromise = new Promise(\n (resolve) => {\n resolveTimeoutPromise = resolve;\n }\n );\n\n const timeoutId = this.nextReadyTimeoutId;\n this.nextReadyTimeoutId++;\n\n const onReadyTimeout = (() => {\n delete this.readyTimeouts[timeoutId];\n resolveTimeoutPromise({\n success: false,\n reason: sprintf('onReady timeout expired after %s ms', timeoutValue),\n });\n });\n const readyTimeout = setTimeout(onReadyTimeout, timeoutValue);\n const onClose = function() {\n resolveTimeoutPromise({\n success: false,\n reason: 'Instance closed',\n });\n };\n\n this.readyTimeouts[timeoutId] = {\n readyTimeout: readyTimeout,\n onClose: onClose,\n };\n\n this.readyPromise.then(() => {\n clearTimeout(readyTimeout);\n delete this.readyTimeouts[timeoutId];\n resolveTimeoutPromise({\n success: true,\n });\n });\n\n return Promise.race([this.readyPromise, timeoutPromise]);\n }\n\n //============ decide ============//\n\n /**\n * Creates a context of the user for which decision APIs will be called.\n *\n * A user context will be created successfully even when the SDK is not fully configured yet, so no\n * this.isValidInstance() check is performed here.\n *\n * @param {string} userId The user ID to be used for bucketing.\n * @param {UserAttributes} attributes Optional user attributes.\n * @return {OptimizelyUserContext|null} An OptimizelyUserContext associated with this OptimizelyClient or\n * null if provided inputs are invalid\n */\n createUserContext(userId: string, attributes?: UserAttributes): OptimizelyUserContext | null {\n if (!this.validateInputs({ user_id: userId }, attributes)) {\n return null;\n }\n\n return new OptimizelyUserContext({\n optimizely: this,\n userId,\n attributes\n });\n }\n\n decide(\n user: OptimizelyUserContext,\n key: string,\n options: OptimizelyDecideOption[] = []\n ): OptimizelyDecision {\n const userId = user.getUserId();\n const attributes = user.getAttributes();\n const configObj = this.projectConfigManager.getConfig();\n const reasons: (string | number)[][] = [];\n let decisionObj: DecisionObj;\n if (!this.isValidInstance() || !configObj) {\n this.logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'decide');\n return newErrorDecision(key, user, [DECISION_MESSAGES.SDK_NOT_READY]);\n }\n\n const feature = configObj.featureKeyMap[key];\n if (!feature) {\n this.logger.log(LOG_LEVEL.ERROR, ERROR_MESSAGES.FEATURE_NOT_IN_DATAFILE, MODULE_NAME, key);\n return newErrorDecision(key, user, [sprintf(DECISION_MESSAGES.FLAG_KEY_INVALID, key)]);\n }\n\n const allDecideOptions = this.getAllDecideOptions(options);\n\n const forcedDecisionResponse = this.decisionService.findValidatedForcedDecision(configObj, user, key);\n reasons.push(...forcedDecisionResponse.reasons);\n const variation = forcedDecisionResponse.result;\n if (variation) {\n decisionObj = {\n experiment: null,\n variation: variation,\n decisionSource: DECISION_SOURCES.FEATURE_TEST\n }\n } else {\n const decisionVariation = this.decisionService.getVariationForFeature(\n configObj,\n feature,\n user,\n allDecideOptions,\n );\n reasons.push(...decisionVariation.reasons);\n decisionObj = decisionVariation.result;\n }\n const decisionSource = decisionObj.decisionSource;\n const experimentKey = decisionObj.experiment?.key ?? null;\n const variationKey = decisionObj.variation?.key ?? null;\n const flagEnabled: boolean = decision.getFeatureEnabledFromVariation(decisionObj);\n if (flagEnabled === true) {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.FEATURE_ENABLED_FOR_USER,\n MODULE_NAME,\n key,\n userId,\n );\n } else {\n this.logger.log(\n LOG_LEVEL.INFO,\n LOG_MESSAGES.FEATURE_NOT_ENABLED_FOR_USER,\n MODULE_NAME,\n key,\n userId,\n );\n }\n\n const variablesMap: { [key: string]: unknown } = {};\n let decisionEventDispatched = false;\n\n if (!allDecideOptions[OptimizelyDecideOption.EXCLUDE_VARIABLES]) {\n feature.variables.forEach(variable => {\n variablesMap[variable.key] =\n this.getFeatureVariableValueFromVariation(\n key,\n flagEnabled,\n decisionObj.variation,\n variable,\n userId\n );\n });\n }\n\n if (\n !allDecideOptions[OptimizelyDecideOption.DISABLE_DECISION_EVENT] && (\n decisionSource === DECISION_SOURCES.FEATURE_TEST ||\n decisionSource === DECISION_SOURCES.ROLLOUT && projectConfig.getSendFlagDecisionsValue(configObj))\n ) {\n this.sendImpressionEvent(\n decisionObj,\n key,\n userId,\n flagEnabled,\n attributes\n )\n decisionEventDispatched = true;\n }\n\n const shouldIncludeReasons = allDecideOptions[OptimizelyDecideOption.INCLUDE_REASONS];\n\n let reportedReasons: string[] = [];\n if (shouldIncludeReasons) {\n reportedReasons = reasons.map((reason) => sprintf(reason[0] as string, ...reason.slice(1)));\n }\n\n const featureInfo = {\n flagKey: key,\n enabled: flagEnabled,\n variationKey: variationKey,\n ruleKey: experimentKey,\n variables: variablesMap,\n reasons: reportedReasons,\n decisionEventDispatched: decisionEventDispatched,\n };\n\n this.notificationCenter.sendNotifications(NOTIFICATION_TYPES.DECISION, {\n type: DECISION_NOTIFICATION_TYPES.FLAG,\n userId: userId,\n attributes: attributes,\n decisionInfo: featureInfo,\n });\n\n return {\n variationKey: variationKey,\n enabled: flagEnabled,\n variables: variablesMap,\n ruleKey: experimentKey,\n flagKey: key,\n userContext: user,\n reasons: reportedReasons,\n };\n }\n\n /**\n * Get all decide options.\n * @param {OptimizelyDecideOption[]} options decide options\n * @return {[key: string]: boolean} Map of all provided decide options including default decide options\n */\n private getAllDecideOptions(options: OptimizelyDecideOption[]): { [key: string]: boolean } {\n const allDecideOptions = { ...this.defaultDecideOptions };\n if (!Array.isArray(options)) {\n this.logger.log(LOG_LEVEL.DEBUG, LOG_MESSAGES.INVALID_DECIDE_OPTIONS, MODULE_NAME);\n } else {\n options.forEach((option) => {\n // Filter out all provided decide options that are not in OptimizelyDecideOption[]\n if (OptimizelyDecideOption[option]) {\n allDecideOptions[option] = true;\n } else {\n this.logger.log(\n LOG_LEVEL.WARNING,\n LOG_MESSAGES.UNRECOGNIZED_DECIDE_OPTION,\n MODULE_NAME,\n option,\n );\n }\n });\n }\n\n return allDecideOptions;\n }\n\n /**\n * Returns an object of decision results for multiple flag keys and a user context.\n * If the SDK finds an error for a key, the response will include a decision for the key showing reasons for the error.\n * The SDK will always return an object of decisions. When it cannot process requests, it will return an empty object after logging the errors.\n * @param {OptimizelyUserContext} user A user context associated with this OptimizelyClient\n * @param {string[]} keys An array of flag keys for which decisions will be made.\n * @param {OptimizelyDecideOption[]} options An array of options for decision-making.\n * @return {[key: string]: OptimizelyDecision} An object of decision results mapped by flag keys.\n */\n decideForKeys(\n user: OptimizelyUserContext,\n keys: string[],\n options: OptimizelyDecideOption[] = []\n ): { [key: string]: OptimizelyDecision } {\n const decisionMap: { [key: string]: OptimizelyDecision } = {};\n if (!this.isValidInstance()) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'decideForKeys');\n return decisionMap;\n }\n if (keys.length === 0) {\n return decisionMap;\n }\n\n const allDecideOptions = this.getAllDecideOptions(options);\n keys.forEach(key => {\n const optimizelyDecision: OptimizelyDecision = this.decide(user, key, options);\n if (!allDecideOptions[OptimizelyDecideOption.ENABLED_FLAGS_ONLY] || optimizelyDecision.enabled) {\n decisionMap[key] = optimizelyDecision;\n }\n });\n\n return decisionMap;\n }\n\n /**\n * Returns an object of decision results for all active flag keys.\n * @param {OptimizelyUserContext} user A user context associated with this OptimizelyClient\n * @param {OptimizelyDecideOption[]} options An array of options for decision-making.\n * @return {[key: string]: OptimizelyDecision} An object of all decision results mapped by flag keys.\n */\n decideAll(\n user: OptimizelyUserContext,\n options: OptimizelyDecideOption[] = []\n ): { [key: string]: OptimizelyDecision } {\n const configObj = this.projectConfigManager.getConfig();\n const decisionMap: { [key: string]: OptimizelyDecision } = {};\n if (!this.isValidInstance() || !configObj) {\n this.logger.log(LOG_LEVEL.ERROR, LOG_MESSAGES.INVALID_OBJECT, MODULE_NAME, 'decideAll');\n return decisionMap;\n }\n\n const allFlagKeys = Object.keys(configObj.featureKeyMap);\n\n return this.decideForKeys(user, allFlagKeys, options);\n }\n\n}\n","/**\n * Copyright 2017, 2020, 2022 Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Provides utility method for validating that event tags user has provided are valid\n */\nimport { sprintf } from '../../utils/fns';\n\nimport { ERROR_MESSAGES } from '../enums';\n\nconst MODULE_NAME = 'EVENT_TAGS_VALIDATOR';\n\n/**\n * Validates user's provided event tags\n * @param {unknown} eventTags\n * @return {boolean} true if event tags are valid\n * @throws If event tags are not valid\n */\nexport function validate(eventTags: unknown): boolean {\n if (typeof eventTags === 'object' && !Array.isArray(eventTags) && eventTags !== null) {\n return true;\n } else {\n throw new Error(sprintf(ERROR_MESSAGES.INVALID_EVENT_TAGS, MODULE_NAME));\n }\n}\n","/**\n * Copyright 2019-2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport fns from '../fns';\n\n/**\n * Return true if the argument is a valid event batch size, false otherwise\n * @param {unknown} eventBatchSize\n * @returns {boolean}\n */\nconst validateEventBatchSize = function(eventBatchSize: unknown): boolean {\n if (typeof eventBatchSize === 'number' && fns.isSafeInteger(eventBatchSize)) {\n return eventBatchSize >= 1;\n }\n return false;\n}\n\n/**\n * Return true if the argument is a valid event flush interval, false otherwise\n * @param {unknown} eventFlushInterval\n * @returns {boolean}\n */\nconst validateEventFlushInterval = function(eventFlushInterval: unknown): boolean {\n if (typeof eventFlushInterval === 'number' && fns.isSafeInteger(eventFlushInterval)) {\n return eventFlushInterval > 0;\n }\n return false;\n}\n\nexport default {\n validateEventBatchSize: validateEventBatchSize,\n validateEventFlushInterval: validateEventFlushInterval,\n}\n","/**\n * Copyright 2020, 2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { LogHandler, ErrorHandler } from '@optimizely/js-sdk-logging';\nimport { objectValues } from '../../utils/fns';\nimport { NotificationListener, ListenerPayload } from '../../shared_types';\n\nimport {\n LOG_LEVEL,\n LOG_MESSAGES,\n NOTIFICATION_TYPES,\n} from '../../utils/enums';\n\nconst MODULE_NAME = 'NOTIFICATION_CENTER';\n\ninterface NotificationCenterOptions {\n logger: LogHandler;\n errorHandler: ErrorHandler;\n}\n\ninterface ListenerEntry {\n id: number;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: (notificationData: any) => void;\n}\n\ntype NotificationListeners = {\n [key: string]: ListenerEntry[];\n}\n\n/**\n * NotificationCenter allows registration and triggering of callback functions using\n * notification event types defined in NOTIFICATION_TYPES of utils/enums/index.js:\n * - ACTIVATE: An impression event will be sent to Optimizely.\n * - TRACK a conversion event will be sent to Optimizely\n */\nexport class NotificationCenter {\n private logger: LogHandler;\n private errorHandler: ErrorHandler;\n private notificationListeners: NotificationListeners;\n private listenerId: number;\n\n /**\n * @constructor\n * @param {NotificationCenterOptions} options\n * @param {LogHandler} options.logger An instance of a logger to log messages with\n * @param {ErrorHandler} options.errorHandler An instance of errorHandler to handle any unexpected error\n */\n constructor(options: NotificationCenterOptions) {\n this.logger = options.logger;\n this.errorHandler = options.errorHandler;\n this.notificationListeners = {};\n objectValues(NOTIFICATION_TYPES).forEach(\n (notificationTypeEnum) => {\n this.notificationListeners[notificationTypeEnum] = [];\n }\n );\n this.listenerId = 1;\n }\n\n /**\n * Add a notification callback to the notification center\n * @param {string} notificationType One of the values from NOTIFICATION_TYPES in utils/enums/index.js\n * @param {NotificationListener} callback Function that will be called when the event is triggered\n * @returns {number} If the callback was successfully added, returns a listener ID which can be used\n * to remove the callback by calling removeNotificationListener. The ID is a number greater than 0.\n * If there was an error and the listener was not added, addNotificationListener returns -1. This\n * can happen if the first argument is not a valid notification type, or if the same callback\n * function was already added as a listener by a prior call to this function.\n */\n addNotificationListener(\n notificationType: string,\n callback: NotificationListener\n ): number {\n try {\n const notificationTypeValues: string[] = objectValues(NOTIFICATION_TYPES);\n const isNotificationTypeValid = notificationTypeValues.indexOf(notificationType) > -1;\n if (!isNotificationTypeValid) {\n return -1;\n }\n \n if (!this.notificationListeners[notificationType]) {\n this.notificationListeners[notificationType] = [];\n }\n \n let callbackAlreadyAdded = false;\n (this.notificationListeners[notificationType] || []).forEach(\n (listenerEntry) => {\n if (listenerEntry.callback === callback) {\n callbackAlreadyAdded = true;\n return;\n }\n });\n\n if (callbackAlreadyAdded) {\n return -1;\n }\n \n this.notificationListeners[notificationType].push({\n id: this.listenerId,\n callback: callback,\n });\n \n const returnId = this.listenerId;\n this.listenerId += 1;\n return returnId;\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n return -1;\n }\n }\n\n /**\n * Remove a previously added notification callback\n * @param {number} listenerId ID of listener to be removed\n * @returns {boolean} Returns true if the listener was found and removed, and false\n * otherwise.\n */\n removeNotificationListener(listenerId: number): boolean {\n try {\n let indexToRemove: number | undefined;\n let typeToRemove: string | undefined;\n \n Object.keys(this.notificationListeners).some(\n (notificationType) => {\n const listenersForType = this.notificationListeners[notificationType];\n (listenersForType || []).every((listenerEntry, i) => {\n if (listenerEntry.id === listenerId) {\n indexToRemove = i;\n typeToRemove = notificationType;\n return false;\n }\n\n return true;\n });\n\n if (indexToRemove !== undefined && typeToRemove !== undefined) {\n return true;\n }\n\n return false;\n }\n );\n \n if (indexToRemove !== undefined && typeToRemove !== undefined) {\n this.notificationListeners[typeToRemove].splice(indexToRemove, 1);\n return true;\n }\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n }\n\n return false;\n }\n\n /**\n * Removes all previously added notification listeners, for all notification types\n */\n clearAllNotificationListeners(): void {\n try {\n objectValues(NOTIFICATION_TYPES).forEach(\n (notificationTypeEnum) => {\n this.notificationListeners[notificationTypeEnum] = [];\n }\n );\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n }\n }\n\n /**\n * Remove all previously added notification listeners for the argument type\n * @param {NOTIFICATION_TYPES} notificationType One of NOTIFICATION_TYPES\n */\n clearNotificationListeners(notificationType: NOTIFICATION_TYPES): void {\n try {\n this.notificationListeners[notificationType] = [];\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n }\n }\n\n /**\n * Fires notifications for the argument type. All registered callbacks for this type will be\n * called. The notificationData object will be passed on to callbacks called.\n * @param {string} notificationType One of NOTIFICATION_TYPES\n * @param {Object} notificationData Will be passed to callbacks called\n */\n sendNotifications(\n notificationType: string,\n notificationData?: T\n ): void {\n try {\n (this.notificationListeners[notificationType] || []).forEach(\n (listenerEntry) => {\n const callback = listenerEntry.callback;\n try {\n callback(notificationData);\n } catch (ex) {\n this.logger.log(\n LOG_LEVEL.ERROR,\n LOG_MESSAGES.NOTIFICATION_LISTENER_EXCEPTION,\n MODULE_NAME,\n notificationType,\n ex.message,\n );\n }\n }\n );\n } catch (e) {\n this.logger.log(LOG_LEVEL.ERROR, e.message);\n this.errorHandler.handleError(e);\n }\n }\n}\n\n/**\n * Create an instance of NotificationCenter\n * @param {NotificationCenterOptions} options\n * @returns {NotificationCenter} An instance of NotificationCenter\n */\nexport function createNotificationCenter(options: NotificationCenterOptions): NotificationCenter {\n return new NotificationCenter(options);\n}\n\nexport interface NotificationSender {\n // TODO[OASIS-6649]: Don't use any type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n sendNotifications(notificationType: NOTIFICATION_TYPES, notificationData?: any): void\n}\n","/**\n * Copyright 2020, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LogTierV1EventProcessor, LocalStoragePendingEventsDispatcher } from '@optimizely/js-sdk-event-processor';\n\nexport function createEventProcessor(\n ...args: ConstructorParameters\n): LogTierV1EventProcessor {\n return new LogTierV1EventProcessor(...args);\n}\n\nexport default { createEventProcessor, LocalStoragePendingEventsDispatcher };\n","/**\n * Copyright 2021-2022, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { LoggerFacade } from '@optimizely/js-sdk-logging';\nimport { HttpPollingDatafileManager } from '@optimizely/js-sdk-datafile-manager';\nimport { DatafileOptions, DatafileManagerConfig, DatafileManager } from '../../shared_types';\nimport { toDatafile, tryCreatingProjectConfig } from '../../core/project_config';\nimport fns from '../../utils/fns';\n\nexport function createHttpPollingDatafileManager(\n sdkKey: string,\n logger: LoggerFacade,\n // TODO[OASIS-6649]: Don't use object type\n // eslint-disable-next-line @typescript-eslint/ban-types\n datafile?: string | object,\n datafileOptions?: DatafileOptions,\n): DatafileManager { \n const datafileManagerConfig: DatafileManagerConfig = { sdkKey };\n if (datafileOptions === undefined || (typeof datafileOptions === 'object' && datafileOptions !== null)) {\n fns.assign(datafileManagerConfig, datafileOptions);\n }\n if (datafile) {\n const { configObj, error } = tryCreatingProjectConfig({\n datafile: datafile,\n jsonSchemaValidator: undefined,\n logger: logger,\n });\n \n if (error) {\n logger.error(error);\n }\n if (configObj) {\n datafileManagerConfig.datafile = toDatafile(configObj);\n }\n }\n return new HttpPollingDatafileManager(datafileManagerConfig);\n}\n","/**\n * Copyright 2016-2017, 2019-2022 Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n getLogger,\n setLogHandler,\n setLogLevel,\n setErrorHandler,\n getErrorHandler,\n LogLevel\n} from '@optimizely/js-sdk-logging';\nimport { LocalStoragePendingEventsDispatcher } from '@optimizely/js-sdk-event-processor';\nimport configValidator from './utils/config_validator';\nimport defaultErrorHandler from './plugins/error_handler';\nimport defaultEventDispatcher from './plugins/event_dispatcher/index.browser';\nimport * as enums from './utils/enums';\nimport * as loggerPlugin from './plugins/logger';\nimport Optimizely from './optimizely';\nimport eventProcessorConfigValidator from './utils/event_processor_config_validator';\nimport { createNotificationCenter } from './core/notification_center';\nimport { default as eventProcessor } from './plugins/event_processor';\nimport { OptimizelyDecideOption, Client, Config } from './shared_types';\nimport { createHttpPollingDatafileManager } from './plugins/datafile_manager/http_polling_datafile_manager';\n\nconst logger = getLogger();\nsetLogHandler(loggerPlugin.createLogger());\nsetLogLevel(LogLevel.INFO);\n\nconst MODULE_NAME = 'INDEX_BROWSER';\nconst DEFAULT_EVENT_BATCH_SIZE = 10;\nconst DEFAULT_EVENT_FLUSH_INTERVAL = 1000; // Unit is ms, default is 1s\nconst DEFAULT_EVENT_MAX_QUEUE_SIZE = 10000;\n\nlet hasRetriedEvents = false;\n\n/**\n * Creates an instance of the Optimizely class\n * @param {Config} config\n * @return {Client|null} the Optimizely client object\n * null on error \n */\nconst createInstance = function(config: Config): Client | null {\n try {\n // TODO warn about setting per instance errorHandler / logger / logLevel\n let isValidInstance = false\n\n if (config.errorHandler) {\n setErrorHandler(config.errorHandler);\n }\n if (config.logger) {\n setLogHandler(config.logger);\n // respect the logger's shouldLog functionality\n setLogLevel(LogLevel.NOTSET);\n }\n if (config.logLevel !== undefined) {\n setLogLevel(config.logLevel);\n }\n\n try {\n configValidator.validate(config);\n isValidInstance = true;\n } catch (ex) {\n logger.error(ex);\n }\n\n let eventDispatcher;\n // prettier-ignore\n if (config.eventDispatcher == null) { // eslint-disable-line eqeqeq\n // only wrap the event dispatcher with pending events retry if the user didnt override\n eventDispatcher = new LocalStoragePendingEventsDispatcher({\n eventDispatcher: defaultEventDispatcher,\n });\n\n if (!hasRetriedEvents) {\n eventDispatcher.sendPendingEvents();\n hasRetriedEvents = true;\n }\n } else {\n eventDispatcher = config.eventDispatcher;\n }\n\n let eventBatchSize = config.eventBatchSize;\n let eventFlushInterval = config.eventFlushInterval;\n\n if (!eventProcessorConfigValidator.validateEventBatchSize(config.eventBatchSize)) {\n logger.warn('Invalid eventBatchSize %s, defaulting to %s', config.eventBatchSize, DEFAULT_EVENT_BATCH_SIZE);\n eventBatchSize = DEFAULT_EVENT_BATCH_SIZE;\n }\n if (!eventProcessorConfigValidator.validateEventFlushInterval(config.eventFlushInterval)) {\n logger.warn(\n 'Invalid eventFlushInterval %s, defaulting to %s',\n config.eventFlushInterval,\n DEFAULT_EVENT_FLUSH_INTERVAL\n );\n eventFlushInterval = DEFAULT_EVENT_FLUSH_INTERVAL;\n }\n\n const errorHandler = getErrorHandler();\n const notificationCenter = createNotificationCenter({ logger: logger, errorHandler: errorHandler });\n\n const eventProcessorConfig = {\n dispatcher: eventDispatcher,\n flushInterval: eventFlushInterval,\n batchSize: eventBatchSize,\n maxQueueSize: config.eventMaxQueueSize || DEFAULT_EVENT_MAX_QUEUE_SIZE,\n notificationCenter,\n }\n\n const optimizelyOptions = {\n clientEngine: enums.JAVASCRIPT_CLIENT_ENGINE,\n ...config,\n eventProcessor: eventProcessor.createEventProcessor(eventProcessorConfig),\n logger,\n errorHandler,\n datafileManager: config.sdkKey ? createHttpPollingDatafileManager(config.sdkKey, logger, config.datafile, config.datafileOptions) : undefined,\n notificationCenter,\n isValidInstance: isValidInstance\n };\n\n const optimizely = new Optimizely(optimizelyOptions);\n\n try {\n if (typeof window.addEventListener === 'function') {\n const unloadEvent = 'onpagehide' in window ? 'pagehide' : 'unload';\n window.addEventListener(\n unloadEvent,\n () => {\n optimizely.close();\n },\n false\n );\n }\n } catch (e) {\n logger.error(enums.LOG_MESSAGES.UNABLE_TO_ATTACH_UNLOAD, MODULE_NAME, e.message);\n }\n\n return optimizely;\n } catch (e) {\n logger.error(e);\n return null;\n }\n};\n\nconst __internalResetRetryState = function(): void {\n hasRetriedEvents = false;\n};\n\n/**\n * Entry point into the Optimizely Browser SDK\n */\nexport {\n loggerPlugin as logging,\n defaultErrorHandler as errorHandler,\n defaultEventDispatcher as eventDispatcher,\n enums,\n setLogHandler as setLogger,\n setLogLevel,\n createInstance,\n __internalResetRetryState,\n OptimizelyDecideOption,\n};\n\nexport default {\n logging: loggerPlugin,\n errorHandler: defaultErrorHandler,\n eventDispatcher: defaultEventDispatcher,\n enums,\n setLogger: setLogHandler,\n setLogLevel,\n createInstance,\n __internalResetRetryState,\n OptimizelyDecideOption,\n};\n\nexport * from './export_types'\n"],"names":["Object","defineProperty","exports","value","config_1","BackoffController","this","errorCount","prototype","getDelay","BACKOFF_BASE_WAIT_SECONDS_BY_ERROR_COUNT","Math","min","length","round","random","countError","reset","extendStatics","__extends","d","b","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__","constructor","create","__importDefault","mod","__esModule","browserRequest_1","BrowserDatafileManager","_super","apply","arguments","makeGetRequest","reqUrl","headers","getConfigDefaults","autoUpdate","default","logger","getLogger","req","XMLHttpRequest","responsePromise","Promise","resolve","reject","open","keys","forEach","headerName","header","setRequestHeader","setHeadersInXhr","onreadystatechange","readyState","status","Error","headers_1","allHeadersString","getAllResponseHeaders","headerLines","split","headerLine","separatorIndex","indexOf","slice","headerValue","parseHeadersFromXhr","resp","statusCode","body","responseText","timeout","REQUEST_TIMEOUT_MS","ontimeout","error","send","abort","DEFAULT_UPDATE_INTERVAL","MIN_UPDATE_INTERVAL","DEFAULT_URL_TEMPLATE","DEFAULT_AUTHENTICATED_URL_TEMPLATE","EventEmitter","listeners","listenerId","on","eventName","listener","_this","currentListenerId","String","emit","arg","removeAllListeners","__assign","assign","t","s","i","n","call","js_sdk_logging_1","js_sdk_utils_1","eventEmitter_1","backoffController_1","isSuccessStatusCode","noOpKeyValueCache","get","set","contains","remove","HttpPollingDatafileManager","config","configWithDefaultsApplied","datafile","_a","sdkKey","_b","updateInterval","_c","urlTemplate","_d","cache","cacheKey","isReadyPromiseSettled","readyPromiseResolver","readyPromiseRejecter","readyPromise","currentDatafile","resolveReadyPromise","isStarted","datafileUrl","sprintf","emitter","isValidUpdateInterval","warn","currentTimeout","currentRequest","backoffController","syncOnCurrentRequestComplete","start","debug","setDatafileFromCacheIfAvailable","syncDatafile","stop","clearTimeout","onReady","onRequestRejected","err","message","onRequestResolved","response","trySavingLastModified","getNextDatafileFromResponse","info","datafileUpdate","onRequestComplete","rejectReadyPromise","lastResponseLastModified","JSON","stringify","then","scheduleNextUpdate","currentBackoffDelay","nextUpdateDelay","max","setTimeout","lastModifiedHeader","browserDatafileManager_1","sendEventNotification","getQueue","validateAndGetBatchSize","validateAndGetFlushInterval","DEFAULT_BATCH_SIZE","DEFAULT_FLUSH_INTERVAL","eventQueue_1","flushInterval","batchSize","floor","sink","batchComparator","DefaultEventQueue","maxQueueSize","SingleEventQueue","notificationCenter","event","sendNotifications","NOTIFICATION_TYPES","LOG_EVENT","Timer","callback","timeoutId","refresh","enqueue","buffer","timer","flush","bind","started","result","bufferedEvent","push","areEventContextsEqual","eventA","eventB","contextA","context","contextB","accountId","projectId","clientName","clientVersion","revision","anonymizeIP","botFiltering","__createBinding","o","m","k","k2","undefined","enumerable","__exportStar","LocalStoragePendingEventsDispatcher","PendingEventsDispatcher","pendingEventsStore_1","eventDispatcher","store","dispatcher","dispatchEvent","request","uuid","generateUUID","timestamp","getTimestamp","sendPendingEvents","pendingEvents","values","item","e","entry","LocalStorageStore","maxValues","key","LS_KEY","getMap","map","replace","objectValues","clear","window","localStorage","setItem","clean","toRemove","entries","sort","a","data","getItem","parse","RequestTracker","reqsInFlightCount","reqsCompleteResolvers","trackRequest","reqPromise","onReqComplete","resolver","onRequestsComplete","formatEvents","buildConversionEventV1","buildImpressionEventV1","makeBatchedEventV1","BOT_FILTERING_KEY","events","visitors","type","visitor","makeVisitor","snapshots","makeDecisionSnapshot","makeConversionSnapshot","client_name","client_version","account_id","project_id","anonymize_ip","enrich_decisions","conversion","tags","entity_id","id","revenue","layer","experiment","variation","ruleKey","flagKey","ruleType","enabled","layerId","decisions","campaign_id","experiment_id","variation_id","metadata","flag_key","rule_key","rule_type","variation_key","visitor_id","user","attributes","attr","entityId","url","httpVerb","params","__awaiter","thisArg","_arguments","P","generator","fulfilled","step","next","rejected","done","__generator","f","y","g","_","label","sent","trys","ops","verb","Symbol","iterator","v","op","TypeError","pop","LogTierV1EventProcessor","eventProcessor_1","requestTracker_1","events_1","buildEventV1_1","requestTracker","queue","drainQueue","formattedEvent","process","NoopErrorHandler","handleError","exception","globalErrorHandler","setErrorHandler","handler","getErrorHandler","resetErrorHandler","__export","__spreadArrays","il","r","j","jl","errorHandler_1","models_1","stringToLogLevel","NOTSET","DEBUG","INFO","WARNING","ERROR","coerceLogLevel","level","toUpperCase","DefaultLogManager","defaultLoggerFacade","OptimizelyLogger","loggers","name","messagePrefix","ConsoleLogHandler","logLevel","LogLevel","isValidEnum","setLogLevel","logToConsole","prefix","log","shouldLog","logMessage","getLogLevelName","getTime","consoleLog","Date","toISOString","targetLogLevel","logArguments","console","globalLogLevel","globalLogHandler","opts","splat","_i","internalLog","namedLog","format","last","splice","globalLogManager","setLogHandler","getLogLevel","resetLogger","uuid_1","obj","v4","enumToCheck","found","index","groupBy","arr","grouperFn","grouper","objectEntries","find","cond","arr_1","keyBy","keyByFn","args","MAX_SAFE_INTEGER_LIMIT","pow","target","sources","to","nextSource","nextKey","keyByUtil","currentTimestamp","isSafeInteger","number","abs","isNumber","LOG_LEVEL","ERROR_MESSAGES","CONDITION_EVALUATOR_ERROR","DATAFILE_AND_SDK_KEY_MISSING","EXPERIMENT_KEY_NOT_IN_DATAFILE","FEATURE_NOT_IN_DATAFILE","IMPROPERLY_FORMATTED_EXPERIMENT","INVALID_ATTRIBUTES","INVALID_BUCKETING_ID","INVALID_DATAFILE","INVALID_DATAFILE_MALFORMED","INVALID_CONFIG","INVALID_JSON","INVALID_ERROR_HANDLER","INVALID_EVENT_DISPATCHER","INVALID_EVENT_TAGS","INVALID_EXPERIMENT_KEY","INVALID_EXPERIMENT_ID","INVALID_GROUP_ID","INVALID_LOGGER","INVALID_ROLLOUT_ID","INVALID_USER_ID","INVALID_USER_PROFILE_SERVICE","NO_DATAFILE_SPECIFIED","NO_JSON_PROVIDED","NO_VARIATION_FOR_EXPERIMENT_KEY","UNDEFINED_ATTRIBUTE","UNRECOGNIZED_ATTRIBUTE","UNABLE_TO_CAST_VALUE","USER_NOT_IN_FORCED_VARIATION","USER_PROFILE_LOOKUP_ERROR","USER_PROFILE_SAVE_ERROR","VARIABLE_KEY_NOT_IN_DATAFILE","VARIATION_ID_NOT_IN_DATAFILE","VARIATION_ID_NOT_IN_DATAFILE_NO_EXPERIMENT","INVALID_INPUT_FORMAT","INVALID_DATAFILE_VERSION","INVALID_VARIATION_KEY","LOG_MESSAGES","ACTIVATE_USER","DISPATCH_CONVERSION_EVENT","DISPATCH_IMPRESSION_EVENT","DEPRECATED_EVENT_VALUE","EVENT_KEY_NOT_FOUND","EXPERIMENT_NOT_RUNNING","FEATURE_ENABLED_FOR_USER","FEATURE_NOT_ENABLED_FOR_USER","FEATURE_HAS_NO_EXPERIMENTS","FAILED_TO_PARSE_VALUE","FAILED_TO_PARSE_REVENUE","FORCED_BUCKETING_FAILED","INVALID_OBJECT","INVALID_CLIENT_ENGINE","INVALID_DEFAULT_DECIDE_OPTIONS","INVALID_DECIDE_OPTIONS","INVALID_VARIATION_ID","NOTIFICATION_LISTENER_EXCEPTION","NO_ROLLOUT_EXISTS","NOT_ACTIVATING_USER","NOT_TRACKING_USER","PARSED_REVENUE_VALUE","PARSED_NUMERIC_VALUE","RETURNING_STORED_VARIATION","ROLLOUT_HAS_NO_EXPERIMENTS","SAVED_VARIATION","SAVED_VARIATION_NOT_FOUND","SHOULD_NOT_DISPATCH_ACTIVATE","SKIPPING_JSON_VALIDATION","TRACK_EVENT","UNRECOGNIZED_DECIDE_OPTION","USER_ASSIGNED_TO_EXPERIMENT_BUCKET","USER_BUCKETED_INTO_EXPERIMENT_IN_GROUP","USER_BUCKETED_INTO_TARGETING_RULE","USER_IN_FEATURE_EXPERIMENT","USER_IN_ROLLOUT","USER_NOT_BUCKETED_INTO_EVERYONE_TARGETING_RULE","USER_NOT_BUCKETED_INTO_EXPERIMENT_IN_GROUP","USER_NOT_BUCKETED_INTO_ANY_EXPERIMENT_IN_GROUP","USER_NOT_BUCKETED_INTO_TARGETING_RULE","USER_NOT_IN_FEATURE_EXPERIMENT","USER_NOT_IN_ROLLOUT","USER_FORCED_IN_VARIATION","USER_MAPPED_TO_FORCED_VARIATION","USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE","USER_MEETS_CONDITIONS_FOR_TARGETING_RULE","USER_HAS_VARIATION","USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED","USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED","USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED_BUT_INVALID","USER_HAS_FORCED_DECISION_WITH_NO_RULE_SPECIFIED_BUT_INVALID","USER_HAS_FORCED_VARIATION","USER_HAS_NO_VARIATION","USER_HAS_NO_FORCED_VARIATION","USER_HAS_NO_FORCED_VARIATION_FOR_EXPERIMENT","USER_NOT_IN_ANY_EXPERIMENT","USER_NOT_IN_EXPERIMENT","USER_RECEIVED_DEFAULT_VARIABLE_VALUE","FEATURE_NOT_ENABLED_RETURN_DEFAULT_VARIABLE_VALUE","VARIABLE_NOT_USED_RETURN_DEFAULT_VARIABLE_VALUE","USER_RECEIVED_VARIABLE_VALUE","VALID_DATAFILE","VALID_USER_PROFILE_SERVICE","VARIATION_REMOVED_FOR_USER","VARIABLE_REQUESTED_WITH_WRONG_TYPE","VALID_BUCKETING_ID","BUCKETING_ID_NOT_STRING","EVALUATING_AUDIENCE","EVALUATING_AUDIENCES_COMBINED","AUDIENCE_EVALUATION_RESULT","AUDIENCE_EVALUATION_RESULT_COMBINED","MISSING_ATTRIBUTE_VALUE","UNEXPECTED_CONDITION_VALUE","UNEXPECTED_TYPE","UNEXPECTED_TYPE_NULL","UNKNOWN_CONDITION_TYPE","UNKNOWN_MATCH_TYPE","UPDATED_OPTIMIZELY_CONFIG","OUT_OF_BOUNDS","UNABLE_TO_ATTACH_UNLOAD","CONTROL_ATTRIBUTES","BOT_FILTERING","BUCKETING_ID","STICKY_BUCKETING_KEY","USER_AGENT","FORCED_DECISION_NULL_RULE_KEY","DECISION_NOTIFICATION_TYPES","AB_TEST","FEATURE","FEATURE_TEST","FEATURE_VARIABLE","ALL_FEATURE_VARIABLES","FLAG","DECISION_SOURCES","ROLLOUT","EXPERIMENT","AUDIENCE_EVALUATION_TYPES","RULE","FEATURE_VARIABLE_TYPES","BOOLEAN","DOUBLE","INTEGER","STRING","DATAFILE_VERSIONS","V2","V3","V4","DECISION_MESSAGES","SDK_NOT_READY","FLAG_KEY_INVALID","VARIABLE_VALUE_INVALID","MODULE_NAME","SUPPORTED_VERSIONS","eventObj","encodeURIComponent","join","toQueryString","NoOpLogger","createLogger","VariableType","OptimizelyDecideOption","newErrorDecision","reasons","variationKey","variables","userContext","optimizely","userId","forcedDecisionsMap","OptimizelyUserContext","options","decide","cloneUserContext","decideForKeys","decideAll","eventTags","track","decision","forcedDecision","findForcedDecision","isForcedDecisionRemoved","validRuleKey","forcedDecisionByRuleKey","getOptimizely","getUserId","getAttributes","DEFAULT_OPERATOR_TYPES","evaluate","conditions","leafEvaluator","isArray","firstOperator","restOfConditions","sawNullResult","conditionResult","configObj","environmentKey","audiences","OptimizelyConfig","getAudiences","featureIdVariablesMap","featureFlags","reduce","resultMap","feature","variableIdMap","getVariableIdMap","experimentsMapById","getExperimentsMapById","experimentsMap","getExperimentsKeyMap","featuresMap","getFeaturesMap","typedAudienceIds","typedAudiences","typedAudience","audience","audiencesById","serializedAudience","cond_1","subAudience","getSerializedAudiences","audienceName","concat","audienceConditions","featureIdVariableMap","featureId","featureVariableUsages","isFeatureEnabled","variablesMap","optlyVariablesMap","featureVariable","defaultValue","featureVariableUsage","defaultVariable","optimizelyVariable","variations","optlyVariationsMap","mergeFeatureVariables","featureEnabled","variable","featureVariableIdMap","experiments","getExperimentAudiences","variationsMap","getVariationsMap","rollouts","experimentIds","rollout","rolloutExperimentIds","getRolloutExperimentIds","featureIds","experimentFeatureMap","toString","experimentKeysMap","featureFlag","featureExperimentMap","experimentRules","experimentId","featureVariableMap","deliveryRules","rolloutIdMap","rolloutId","getDeliveryRules","createProjectConfig","datafileObj","datafileStr","datafileCopy","projectConfig","groups","group","groupCopy","rolloutCopy","__datafileStr","attributeKeyMap","eventKeyMap","groupIdMap","Id","groupId","variationKeyMap","experimentKeyMap","experimentIdMap","variationIdMap","variationVariableUsageMap","featureKeyMap","subType","variableKeyMap","flagRulesMap","flagRuleExperiments","flagVariationsMap","rules","rule","getLayerId","getAttributeId","attributeKey","attribute","hasReservedPrefix","getEventId","eventKey","getExperimentStatus","experimentKey","getVariationKeyFromId","variationId","getExperimentFromKey","getTrafficAllocation","trafficAllocation","getExperimentFromId","getFlagVariationByKey","getFeatureFromKey","featureKey","toDatafile","tryCreatingProjectConfig","newDatafileObj","ex","configValidator","jsonSchemaValidator","validate","createProjectConfigArgs","getSendFlagDecisionsValue","sendFlagDecisions","getErrorMessage","maybeError","defaultMessage","datafileAndSdkKeyMissingError","success","reason","handleNewDatafileException","handleNewDatafile","datafileManager","onDatafileManagerReadyFulfill","onDatafileManagerReadyReject","onDatafileManagerUpdate","ProjectConfigManager","newDatafileError","newDatafile","oldRevision","optimizelyConfigObj","updateListeners","MAX_HASH_VALUE","bucket","bucketerParams","decideReasons","policy","bucketedExperimentId","bucketUserIntoExperiment","bucketingId","bucketValue","_generateBucketValue","_findBucket","trafficAllocationConfig","bucketingKey","endOfRange","ratio","murmurhash","v3","content","test","isPreReleaseVersion","version","preReleaseIndex","buildIndex","isBuildVersion","splitVersion","targetPrefix","targetSuffix","substring","dotCount","targetVersionParts","targetVersionParts_1","MATCH_TYPES","EVALUATORS_BY_MATCH_TYPE","isValueTypeValidForExactConditions","fns","exactEvaluator","condition","userAttributes","conditionValue","conditionValueType","conditionName","userValue","userValueType","validateValuesForNumericCondition","evaluateSemanticVersion","conditionsVersion","userProvidedVersion","userVersionParts","conditionsVersionParts","userVersionPartsLen","idx","userVersionPart","parseInt","conditionsVersionPart","conditionMatch","match","UNSTABLE_conditionEvaluators","typeToEvaluatorMap","custom_attribute","customAttributeConditionEvaluator","AudienceEvaluator","conditionTreeEvaluator.evaluate","audienceId","evaluateConditionWithUserAttributes","resultText","evaluator","input","audienceEvaluator","forcedVariationMap","userProfileService","DecisionService","getBucketingId","checkIfExperimentIsActive","decisionForcedVariation","getForcedVariation","forcedVariationKey","decisionWhitelistedVariation","getWhitelistedVariation","shouldIgnoreUPS","experimentBucketMap","resolveExperimentBucketMap","getStoredVariation","decisionifUserIsInAudience","checkIfUserIsInAudience","buildBucketerParams","decisionVariation","saveUserProfile","userProfile","getUserProfile","attributeExperimentBucketMap","experiment_bucket_map","forcedVariations","evaluationAttribute","loggingKey","experimentAudienceConditions","audienceIds","user_id","lookup","save","getVariationForFeatureExperiment","experimentDecision","decisionRolloutVariation","getVariationForRollout","rolloutDecision","getVariationFromExperimentRule","decisionSource","skipToEveryoneElse","rolloutRules","getVariationFromDeliveryRule","getForcedDecision","experimentToVariationMap","stringValidator.validate","removeForcedVariation","setInForcedVariationMap","forcedDecisionResponse","findValidatedForcedDecision","forcedVariaton","getVariation","ruleIndex","bucketerVariationId","everyoneElse","bucketedVariation","getRevenueValue","rawValue","parsedRevenueValue","isNaN","getEventValue","parsedEventValue","parseFloat","isAttributeValid","attributeValue","ENDPOINT","getCommonEventParams","clientEngine","commonParams","attributeId","getExperimentKey","decisionObj","getVariationKey","getFeatureEnabledFromVariation","getExperimentId","getVariationId","buildVisitorAttributes","builtAttributes","attributesValidator.isAttributeValid","errorHandler","isOptimizelyConfigValid","isValidInstance","decideOptionsArray","defaultDecideOptions","option","projectConfigManager","disposeOnUpdate","onUpdate","OPTIMIZELY_CONFIG_UPDATE","projectConfigManagerReadyPromise","userProfileServiceInstance","decisionService","eventProcessor","eventProcessorStartedPromise","all","promiseResults","readyTimeouts","nextReadyTimeoutId","Optimizely","getConfig","validateInputs","experiment_key","notActivatingExperiment","projectConfig.getExperimentFromKey","enums.DECISION_SOURCES","sendImpressionEvent","impressionEvent","decision.getExperimentKey","decision.getExperimentId","decision.getVariationKey","decision.getVariationId","emitNotificationCenterActivate","campaignId","impressionEventParams","getImpressionEvent","ACTIVATE","logEvent","event_key","enums.LOG_MESSAGES","conversionEvent","eventId","eventTagUtils.getRevenueValue","eventValue","eventTagUtils.getEventValue","filterEmptyValues","emitNotificationCenterTrack","snapshot","eventDict","getConversionEvent","TRACK","createUserContext","decisionNotificationType","DECISION","decisionInfo","setForcedVariation","stringInputs","feature_key","projectConfig.getFeatureFromKey","sourceInfo","getVariationForFeature","decision.getFeatureEnabledFromVariation","projectConfig.getSendFlagDecisionsValue","featureInfo","source","enabledFeatures_1","variableKey","getFeatureVariableForType","variableType","variable_key","variableValue","getFeatureVariableValueFromVariation","variableUsage","castValue","decisionObj_1","featureEnabled_1","allVariables_1","variableValues","getOptimizelyConfig","eventProcessorStoppedPromise","readyTimeoutId","readyTimeoutRecord","readyTimeout","onClose","timeoutValue","resolveTimeoutPromise","timeoutPromise","race","allDecideOptions","getAllDecideOptions","flagEnabled","decisionEventDispatched","reportedReasons","decisionMap","optimizelyDecision","allFlagKeys","notificationListeners","notificationTypeEnum","NotificationCenter","notificationType","callbackAlreadyAdded_1","listenerEntry","returnId","indexToRemove_1","typeToRemove_1","some","every","notificationData","createEventProcessor","createHttpPollingDatafileManager","datafileOptions","datafileManagerConfig","loggerPlugin.createLogger","hasRetriedEvents","createInstance","defaultEventDispatcher","eventBatchSize","eventFlushInterval","eventProcessorConfigValidator","eventProcessorConfig","eventMaxQueueSize","optimizelyOptions","optimizely_1","addEventListener","unloadEvent","close","__internalResetRetryState","logging","loggerPlugin","defaultErrorHandler","enums","setLogger"],"sourceRoot":""}