{"version":3,"file":"index.mjs","mappings":"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","sources":["webpack://@featurevisor/sdk/../../node_modules/murmurhash/murmurhash.js","webpack://@featurevisor/sdk/webpack/bootstrap","webpack://@featurevisor/sdk/webpack/runtime/define property getters","webpack://@featurevisor/sdk/webpack/runtime/hasOwnProperty shorthand","webpack://@featurevisor/sdk/./src/bucket.ts","webpack://@featurevisor/sdk/./src/logger.ts","webpack://@featurevisor/sdk/./src/datafileReader.ts","webpack://@featurevisor/sdk/./src/emitter.ts","webpack://@featurevisor/sdk/../../node_modules/compare-versions/lib/esm/index.js","webpack://@featurevisor/sdk/./src/conditions.ts","webpack://@featurevisor/sdk/./src/segments.ts","webpack://@featurevisor/sdk/./src/feature.ts","webpack://@featurevisor/sdk/./src/evaluate.ts","webpack://@featurevisor/sdk/./src/instance.ts"],"sourcesContent":["(function(){\n  const _global = this;\n\n  const createBuffer = (val) => new TextEncoder().encode(val)\n\n  /**\n   * JS Implementation of MurmurHash2\n   *\n   * @author <a href=\"mailto:gary.court@gmail.com\">Gary Court</a>\n   * @see http://github.com/garycourt/murmurhash-js\n   * @author <a href=\"mailto:aappleby@gmail.com\">Austin Appleby</a>\n   * @see http://sites.google.com/site/murmurhash/\n   *\n   * @param {Uint8Array | string} str ASCII only\n   * @param {number} seed Positive integer only\n   * @return {number} 32-bit positive integer hash\n   */\n  function MurmurHashV2(str, seed) {\n    if (typeof str === 'string') str = createBuffer(str);\n    let\n      l = str.length,\n      h = seed ^ l,\n      i = 0,\n      k;\n\n    while (l >= 4) {\n      k =\n        ((str[i] & 0xff)) |\n        ((str[++i] & 0xff) << 8) |\n        ((str[++i] & 0xff) << 16) |\n        ((str[++i] & 0xff) << 24);\n\n      k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n      k ^= k >>> 24;\n      k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n\n    h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;\n\n      l -= 4;\n      ++i;\n    }\n\n    switch (l) {\n    case 3: h ^= (str[i + 2] & 0xff) << 16;\n    case 2: h ^= (str[i + 1] & 0xff) << 8;\n    case 1: h ^= (str[i] & 0xff);\n            h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n    }\n\n    h ^= h >>> 13;\n    h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));\n    h ^= h >>> 15;\n\n    return h >>> 0;\n  };\n\n  /*\n   * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)\n   *\n   * @author <a href=\"mailto:gary.court@gmail.com\">Gary Court</a>\n   * @see http://github.com/garycourt/murmurhash-js\n   * @author <a href=\"mailto:aappleby@gmail.com\">Austin Appleby</a>\n   * @see http://sites.google.com/site/murmurhash/\n   *\n   * @param {Uint8Array | string} key ASCII only\n   * @param {number} seed Positive integer only\n   * @return {number} 32-bit positive integer hash\n   */\n  function MurmurHashV3(key, seed) {\n    if (typeof key === 'string') key = createBuffer(key);\n\n    let remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i;\n\n    remainder = key.length & 3; // key.length % 4\n    bytes = key.length - remainder;\n    h1 = seed;\n    c1 = 0xcc9e2d51;\n    c2 = 0x1b873593;\n    i = 0;\n\n    while (i < bytes) {\n        k1 =\n          ((key[i] & 0xff)) |\n          ((key[++i] & 0xff) << 8) |\n          ((key[++i] & 0xff) << 16) |\n          ((key[++i] & 0xff) << 24);\n      ++i;\n\n      k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;\n      k1 = (k1 << 15) | (k1 >>> 17);\n      k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;\n\n      h1 ^= k1;\n          h1 = (h1 << 13) | (h1 >>> 19);\n      h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;\n      h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));\n    }\n\n    k1 = 0;\n\n    switch (remainder) {\n      case 3: k1 ^= (key[i + 2] & 0xff) << 16;\n      case 2: k1 ^= (key[i + 1] & 0xff) << 8;\n      case 1: k1 ^= (key[i] & 0xff);\n\n      k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n      k1 = (k1 << 15) | (k1 >>> 17);\n      k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n      h1 ^= k1;\n    }\n\n    h1 ^= key.length;\n\n    h1 ^= h1 >>> 16;\n    h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\n    h1 ^= h1 >>> 13;\n    h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;\n    h1 ^= h1 >>> 16;\n\n    return h1 >>> 0;\n  }\n\n  const murmur = MurmurHashV3;\n  murmur.v2 = MurmurHashV2;\n  murmur.v3 = MurmurHashV3;\n\n  if (typeof(module) != 'undefined') {\n    module.exports = murmur;\n  } else {\n    const _previousRoot = _global.murmur;\n    murmur.noConflict = function() {\n      _global.murmur = _previousRoot;\n      return murmur;\n    }\n    _global.murmur = murmur;\n  }\n}());\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import * as murmurhash from \"murmurhash\";\nimport { Feature, BucketKey, BucketValue, Context, AttributeValue } from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\n\n/**\n * Generic hashing\n */\nconst HASH_SEED = 1;\nconst MAX_HASH_VALUE = Math.pow(2, 32);\n\nexport const MAX_BUCKETED_NUMBER = 100000; // 100% * 1000 to include three decimal places in the same integer value\n\nexport function getBucketedNumber(bucketKey: string): number {\n  const hashValue = murmurhash.v3(bucketKey, HASH_SEED);\n  const ratio = hashValue / MAX_HASH_VALUE;\n\n  return Math.floor(ratio * MAX_BUCKETED_NUMBER);\n}\n\n/**\n * Feature specific bucketing\n */\nexport type ConfigureBucketKey = (\n  feature: Feature,\n  context: Context,\n  bucketKey: BucketKey,\n) => BucketKey;\n\nexport interface BucketKeyOptions {\n  feature: Feature;\n  context: Context;\n  logger: Logger;\n  bucketKeySeparator?: string;\n  configureBucketKey?: ConfigureBucketKey;\n}\n\nexport function getBucketKey(options: BucketKeyOptions): BucketKey {\n  const { feature, context, logger, bucketKeySeparator = \".\", configureBucketKey } = options;\n\n  const featureKey = feature.key;\n\n  let type;\n  let attributeKeys;\n\n  if (typeof feature.bucketBy === \"string\") {\n    type = \"plain\";\n    attributeKeys = [feature.bucketBy];\n  } else if (Array.isArray(feature.bucketBy)) {\n    type = \"and\";\n    attributeKeys = feature.bucketBy;\n  } else if (typeof feature.bucketBy === \"object\" && Array.isArray(feature.bucketBy.or)) {\n    type = \"or\";\n    attributeKeys = feature.bucketBy.or;\n  } else {\n    logger.error(\"invalid bucketBy\", { featureKey, bucketBy: feature.bucketBy });\n\n    throw new Error(\"invalid bucketBy\");\n  }\n\n  const bucketKey: AttributeValue[] = [];\n\n  attributeKeys.forEach((attributeKey) => {\n    const attributeValue = context[attributeKey];\n\n    if (typeof attributeValue === \"undefined\") {\n      return;\n    }\n\n    if (type === \"plain\" || type === \"and\") {\n      bucketKey.push(attributeValue);\n    } else {\n      // or\n      if (bucketKey.length === 0) {\n        bucketKey.push(attributeValue);\n      }\n    }\n  });\n\n  bucketKey.push(featureKey);\n\n  const result = bucketKey.join(bucketKeySeparator);\n\n  if (configureBucketKey) {\n    return configureBucketKey(feature, context, result);\n  }\n\n  return result;\n}\n\nexport interface Bucket {\n  bucketKey: BucketKey;\n  bucketValue: BucketValue;\n}\n\nexport type ConfigureBucketValue = (\n  feature: Feature,\n  context: Context,\n  bucketValue: BucketValue,\n) => BucketValue;\n\nexport interface BucketValueOptions {\n  // common with BucketKeyOptions\n  feature: Feature;\n  context: Context;\n  logger: Logger;\n  bucketKeySeparator?: string;\n  configureBucketKey?: ConfigureBucketKey;\n\n  // specific to BucketValueOptions\n  configureBucketValue?: ConfigureBucketValue;\n}\n\nexport function getBucket(options: BucketValueOptions): Bucket {\n  const { feature, context, logger, bucketKeySeparator, configureBucketKey, configureBucketValue } =\n    options;\n  const bucketKey = getBucketKey({\n    feature,\n    context,\n    logger,\n    bucketKeySeparator,\n    configureBucketKey,\n  });\n  const value = getBucketedNumber(bucketKey);\n\n  if (configureBucketValue) {\n    const configuredValue = configureBucketValue(feature, context, value);\n\n    return {\n      bucketKey,\n      bucketValue: configuredValue,\n    };\n  }\n\n  return {\n    bucketKey,\n    bucketValue: value,\n  };\n}\n","export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport type LogMessage = string;\n\nexport interface LogDetails {\n  [key: string]: any;\n}\n\nexport type LogHandler = (level: LogLevel, message: LogMessage, details?: LogDetails) => void;\n\nexport interface CreateLoggerOptions {\n  levels?: LogLevel[];\n  handler?: LogHandler;\n}\n\nexport const loggerPrefix = \"[Featurevisor]\";\n\nexport const defaultLogLevels: LogLevel[] = [\n  // supported, but not enabled by default\n  // \"debug\",\n  // \"info\",\n\n  // enabled by default\n  \"warn\",\n  \"error\",\n];\n\nexport const defaultLogHandler: LogHandler = function defaultLogHandler(\n  level,\n  message,\n  details = {},\n) {\n  switch (level) {\n    case \"debug\":\n      console.log(loggerPrefix, message, details);\n      break;\n    case \"info\":\n      console.info(loggerPrefix, message, details);\n      break;\n    case \"warn\":\n      console.warn(loggerPrefix, message, details);\n      break;\n    case \"error\":\n      console.error(loggerPrefix, message, details);\n      break;\n  }\n};\n\nexport class Logger {\n  private levels: LogLevel[];\n  private handle: LogHandler;\n\n  constructor(options: CreateLoggerOptions) {\n    this.levels = options.levels as LogLevel[];\n    this.handle = options.handler as LogHandler;\n  }\n\n  setLevels(levels: LogLevel[]) {\n    this.levels = levels;\n  }\n\n  log(level: LogLevel, message: LogMessage, details?: LogDetails) {\n    if (this.levels.indexOf(level) !== -1) {\n      this.handle(level, message, details);\n    }\n  }\n\n  debug(message: LogMessage, details?: LogDetails) {\n    this.log(\"debug\", message, details);\n  }\n\n  info(message: LogMessage, details?: LogDetails) {\n    this.log(\"info\", message, details);\n  }\n\n  warn(message: LogMessage, details?: LogDetails) {\n    this.log(\"warn\", message, details);\n  }\n\n  error(message: LogMessage, details?: LogDetails) {\n    this.log(\"error\", message, details);\n  }\n}\n\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n  const levels = options.levels || defaultLogLevels;\n  const logHandler = options.handler || defaultLogHandler;\n\n  return new Logger({ levels, handler: logHandler });\n}\n","import {\n  Feature,\n  Segment,\n  DatafileContentV1,\n  DatafileContentV2,\n  Attribute,\n  AttributeKey,\n  SegmentKey,\n  FeatureKey,\n} from \"@featurevisor/types\";\n\nexport function parseJsonConditionsIfStringified<T>(record: T, key: string): T {\n  if (typeof record[key] === \"string\" && record[key] !== \"*\") {\n    try {\n      record[key] = JSON.parse(record[key]);\n    } catch (e) {\n      console.error(\"Error parsing JSON\", e);\n    }\n  }\n\n  return record;\n}\n\nexport class DatafileReader {\n  private schemaVersion: string;\n  private revision: string;\n\n  private attributes: Record<AttributeKey, Attribute>;\n  private segments: Record<SegmentKey, Segment>;\n  private features: Record<FeatureKey, Feature>;\n\n  constructor(datafileJson: DatafileContentV1 | DatafileContentV2) {\n    this.schemaVersion = datafileJson.schemaVersion;\n    this.revision = datafileJson.revision;\n\n    if (this.schemaVersion === \"2\") {\n      // v2\n      const datafileJsonV2 = datafileJson as DatafileContentV2;\n\n      this.attributes = datafileJsonV2.attributes;\n      this.segments = datafileJsonV2.segments;\n      this.features = datafileJsonV2.features;\n    } else {\n      // v1\n      const datafileJsonV1 = datafileJson as DatafileContentV1;\n\n      this.attributes = {};\n      datafileJsonV1.attributes.forEach((a) => {\n        this.attributes[a.key] = a;\n      });\n\n      this.segments = {};\n      datafileJsonV1.segments.forEach((s) => {\n        this.segments[s.key] = s;\n      });\n\n      this.features = {};\n      datafileJsonV1.features.forEach((f) => {\n        if (Array.isArray(f.variablesSchema)) {\n          f.variablesSchema = f.variablesSchema.reduce((acc, variable) => {\n            acc[variable.key] = variable;\n            return acc;\n          }, {});\n        }\n\n        this.features[f.key] = f;\n      });\n    }\n  }\n\n  getRevision(): string {\n    return this.revision;\n  }\n\n  getSchemaVersion(): string {\n    return this.schemaVersion;\n  }\n\n  getAllAttributes(): Attribute[] {\n    const result: Attribute[] = [];\n\n    Object.keys(this.attributes).forEach((key) => {\n      result.push(this.attributes[key]);\n    });\n\n    return result;\n  }\n\n  getAttribute(attributeKey: AttributeKey): Attribute | undefined {\n    return this.attributes[attributeKey];\n  }\n\n  getSegment(segmentKey: SegmentKey): Segment | undefined {\n    const segment = this.segments[segmentKey];\n\n    if (!segment) {\n      return undefined;\n    }\n\n    return parseJsonConditionsIfStringified(segment, \"conditions\");\n  }\n\n  getFeature(featureKey: FeatureKey): Feature | undefined {\n    return this.features[featureKey];\n  }\n}\n","export type EventName = \"ready\" | \"refresh\" | \"update\" | \"activation\";\n\nexport interface Listeners {\n  [key: string]: Function[];\n}\n\nexport class Emitter {\n  private _listeners: Listeners;\n\n  constructor() {\n    this._listeners = {};\n  }\n\n  public addListener(eventName: EventName, fn: Function): void {\n    if (typeof this._listeners[eventName] === \"undefined\") {\n      this._listeners[eventName] = [];\n    }\n\n    this._listeners[eventName].push(fn);\n  }\n\n  public removeListener(eventName: EventName, fn: Function): void {\n    if (typeof this._listeners[eventName] === \"undefined\") {\n      return;\n    }\n\n    const index = this._listeners[eventName].indexOf(fn);\n\n    if (index !== -1) {\n      this._listeners[eventName].splice(index, 1);\n    }\n  }\n\n  public removeAllListeners(eventName?: EventName): void {\n    if (eventName) {\n      this._listeners[eventName] = [];\n    } else {\n      Object.keys(this._listeners).forEach((key) => {\n        this._listeners[key] = [];\n      });\n    }\n  }\n\n  public emit(eventName: EventName, ...args: any[]): void {\n    if (typeof this._listeners[eventName] === \"undefined\") {\n      return;\n    }\n\n    this._listeners[eventName].forEach((fn) => {\n      fn(...args);\n    });\n  }\n}\n","/**\n * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.\n * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.\n * @param v1 - First version to compare\n * @param v2 - Second version to compare\n * @returns Numeric value compatible with the [Array.sort(fn) interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters).\n */\nexport const compareVersions = (v1, v2) => {\n    // validate input and split into segments\n    const n1 = validateAndParse(v1);\n    const n2 = validateAndParse(v2);\n    // pop off the patch\n    const p1 = n1.pop();\n    const p2 = n2.pop();\n    // validate numbers\n    const r = compareSegments(n1, n2);\n    if (r !== 0)\n        return r;\n    // validate pre-release\n    if (p1 && p2) {\n        return compareSegments(p1.split('.'), p2.split('.'));\n    }\n    else if (p1 || p2) {\n        return p1 ? -1 : 1;\n    }\n    return 0;\n};\n/**\n * Validate [semver](https://semver.org/) version strings.\n *\n * @param version Version number to validate\n * @returns `true` if the version number is a valid semver version number, `false` otherwise.\n *\n * @example\n * ```\n * validate('1.0.0-rc.1'); // return true\n * validate('1.0-rc.1'); // return false\n * validate('foo'); // return false\n * ```\n */\nexport const validate = (version) => typeof version === 'string' && /^[v\\d]/.test(version) && semver.test(version);\n/**\n * Compare [semver](https://semver.org/) version strings using the specified operator.\n *\n * @param v1 First version to compare\n * @param v2 Second version to compare\n * @param operator Allowed arithmetic operator to use\n * @returns `true` if the comparison between the firstVersion and the secondVersion satisfies the operator, `false` otherwise.\n *\n * @example\n * ```\n * compare('10.1.8', '10.0.4', '>'); // return true\n * compare('10.0.1', '10.0.1', '='); // return true\n * compare('10.1.1', '10.2.2', '<'); // return true\n * compare('10.1.1', '10.2.2', '<='); // return true\n * compare('10.1.1', '10.2.2', '>='); // return false\n * ```\n */\nexport const compare = (v1, v2, operator) => {\n    // validate input operator\n    assertValidOperator(operator);\n    // since result of compareVersions can only be -1 or 0 or 1\n    // a simple map can be used to replace switch\n    const res = compareVersions(v1, v2);\n    return operatorResMap[operator].includes(res);\n};\n/**\n * Match [npm semver](https://docs.npmjs.com/cli/v6/using-npm/semver) version range.\n *\n * @param version Version number to match\n * @param range Range pattern for version\n * @returns `true` if the version number is within the range, `false` otherwise.\n *\n * @example\n * ```\n * satisfies('1.1.0', '^1.0.0'); // return true\n * satisfies('1.1.0', '~1.0.0'); // return false\n * ```\n */\nexport const satisfies = (version, range) => {\n    // handle multiple comparators\n    if (range.includes('||')) {\n        return range.split('||').some((r) => satisfies(version, r));\n    }\n    else if (range.includes(' ')) {\n        return range\n            .trim()\n            .replace(/\\s{2,}/g, ' ')\n            .split(' ')\n            .every((r) => satisfies(version, r));\n    }\n    // if no range operator then \"=\"\n    const m = range.match(/^([<>=~^]+)/);\n    const op = m ? m[1] : '=';\n    // if gt/lt/eq then operator compare\n    if (op !== '^' && op !== '~')\n        return compare(version, range, op);\n    // else range of either \"~\" or \"^\" is assumed\n    const [v1, v2, v3, , vp] = validateAndParse(version);\n    const [r1, r2, r3, , rp] = validateAndParse(range);\n    const v = [v1, v2, v3];\n    const r = [r1, r2 !== null && r2 !== void 0 ? r2 : 'x', r3 !== null && r3 !== void 0 ? r3 : 'x'];\n    // validate pre-release\n    if (rp) {\n        if (!vp)\n            return false;\n        if (compareSegments(v, r) !== 0)\n            return false;\n        if (compareSegments(vp.split('.'), rp.split('.')) === -1)\n            return false;\n    }\n    // first non-zero number\n    const nonZero = r.findIndex((v) => v !== '0') + 1;\n    // pointer to where segments can be >=\n    const i = op === '~' ? 2 : nonZero > 1 ? nonZero : 1;\n    // before pointer must be equal\n    if (compareSegments(v.slice(0, i), r.slice(0, i)) !== 0)\n        return false;\n    // after pointer must be >=\n    if (compareSegments(v.slice(i), r.slice(i)) === -1)\n        return false;\n    return true;\n};\nconst semver = /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\nconst validateAndParse = (version) => {\n    if (typeof version !== 'string') {\n        throw new TypeError('Invalid argument expected string');\n    }\n    const match = version.match(semver);\n    if (!match) {\n        throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n    }\n    match.shift();\n    return match;\n};\nconst isWildcard = (s) => s === '*' || s === 'x' || s === 'X';\nconst tryParse = (v) => {\n    const n = parseInt(v, 10);\n    return isNaN(n) ? v : n;\n};\nconst forceType = (a, b) => typeof a !== typeof b ? [String(a), String(b)] : [a, b];\nconst compareStrings = (a, b) => {\n    if (isWildcard(a) || isWildcard(b))\n        return 0;\n    const [ap, bp] = forceType(tryParse(a), tryParse(b));\n    if (ap > bp)\n        return 1;\n    if (ap < bp)\n        return -1;\n    return 0;\n};\nconst compareSegments = (a, b) => {\n    for (let i = 0; i < Math.max(a.length, b.length); i++) {\n        const r = compareStrings(a[i] || '0', b[i] || '0');\n        if (r !== 0)\n            return r;\n    }\n    return 0;\n};\nconst operatorResMap = {\n    '>': [1],\n    '>=': [0, 1],\n    '=': [0],\n    '<=': [-1, 0],\n    '<': [-1],\n};\nconst allowedOperators = Object.keys(operatorResMap);\nconst assertValidOperator = (op) => {\n    if (typeof op !== 'string') {\n        throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);\n    }\n    if (allowedOperators.indexOf(op) === -1) {\n        throw new Error(`Invalid operator, expected one of ${allowedOperators.join('|')}`);\n    }\n};\n//# sourceMappingURL=index.js.map","import { compareVersions } from \"compare-versions\";\n\nimport { Context, Condition, PlainCondition } from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\n\nexport function conditionIsMatched(condition: PlainCondition, context: Context): boolean {\n  const { attribute, operator, value } = condition;\n\n  if (operator === \"equals\") {\n    return context[attribute] === value;\n  } else if (operator === \"notEquals\") {\n    return context[attribute] !== value;\n  } else if (operator === \"before\" || operator === \"after\") {\n    // date comparisons\n    const valueInContext = context[attribute] as string | Date;\n\n    const dateInContext =\n      valueInContext instanceof Date ? valueInContext : new Date(valueInContext);\n    const dateInCondition = value instanceof Date ? value : new Date(value as string);\n\n    return operator === \"before\"\n      ? dateInContext < dateInCondition\n      : dateInContext > dateInCondition;\n  } else if (\n    Array.isArray(value) &&\n    ([\"string\", \"number\"].indexOf(typeof context[attribute]) !== -1 || context[attribute] === null)\n  ) {\n    // array\n    const valueInContext = context[attribute] as string;\n\n    if (operator === \"in\") {\n      return value.indexOf(valueInContext) !== -1;\n    } else if (operator === \"notIn\") {\n      return value.indexOf(valueInContext) === -1;\n    }\n  } else if (typeof context[attribute] === \"string\" && typeof value === \"string\") {\n    // string\n    const valueInContext = context[attribute] as string;\n\n    if (operator === \"contains\") {\n      return valueInContext.indexOf(value) !== -1;\n    } else if (operator === \"notContains\") {\n      return valueInContext.indexOf(value) === -1;\n    } else if (operator === \"startsWith\") {\n      return valueInContext.startsWith(value);\n    } else if (operator === \"endsWith\") {\n      return valueInContext.endsWith(value);\n    } else if (operator === \"semverEquals\") {\n      return compareVersions(valueInContext, value) === 0;\n    } else if (operator === \"semverNotEquals\") {\n      return compareVersions(valueInContext, value) !== 0;\n    } else if (operator === \"semverGreaterThan\") {\n      return compareVersions(valueInContext, value) === 1;\n    } else if (operator === \"semverGreaterThanOrEquals\") {\n      return compareVersions(valueInContext, value) >= 0;\n    } else if (operator === \"semverLessThan\") {\n      return compareVersions(valueInContext, value) === -1;\n    } else if (operator === \"semverLessThanOrEquals\") {\n      return compareVersions(valueInContext, value) <= 0;\n    }\n  } else if (typeof context[attribute] === \"number\" && typeof value === \"number\") {\n    // numeric\n    const valueInContext = context[attribute] as number;\n\n    if (operator === \"greaterThan\") {\n      return valueInContext > value;\n    } else if (operator === \"greaterThanOrEquals\") {\n      return valueInContext >= value;\n    } else if (operator === \"lessThan\") {\n      return valueInContext < value;\n    } else if (operator === \"lessThanOrEquals\") {\n      return valueInContext <= value;\n    }\n  }\n\n  return false;\n}\n\nexport function allConditionsAreMatched(\n  conditions: Condition[] | Condition,\n  context: Context,\n  logger: Logger,\n): boolean {\n  if (\"attribute\" in conditions) {\n    try {\n      return conditionIsMatched(conditions, context);\n    } catch (e) {\n      logger.warn(e.message, {\n        error: e,\n        details: {\n          condition: conditions,\n          context,\n        },\n      });\n\n      return false;\n    }\n  }\n\n  if (\"and\" in conditions && Array.isArray(conditions.and)) {\n    return conditions.and.every((c) => allConditionsAreMatched(c, context, logger));\n  }\n\n  if (\"or\" in conditions && Array.isArray(conditions.or)) {\n    return conditions.or.some((c) => allConditionsAreMatched(c, context, logger));\n  }\n\n  if (\"not\" in conditions && Array.isArray(conditions.not)) {\n    return conditions.not.every(\n      () =>\n        allConditionsAreMatched(\n          {\n            and: conditions.not,\n          },\n          context,\n          logger,\n        ) === false,\n    );\n  }\n\n  if (Array.isArray(conditions)) {\n    return conditions.every((c) => allConditionsAreMatched(c, context, logger));\n  }\n\n  return false;\n}\n","import { Context, GroupSegment, Segment, Condition } from \"@featurevisor/types\";\nimport { allConditionsAreMatched } from \"./conditions\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { Logger } from \"./logger\";\n\nexport function segmentIsMatched(segment: Segment, context: Context, logger: Logger): boolean {\n  return allConditionsAreMatched(segment.conditions as Condition | Condition[], context, logger);\n}\n\nexport function allGroupSegmentsAreMatched(\n  groupSegments: GroupSegment | GroupSegment[] | \"*\",\n  context: Context,\n  datafileReader: DatafileReader,\n  logger: Logger,\n): boolean {\n  if (groupSegments === \"*\") {\n    return true;\n  }\n\n  if (typeof groupSegments === \"string\") {\n    const segment = datafileReader.getSegment(groupSegments);\n\n    if (segment) {\n      return segmentIsMatched(segment, context, logger);\n    }\n\n    return false;\n  }\n\n  if (typeof groupSegments === \"object\") {\n    if (\"and\" in groupSegments && Array.isArray(groupSegments.and)) {\n      return groupSegments.and.every((groupSegment) =>\n        allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger),\n      );\n    }\n\n    if (\"or\" in groupSegments && Array.isArray(groupSegments.or)) {\n      return groupSegments.or.some((groupSegment) =>\n        allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger),\n      );\n    }\n\n    if (\"not\" in groupSegments && Array.isArray(groupSegments.not)) {\n      return groupSegments.not.every(\n        (groupSegment) =>\n          allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger) === false,\n      );\n    }\n  }\n\n  if (Array.isArray(groupSegments)) {\n    return groupSegments.every((groupSegment) =>\n      allGroupSegmentsAreMatched(groupSegment, context, datafileReader, logger),\n    );\n  }\n\n  return false;\n}\n","import { Allocation, Context, Traffic, Feature, Force } from \"@featurevisor/types\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { allGroupSegmentsAreMatched } from \"./segments\";\nimport { allConditionsAreMatched } from \"./conditions\";\nimport { Logger } from \"./logger\";\n\nexport function getMatchedAllocation(\n  traffic: Traffic,\n  bucketValue: number,\n): Allocation | undefined {\n  if (!traffic.allocation) {\n    return undefined;\n  }\n\n  for (const allocation of traffic.allocation) {\n    const [start, end] = allocation.range;\n\n    if (allocation.range && start <= bucketValue && end >= bucketValue) {\n      return allocation;\n    }\n  }\n\n  return undefined;\n}\n\nexport function parseFromStringifiedSegments(value) {\n  if (typeof value === \"string\" && (value.startsWith(\"{\") || value.startsWith(\"[\"))) {\n    return JSON.parse(value);\n  }\n\n  return value;\n}\n\nexport function getMatchedTraffic(\n  traffic: Traffic[],\n  context: Context,\n  datafileReader: DatafileReader,\n  logger: Logger,\n): Traffic | undefined {\n  const matchedTraffic = traffic.find((t) => {\n    if (\n      !allGroupSegmentsAreMatched(\n        parseFromStringifiedSegments(t.segments),\n        context,\n        datafileReader,\n        logger,\n      )\n    ) {\n      return false;\n    }\n\n    return true;\n  });\n\n  if (matchedTraffic && matchedTraffic.percentage > 0) {\n    return matchedTraffic;\n  }\n\n  return;\n}\n\nexport interface MatchedTrafficAndAllocation {\n  matchedTraffic: Traffic | undefined;\n  matchedAllocation: Allocation | undefined;\n}\n\nexport function getMatchedTrafficAndAllocation(\n  traffic: Traffic[],\n  context: Context,\n  bucketValue: number,\n  datafileReader: DatafileReader,\n  logger: Logger,\n): MatchedTrafficAndAllocation {\n  const matchedTraffic = traffic.find((t) => {\n    return allGroupSegmentsAreMatched(\n      parseFromStringifiedSegments(t.segments),\n      context,\n      datafileReader,\n      logger,\n    );\n  });\n\n  if (!matchedTraffic) {\n    return {\n      matchedTraffic: undefined,\n      matchedAllocation: undefined,\n    };\n  }\n\n  const matchedAllocation = getMatchedAllocation(matchedTraffic, bucketValue);\n\n  return {\n    matchedTraffic,\n    matchedAllocation,\n  };\n}\n\nexport interface ForceResult {\n  force?: Force;\n  forceIndex?: number;\n}\n\nexport function findForceFromFeature(\n  feature: Feature,\n  context: Context,\n  datafileReader: DatafileReader,\n  logger: Logger,\n): ForceResult {\n  const result: ForceResult = {\n    force: undefined,\n    forceIndex: undefined,\n  };\n\n  if (!feature.force) {\n    return result;\n  }\n\n  for (let i = 0; i < feature.force.length; i++) {\n    const currentForce = feature.force[i];\n\n    if (\n      currentForce.conditions &&\n      allConditionsAreMatched(currentForce.conditions, context, logger)\n    ) {\n      result.force = currentForce;\n      result.forceIndex = i;\n      break;\n    }\n\n    if (\n      currentForce.segments &&\n      allGroupSegmentsAreMatched(currentForce.segments, context, datafileReader, logger)\n    ) {\n      result.force = currentForce;\n      result.forceIndex = i;\n      break;\n    }\n  }\n\n  return result;\n}\n","import {\n  Feature,\n  FeatureKey,\n  Context,\n  BucketKey,\n  BucketValue,\n  RuleKey,\n  Traffic,\n  Force,\n  Required,\n  OverrideFeature,\n  Variation,\n  VariationValue,\n  VariableKey,\n  VariableValue,\n  VariableSchema,\n  StickyFeatures,\n  InitialFeatures,\n  Allocation,\n} from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { getBucket, ConfigureBucketKey, ConfigureBucketValue } from \"./bucket\";\nimport {\n  getMatchedTraffic,\n  getMatchedTrafficAndAllocation,\n  findForceFromFeature,\n  parseFromStringifiedSegments,\n} from \"./feature\";\nimport { allConditionsAreMatched } from \"./conditions\";\nimport { allGroupSegmentsAreMatched } from \"./segments\";\nimport type { Statuses, InterceptContext } from \"./instance\";\n\nexport enum EvaluationReason {\n  NOT_FOUND = \"not_found\",\n  NO_VARIATIONS = \"no_variations\",\n  NO_MATCH = \"no_match\",\n  DISABLED = \"disabled\",\n  REQUIRED = \"required\",\n  OUT_OF_RANGE = \"out_of_range\",\n  FORCED = \"forced\",\n  INITIAL = \"initial\",\n  STICKY = \"sticky\",\n  RULE = \"rule\",\n  ALLOCATED = \"allocated\",\n  DEFAULTED = \"defaulted\",\n  OVERRIDE = \"override\",\n  ERROR = \"error\",\n}\n\ntype EvaluationType = \"flag\" | \"variation\" | \"variable\";\n\nexport interface Evaluation {\n  // required\n  // type: EvaluationType; // @TODO: bring in later\n  featureKey: FeatureKey;\n  reason: EvaluationReason;\n\n  // common\n  bucketKey?: BucketKey;\n  bucketValue?: BucketValue;\n  ruleKey?: RuleKey;\n  error?: Error;\n  enabled?: boolean;\n  traffic?: Traffic;\n  forceIndex?: number;\n  force?: Force;\n  required?: Required[];\n  sticky?: OverrideFeature;\n  initial?: OverrideFeature;\n\n  // variation\n  variation?: Variation;\n  variationValue?: VariationValue;\n\n  // variable\n  variableKey?: VariableKey;\n  variableValue?: VariableValue;\n  variableSchema?: VariableSchema;\n}\n\nexport interface EvaluateOptions {\n  type: EvaluationType;\n\n  featureKey: FeatureKey | Feature;\n  variableKey?: VariableKey;\n  context: Context;\n\n  logger: Logger;\n  datafileReader: DatafileReader;\n  statuses?: Statuses;\n  interceptContext?: InterceptContext;\n\n  stickyFeatures?: StickyFeatures;\n  initialFeatures?: InitialFeatures;\n\n  bucketKeySeparator?: string;\n  configureBucketKey?: ConfigureBucketKey;\n  configureBucketValue?: ConfigureBucketValue;\n}\n\nexport function evaluate(options: EvaluateOptions): Evaluation {\n  let evaluation: Evaluation;\n  const {\n    type,\n    featureKey,\n    variableKey,\n    context,\n    logger,\n    datafileReader,\n    statuses,\n    stickyFeatures,\n    initialFeatures,\n    interceptContext,\n    bucketKeySeparator,\n    configureBucketKey,\n    configureBucketValue,\n  } = options;\n\n  try {\n    const key = typeof featureKey === \"string\" ? featureKey : featureKey.key;\n\n    /**\n     * Root flag evaluation\n     */\n    let flag: Evaluation;\n    if (type !== \"flag\") {\n      // needed by variation and variable evaluations\n      flag = evaluate({\n        type: \"flag\",\n        featureKey: key,\n        context,\n        logger,\n        datafileReader,\n        statuses,\n        stickyFeatures,\n        initialFeatures,\n        bucketKeySeparator,\n        configureBucketKey,\n        configureBucketValue,\n      });\n\n      if (flag.enabled === false) {\n        evaluation = {\n          featureKey: key,\n          reason: EvaluationReason.DISABLED,\n        };\n\n        logger.debug(\"feature is disabled\", evaluation);\n\n        return evaluation;\n      }\n    }\n\n    /**\n     * Sticky\n     */\n    if (stickyFeatures && stickyFeatures[key]) {\n      // flag\n      if (type === \"flag\" && typeof stickyFeatures[key].enabled !== \"undefined\") {\n        evaluation = {\n          featureKey: key,\n          reason: EvaluationReason.STICKY,\n          sticky: stickyFeatures[key],\n          enabled: stickyFeatures[key].enabled,\n        };\n\n        logger.debug(\"using sticky enabled\", evaluation);\n\n        return evaluation;\n      }\n\n      // variation\n      if (type === \"variation\") {\n        const variationValue = stickyFeatures[key].variation;\n\n        if (typeof variationValue !== \"undefined\") {\n          evaluation = {\n            featureKey: key,\n            reason: EvaluationReason.STICKY,\n            variationValue,\n          };\n\n          logger.debug(\"using sticky variation\", evaluation);\n\n          return evaluation;\n        }\n      }\n\n      // variable\n      if (variableKey) {\n        const variables = stickyFeatures[key].variables;\n\n        if (variables) {\n          const result = variables[variableKey];\n\n          if (typeof result !== \"undefined\") {\n            evaluation = {\n              featureKey: key,\n              reason: EvaluationReason.STICKY,\n              variableKey,\n              variableValue: result,\n            };\n\n            logger.debug(\"using sticky variable\", evaluation);\n\n            return evaluation;\n          }\n        }\n      }\n    }\n\n    /**\n     * Initial\n     */\n    if (statuses && !statuses.ready && initialFeatures && initialFeatures[key]) {\n      // flag\n      if (type === \"flag\" && typeof initialFeatures[key].enabled !== \"undefined\") {\n        evaluation = {\n          featureKey: key,\n          reason: EvaluationReason.INITIAL,\n          initial: initialFeatures[key],\n          enabled: initialFeatures[key].enabled,\n        };\n\n        logger.debug(\"using initial enabled\", evaluation);\n\n        return evaluation;\n      }\n\n      // variation\n      if (type === \"variation\" && typeof initialFeatures[key].variation !== \"undefined\") {\n        const variationValue = initialFeatures[key].variation;\n\n        evaluation = {\n          featureKey: key,\n          reason: EvaluationReason.INITIAL,\n          variationValue,\n        };\n\n        logger.debug(\"using initial variation\", evaluation);\n\n        return evaluation;\n      }\n\n      // variable\n      if (variableKey) {\n        const variables = initialFeatures[key].variables;\n\n        if (variables) {\n          if (typeof variables[variableKey] !== \"undefined\") {\n            evaluation = {\n              featureKey: key,\n              reason: EvaluationReason.INITIAL,\n              variableKey,\n              variableValue: variables[variableKey],\n            };\n\n            logger.debug(\"using initial variable\", evaluation);\n\n            return evaluation;\n          }\n        }\n      }\n    }\n\n    /**\n     * Feature\n     */\n    const feature =\n      typeof featureKey === \"string\" ? datafileReader.getFeature(featureKey) : featureKey;\n\n    // feature: not found\n    if (!feature) {\n      evaluation = {\n        featureKey: key,\n        reason: EvaluationReason.NOT_FOUND, // @TODO: make it type-specific\n      };\n\n      logger.warn(\"feature not found\", evaluation);\n\n      return evaluation;\n    }\n\n    // feature: deprecated\n    if (type === \"flag\" && feature.deprecated) {\n      logger.warn(\"feature is deprecated\", { featureKey: feature.key });\n    }\n\n    // variableSchema\n    let variableSchema: VariableSchema | undefined;\n\n    if (variableKey) {\n      if (feature.variablesSchema && feature.variablesSchema[variableKey]) {\n        variableSchema = feature.variablesSchema[variableKey];\n      }\n\n      // variable schema not found\n      if (!variableSchema) {\n        evaluation = {\n          featureKey: key,\n          reason: EvaluationReason.NOT_FOUND,\n          variableKey,\n        };\n\n        logger.warn(\"variable schema not found\", evaluation);\n\n        return evaluation;\n      }\n\n      if (variableSchema.deprecated) {\n        logger.warn(\"variable is deprecated\", {\n          featureKey: feature.key,\n          variableKey,\n        });\n      }\n    }\n\n    // variation: no variations\n    if (type === \"variation\" && (!feature.variations || feature.variations.length === 0)) {\n      evaluation = {\n        featureKey: key,\n        reason: EvaluationReason.NO_VARIATIONS,\n      };\n\n      logger.warn(\"no variations\", evaluation);\n\n      return evaluation;\n    }\n\n    const finalContext = interceptContext ? interceptContext(context) : context;\n\n    /**\n     * Forced\n     */\n    const { force, forceIndex } = findForceFromFeature(feature, context, datafileReader, logger);\n\n    if (force) {\n      // flag\n      if (type === \"flag\" && typeof force.enabled !== \"undefined\") {\n        evaluation = {\n          featureKey: feature.key,\n          reason: EvaluationReason.FORCED,\n          forceIndex,\n          force,\n          enabled: force.enabled,\n        };\n\n        logger.debug(\"forced enabled found\", evaluation);\n\n        return evaluation;\n      }\n\n      // variation\n      if (type === \"variation\" && force.variation && feature.variations) {\n        const variation = feature.variations.find((v) => v.value === force.variation);\n\n        if (variation) {\n          evaluation = {\n            featureKey: feature.key,\n            reason: EvaluationReason.FORCED,\n            forceIndex,\n            force,\n            variation,\n          };\n\n          logger.debug(\"forced variation found\", evaluation);\n\n          return evaluation;\n        }\n      }\n\n      // variable\n      if (variableKey && force.variables && typeof force.variables[variableKey] !== \"undefined\") {\n        evaluation = {\n          featureKey: feature.key,\n          reason: EvaluationReason.FORCED,\n          forceIndex,\n          force,\n          variableKey,\n          variableSchema,\n          variableValue: force.variables[variableKey],\n        };\n\n        logger.debug(\"forced variable\", evaluation);\n\n        return evaluation;\n      }\n    }\n\n    /**\n     * Required\n     */\n    if (type === \"flag\" && feature.required && feature.required.length > 0) {\n      const requiredFeaturesAreEnabled = feature.required.every((required) => {\n        let requiredKey;\n        let requiredVariation;\n\n        if (typeof required === \"string\") {\n          requiredKey = required;\n        } else {\n          requiredKey = required.key;\n          requiredVariation = required.variation;\n        }\n\n        const requiredEvaluation = evaluate({\n          type: \"flag\",\n          featureKey: requiredKey,\n          context: finalContext,\n          logger,\n          datafileReader,\n          statuses,\n          stickyFeatures,\n          initialFeatures,\n          bucketKeySeparator,\n          configureBucketKey,\n          configureBucketValue,\n        });\n        const requiredIsEnabled = requiredEvaluation.enabled;\n\n        if (!requiredIsEnabled) {\n          return false;\n        }\n\n        if (typeof requiredVariation !== \"undefined\") {\n          const requiredVariationEvaluation = evaluate({\n            type: \"variation\",\n            featureKey: requiredKey,\n            context: finalContext,\n            logger,\n            datafileReader,\n            statuses,\n            stickyFeatures,\n            initialFeatures,\n            bucketKeySeparator,\n            configureBucketKey,\n            configureBucketValue,\n          });\n\n          let requiredVariationValue;\n\n          if (requiredVariationEvaluation.variationValue) {\n            requiredVariationValue = requiredVariationEvaluation.variationValue;\n          } else if (requiredVariationEvaluation.variation) {\n            requiredVariationValue = requiredVariationEvaluation.variation.value;\n          }\n\n          return requiredVariationValue === requiredVariation;\n        }\n\n        return true;\n      });\n\n      if (!requiredFeaturesAreEnabled) {\n        evaluation = {\n          featureKey: feature.key,\n          reason: EvaluationReason.REQUIRED,\n          required: feature.required,\n          enabled: requiredFeaturesAreEnabled,\n        };\n\n        logger.debug(\"required features not enabled\", evaluation);\n\n        return evaluation;\n      }\n    }\n\n    /**\n     * Bucketing\n     */\n    const { bucketKey, bucketValue } = getBucket({\n      feature,\n      context: finalContext,\n      logger,\n      bucketKeySeparator,\n      configureBucketKey,\n      configureBucketValue,\n    });\n\n    let matchedTraffic: Traffic | undefined;\n    let matchedAllocation: Allocation | undefined;\n\n    if (type !== \"flag\") {\n      const matched = getMatchedTrafficAndAllocation(\n        feature.traffic,\n        finalContext,\n        bucketValue,\n        datafileReader,\n        logger,\n      );\n\n      matchedTraffic = matched.matchedTraffic;\n      matchedAllocation = matched.matchedAllocation;\n    } else {\n      matchedTraffic = getMatchedTraffic(feature.traffic, finalContext, datafileReader, logger);\n    }\n\n    if (matchedTraffic) {\n      // flag\n      if (type === \"flag\") {\n        // flag: check if mutually exclusive\n        if (feature.ranges && feature.ranges.length > 0) {\n          const matchedRange = feature.ranges.find((range) => {\n            return bucketValue >= range[0] && bucketValue < range[1];\n          });\n\n          // matched\n          if (matchedRange) {\n            evaluation = {\n              featureKey: feature.key,\n              reason: EvaluationReason.ALLOCATED,\n              bucketKey,\n              bucketValue,\n              ruleKey: matchedTraffic.key,\n              traffic: matchedTraffic,\n              enabled:\n                typeof matchedTraffic.enabled === \"undefined\" ? true : matchedTraffic.enabled,\n            };\n\n            logger.debug(\"matched\", evaluation);\n\n            return evaluation;\n          }\n\n          // no match\n          evaluation = {\n            featureKey: feature.key,\n            reason: EvaluationReason.OUT_OF_RANGE,\n            bucketKey,\n            bucketValue,\n            enabled: false,\n          };\n\n          logger.debug(\"not matched\", evaluation);\n\n          return evaluation;\n        }\n\n        // flag: override from rule\n        if (typeof matchedTraffic.enabled !== \"undefined\") {\n          evaluation = {\n            featureKey: feature.key,\n            reason: EvaluationReason.OVERRIDE,\n            bucketKey,\n            bucketValue,\n            ruleKey: matchedTraffic.key,\n            traffic: matchedTraffic,\n            enabled: matchedTraffic.enabled,\n          };\n\n          logger.debug(\"override from rule\", evaluation);\n\n          return evaluation;\n        }\n\n        // treated as enabled because of matched traffic\n        if (bucketValue <= matchedTraffic.percentage) {\n          evaluation = {\n            featureKey: feature.key,\n            reason: EvaluationReason.RULE,\n            bucketKey,\n            bucketValue,\n            ruleKey: matchedTraffic.key,\n            traffic: matchedTraffic,\n            enabled: true,\n          };\n\n          logger.debug(\"matched traffic\", evaluation);\n\n          return evaluation;\n        }\n      }\n\n      // variation\n      if (type === \"variation\" && feature.variations) {\n        // override from rule\n        if (matchedTraffic.variation) {\n          const variation = feature.variations.find((v) => v.value === matchedTraffic.variation);\n\n          if (variation) {\n            evaluation = {\n              featureKey: feature.key,\n              reason: EvaluationReason.RULE,\n              bucketKey,\n              bucketValue,\n              ruleKey: matchedTraffic.key,\n              traffic: matchedTraffic,\n              variation,\n            };\n\n            logger.debug(\"override from rule\", evaluation);\n\n            return evaluation;\n          }\n        }\n\n        // regular allocation\n        if (matchedAllocation && matchedAllocation.variation) {\n          const variation = feature.variations.find((v) => v.value === matchedAllocation.variation);\n\n          if (variation) {\n            evaluation = {\n              featureKey: feature.key,\n              reason: EvaluationReason.ALLOCATED,\n              bucketKey,\n              bucketValue,\n              ruleKey: matchedTraffic.key,\n              traffic: matchedTraffic,\n              variation,\n            };\n\n            logger.debug(\"allocated variation\", evaluation);\n\n            return evaluation;\n          }\n        }\n      }\n    }\n\n    // variable\n    if (type === \"variable\" && variableKey) {\n      // override from rule\n      if (\n        matchedTraffic &&\n        matchedTraffic.variables &&\n        typeof matchedTraffic.variables[variableKey] !== \"undefined\"\n      ) {\n        evaluation = {\n          featureKey: feature.key,\n          reason: EvaluationReason.RULE,\n          bucketKey,\n          bucketValue,\n          ruleKey: matchedTraffic.key,\n          traffic: matchedTraffic,\n          variableKey,\n          variableSchema,\n          variableValue: matchedTraffic.variables[variableKey],\n        };\n\n        logger.debug(\"override from rule\", evaluation);\n\n        return evaluation;\n      }\n\n      // check variations\n      let variationValue;\n\n      if (force && force.variation) {\n        variationValue = force.variation;\n      } else if (matchedTraffic && matchedTraffic.variation) {\n        variationValue = matchedTraffic.variation;\n      } else if (matchedAllocation && matchedAllocation.variation) {\n        variationValue = matchedAllocation.variation;\n      }\n\n      if (variationValue && Array.isArray(feature.variations)) {\n        const variation = feature.variations.find((v) => v.value === variationValue);\n\n        if (variation && variation.variables) {\n          const variableFromVariation = variation.variables.find((v) => v.key === variableKey);\n\n          if (variableFromVariation) {\n            if (variableFromVariation.overrides) {\n              const override = variableFromVariation.overrides.find((o) => {\n                if (o.conditions) {\n                  return allConditionsAreMatched(\n                    typeof o.conditions === \"string\" ? JSON.parse(o.conditions) : o.conditions,\n                    finalContext,\n                    logger,\n                  );\n                }\n\n                if (o.segments) {\n                  return allGroupSegmentsAreMatched(\n                    parseFromStringifiedSegments(o.segments),\n                    finalContext,\n                    datafileReader,\n                    logger,\n                  );\n                }\n\n                return false;\n              });\n\n              if (override) {\n                evaluation = {\n                  featureKey: feature.key,\n                  reason: EvaluationReason.OVERRIDE,\n                  bucketKey,\n                  bucketValue,\n                  ruleKey: matchedTraffic?.key,\n                  traffic: matchedTraffic,\n                  variableKey,\n                  variableSchema,\n                  variableValue: override.value,\n                };\n\n                logger.debug(\"variable override\", evaluation);\n\n                return evaluation;\n              }\n            }\n\n            if (typeof variableFromVariation.value !== \"undefined\") {\n              evaluation = {\n                featureKey: feature.key,\n                reason: EvaluationReason.ALLOCATED,\n                bucketKey,\n                bucketValue,\n                ruleKey: matchedTraffic?.key,\n                traffic: matchedTraffic,\n                variableKey,\n                variableSchema,\n                variableValue: variableFromVariation.value,\n              };\n\n              logger.debug(\"allocated variable\", evaluation);\n\n              return evaluation;\n            }\n          }\n        }\n      }\n    }\n\n    /**\n     * Nothing matched\n     */\n    if (type === \"variation\") {\n      evaluation = {\n        featureKey: feature.key,\n        reason: EvaluationReason.NO_MATCH,\n        bucketKey,\n        bucketValue,\n      };\n\n      logger.debug(\"no matched variation\", evaluation);\n\n      return evaluation;\n    }\n\n    if (type === \"variable\" && variableSchema) {\n      evaluation = {\n        featureKey: feature.key,\n        reason: EvaluationReason.DEFAULTED,\n        bucketKey,\n        bucketValue,\n        variableKey,\n        variableSchema,\n        variableValue: variableSchema.defaultValue,\n      };\n\n      logger.debug(\"using default value\", evaluation);\n\n      return evaluation;\n    }\n\n    evaluation = {\n      featureKey: feature.key,\n      reason: EvaluationReason.NO_MATCH,\n      bucketKey,\n      bucketValue,\n      enabled: false,\n    };\n\n    logger.debug(\"nothing matched\", evaluation);\n\n    return evaluation;\n  } catch (e) {\n    evaluation = {\n      featureKey: typeof featureKey === \"string\" ? featureKey : featureKey.key,\n      reason: EvaluationReason.ERROR,\n      error: e,\n    };\n\n    logger.error(\"error\", evaluation);\n\n    return evaluation;\n  }\n}\n","import {\n  Context,\n  DatafileContent,\n  Feature,\n  FeatureKey,\n  InitialFeatures,\n  StickyFeatures,\n  VariableType,\n  VariableValue,\n  VariationValue,\n  VariableKey,\n} from \"@featurevisor/types\";\n\nimport { createLogger, Logger, LogLevel } from \"./logger\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { Emitter } from \"./emitter\";\nimport { ConfigureBucketKey, ConfigureBucketValue } from \"./bucket\";\nimport { Evaluation, evaluate } from \"./evaluate\";\n\nexport type ReadyCallback = () => void;\n\nexport type ActivationCallback = (\n  featureName: string,\n  variation: VariationValue,\n  context: Context,\n  captureContext: Context,\n) => void;\n\nexport interface Statuses {\n  ready: boolean;\n  refreshInProgress: boolean;\n}\n\nconst DEFAULT_BUCKET_KEY_SEPARATOR = \".\";\n\nexport type InterceptContext = (context: Context) => Context;\n\nexport interface InstanceOptions {\n  bucketKeySeparator?: string;\n  configureBucketKey?: ConfigureBucketKey;\n  configureBucketValue?: ConfigureBucketValue;\n  datafile?: DatafileContent | string;\n  datafileUrl?: string;\n  handleDatafileFetch?: (datafileUrl: string) => Promise<DatafileContent>;\n  initialFeatures?: InitialFeatures;\n  interceptContext?: InterceptContext;\n  logger?: Logger;\n  onActivation?: ActivationCallback;\n  onReady?: ReadyCallback;\n  onRefresh?: () => void;\n  onUpdate?: () => void;\n  refreshInterval?: number; // seconds\n  stickyFeatures?: StickyFeatures;\n}\n\nconst emptyDatafile: DatafileContent = {\n  schemaVersion: \"1\",\n  revision: \"unknown\",\n  attributes: [],\n  segments: [],\n  features: [],\n};\n\nexport type DatafileFetchHandler = (datafileUrl: string) => Promise<DatafileContent>;\n\nfunction fetchDatafileContent(\n  datafileUrl,\n  handleDatafileFetch?: DatafileFetchHandler,\n): Promise<DatafileContent> {\n  if (handleDatafileFetch) {\n    return handleDatafileFetch(datafileUrl);\n  }\n\n  return fetch(datafileUrl).then((res) => res.json());\n}\n\ntype FieldType = string | VariableType;\ntype ValueType = VariableValue;\n\nexport function getValueByType(value: ValueType, fieldType: FieldType): ValueType {\n  try {\n    if (value === undefined) {\n      return undefined;\n    }\n\n    switch (fieldType) {\n      case \"string\":\n        return typeof value === \"string\" ? value : undefined;\n      case \"integer\":\n        return parseInt(value as string, 10);\n      case \"double\":\n        return parseFloat(value as string);\n      case \"boolean\":\n        return value === true;\n      case \"array\":\n        return Array.isArray(value) ? value : undefined;\n      case \"object\":\n        return typeof value === \"object\" ? value : undefined;\n      // @NOTE: `json` is not handled here intentionally\n      default:\n        return value;\n    }\n  } catch (e) {\n    return undefined;\n  }\n}\n\nexport class FeaturevisorInstance {\n  // from options\n  private bucketKeySeparator: string;\n  private configureBucketKey?: ConfigureBucketKey;\n  private configureBucketValue?: ConfigureBucketValue;\n  private datafileUrl?: string;\n  private handleDatafileFetch?: DatafileFetchHandler;\n  private initialFeatures?: InitialFeatures;\n  private interceptContext?: InterceptContext;\n  private logger: Logger;\n  private refreshInterval?: number; // seconds\n  private stickyFeatures?: StickyFeatures;\n\n  // internally created\n  private datafileReader: DatafileReader;\n  private emitter: Emitter;\n  private statuses: Statuses;\n  private intervalId?: ReturnType<typeof setInterval>;\n\n  // exposed from emitter\n  public on: Emitter[\"addListener\"];\n  public addListener: Emitter[\"addListener\"];\n  public off: Emitter[\"removeListener\"];\n  public removeListener: Emitter[\"removeListener\"];\n  public removeAllListeners: Emitter[\"removeAllListeners\"];\n\n  constructor(options: InstanceOptions) {\n    // from options\n    this.bucketKeySeparator = options.bucketKeySeparator || DEFAULT_BUCKET_KEY_SEPARATOR;\n    this.configureBucketKey = options.configureBucketKey;\n    this.configureBucketValue = options.configureBucketValue;\n    this.datafileUrl = options.datafileUrl;\n    this.handleDatafileFetch = options.handleDatafileFetch;\n    this.initialFeatures = options.initialFeatures;\n    this.interceptContext = options.interceptContext;\n    this.logger = options.logger || createLogger();\n    this.refreshInterval = options.refreshInterval;\n    this.stickyFeatures = options.stickyFeatures;\n\n    // internal\n    this.emitter = new Emitter();\n    this.statuses = {\n      ready: false,\n      refreshInProgress: false,\n    };\n\n    // register events\n    if (options.onReady) {\n      this.emitter.addListener(\"ready\", options.onReady);\n    }\n\n    if (options.onRefresh) {\n      this.emitter.addListener(\"refresh\", options.onRefresh);\n    }\n\n    if (options.onUpdate) {\n      this.emitter.addListener(\"update\", options.onUpdate);\n    }\n\n    if (options.onActivation) {\n      this.emitter.addListener(\"activation\", options.onActivation);\n    }\n\n    // expose emitter methods\n    const on = this.emitter.addListener.bind(this.emitter);\n    this.on = on;\n    this.addListener = on;\n\n    const off = this.emitter.removeListener.bind(this.emitter);\n    this.off = off;\n    this.removeListener = off;\n\n    this.removeAllListeners = this.emitter.removeAllListeners.bind(this.emitter);\n\n    // datafile\n    if (options.datafileUrl) {\n      this.setDatafile(options.datafile || emptyDatafile);\n\n      fetchDatafileContent(options.datafileUrl, options.handleDatafileFetch)\n        .then((datafile) => {\n          this.setDatafile(datafile);\n\n          this.statuses.ready = true;\n          this.emitter.emit(\"ready\");\n\n          if (this.refreshInterval) {\n            this.startRefreshing();\n          }\n        })\n        .catch((e) => {\n          this.logger.error(\"failed to fetch datafile\", { error: e });\n        });\n    } else if (options.datafile) {\n      this.setDatafile(options.datafile);\n      this.statuses.ready = true;\n\n      setTimeout(() => {\n        this.emitter.emit(\"ready\");\n      }, 0);\n    } else {\n      throw new Error(\n        \"Featurevisor SDK instance cannot be created without both `datafile` and `datafileUrl` options\",\n      );\n    }\n  }\n\n  setLogLevels(levels: LogLevel[]) {\n    this.logger.setLevels(levels);\n  }\n\n  onReady(): Promise<FeaturevisorInstance> {\n    return new Promise((resolve) => {\n      if (this.statuses.ready) {\n        return resolve(this);\n      }\n\n      const cb = () => {\n        this.emitter.removeListener(\"ready\", cb);\n\n        resolve(this);\n      };\n\n      this.emitter.addListener(\"ready\", cb);\n    });\n  }\n\n  setDatafile(datafile: DatafileContent | string) {\n    try {\n      this.datafileReader = new DatafileReader(\n        typeof datafile === \"string\" ? JSON.parse(datafile) : datafile,\n      );\n    } catch (e) {\n      this.logger.error(\"could not parse datafile\", { error: e });\n    }\n  }\n\n  setStickyFeatures(stickyFeatures: StickyFeatures | undefined) {\n    this.stickyFeatures = stickyFeatures;\n  }\n\n  getRevision(): string {\n    return this.datafileReader.getRevision();\n  }\n\n  getFeature(featureKey: string | Feature): Feature | undefined {\n    return typeof featureKey === \"string\"\n      ? this.datafileReader.getFeature(featureKey) // only key provided\n      : featureKey; // full feature provided\n  }\n\n  /**\n   * Statuses\n   */\n  isReady(): boolean {\n    return this.statuses.ready;\n  }\n\n  /**\n   * Refresh\n   */\n  refresh() {\n    this.logger.debug(\"refreshing datafile\");\n\n    if (this.statuses.refreshInProgress) {\n      return this.logger.warn(\"refresh in progress, skipping\");\n    }\n\n    if (!this.datafileUrl) {\n      return this.logger.error(\"cannot refresh since `datafileUrl` is not provided\");\n    }\n\n    this.statuses.refreshInProgress = true;\n\n    fetchDatafileContent(this.datafileUrl, this.handleDatafileFetch)\n      .then((datafile) => {\n        const currentRevision = this.getRevision();\n        const newRevision = datafile.revision;\n        const isNotSameRevision = currentRevision !== newRevision;\n\n        this.setDatafile(datafile);\n        this.logger.info(\"refreshed datafile\");\n\n        this.emitter.emit(\"refresh\");\n\n        if (isNotSameRevision) {\n          this.emitter.emit(\"update\");\n        }\n\n        this.statuses.refreshInProgress = false;\n      })\n      .catch((e) => {\n        this.logger.error(\"failed to refresh datafile\", { error: e });\n        this.statuses.refreshInProgress = false;\n      });\n  }\n\n  startRefreshing() {\n    if (!this.datafileUrl) {\n      return this.logger.error(\"cannot start refreshing since `datafileUrl` is not provided\");\n    }\n\n    if (this.intervalId) {\n      return this.logger.warn(\"refreshing has already started\");\n    }\n\n    if (!this.refreshInterval) {\n      return this.logger.warn(\"no `refreshInterval` option provided\");\n    }\n\n    this.intervalId = setInterval(() => {\n      this.refresh();\n    }, this.refreshInterval * 1000);\n  }\n\n  stopRefreshing() {\n    if (!this.intervalId) {\n      return this.logger.warn(\"refreshing has not started yet\");\n    }\n\n    clearInterval(this.intervalId);\n  }\n\n  /**\n   * Flag\n   */\n  evaluateFlag(featureKey: FeatureKey | Feature, context: Context = {}): Evaluation {\n    return evaluate({\n      type: \"flag\",\n\n      featureKey,\n      context,\n\n      logger: this.logger,\n      datafileReader: this.datafileReader,\n      statuses: this.statuses,\n      interceptContext: this.interceptContext,\n\n      stickyFeatures: this.stickyFeatures,\n      initialFeatures: this.initialFeatures,\n\n      bucketKeySeparator: this.bucketKeySeparator,\n      configureBucketKey: this.configureBucketKey,\n      configureBucketValue: this.configureBucketValue,\n    });\n  }\n\n  isEnabled(featureKey: FeatureKey | Feature, context: Context = {}): boolean {\n    try {\n      const evaluation = this.evaluateFlag(featureKey, context);\n\n      return evaluation.enabled === true;\n    } catch (e) {\n      this.logger.error(\"isEnabled\", { featureKey, error: e });\n\n      return false;\n    }\n  }\n\n  /**\n   * Variation\n   */\n  evaluateVariation(featureKey: FeatureKey | Feature, context: Context = {}): Evaluation {\n    return evaluate({\n      type: \"variation\",\n\n      featureKey,\n      context,\n\n      logger: this.logger,\n      datafileReader: this.datafileReader,\n      statuses: this.statuses,\n      interceptContext: this.interceptContext,\n\n      stickyFeatures: this.stickyFeatures,\n      initialFeatures: this.initialFeatures,\n\n      bucketKeySeparator: this.bucketKeySeparator,\n      configureBucketKey: this.configureBucketKey,\n      configureBucketValue: this.configureBucketValue,\n    });\n  }\n\n  getVariation(\n    featureKey: FeatureKey | Feature,\n    context: Context = {},\n  ): VariationValue | undefined {\n    try {\n      const evaluation = this.evaluateVariation(featureKey, context);\n\n      if (typeof evaluation.variationValue !== \"undefined\") {\n        return evaluation.variationValue;\n      }\n\n      if (evaluation.variation) {\n        return evaluation.variation.value;\n      }\n\n      return undefined;\n    } catch (e) {\n      this.logger.error(\"getVariation\", { featureKey, error: e });\n\n      return undefined;\n    }\n  }\n\n  /**\n   * Activate\n   */\n  activate(featureKey: FeatureKey, context: Context = {}): VariationValue | undefined {\n    try {\n      const evaluation = this.evaluateVariation(featureKey, context);\n      const variationValue = evaluation.variation\n        ? evaluation.variation.value\n        : evaluation.variationValue;\n\n      if (typeof variationValue === \"undefined\") {\n        return undefined;\n      }\n\n      const finalContext = this.interceptContext ? this.interceptContext(context) : context;\n\n      const captureContext: Context = {};\n\n      const attributesForCapturing = this.datafileReader\n        .getAllAttributes()\n        .filter((a) => a.capture === true);\n\n      attributesForCapturing.forEach((a) => {\n        if (typeof finalContext[a.key] !== \"undefined\") {\n          captureContext[a.key] = context[a.key];\n        }\n      });\n\n      this.emitter.emit(\n        \"activation\",\n        featureKey,\n        variationValue,\n        finalContext,\n        captureContext,\n        evaluation,\n      );\n\n      return variationValue;\n    } catch (e) {\n      this.logger.error(\"activate\", { featureKey, error: e });\n\n      return undefined;\n    }\n  }\n\n  /**\n   * Variable\n   */\n  evaluateVariable(\n    featureKey: FeatureKey | Feature,\n    variableKey: VariableKey,\n    context: Context = {},\n  ): Evaluation {\n    return evaluate({\n      type: \"variable\",\n\n      featureKey,\n      variableKey,\n      context,\n\n      logger: this.logger,\n      datafileReader: this.datafileReader,\n      statuses: this.statuses,\n      interceptContext: this.interceptContext,\n\n      stickyFeatures: this.stickyFeatures,\n      initialFeatures: this.initialFeatures,\n\n      bucketKeySeparator: this.bucketKeySeparator,\n      configureBucketKey: this.configureBucketKey,\n      configureBucketValue: this.configureBucketValue,\n    });\n  }\n\n  getVariable(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): VariableValue | undefined {\n    try {\n      const evaluation = this.evaluateVariable(featureKey, variableKey, context);\n\n      if (typeof evaluation.variableValue !== \"undefined\") {\n        if (\n          evaluation.variableSchema &&\n          evaluation.variableSchema.type === \"json\" &&\n          typeof evaluation.variableValue === \"string\"\n        ) {\n          return JSON.parse(evaluation.variableValue);\n        }\n\n        return evaluation.variableValue;\n      }\n\n      return undefined;\n    } catch (e) {\n      this.logger.error(\"getVariable\", { featureKey, variableKey, error: e });\n\n      return undefined;\n    }\n  }\n\n  getVariableBoolean(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): boolean | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"boolean\") as boolean | undefined;\n  }\n\n  getVariableString(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): string | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"string\") as string | undefined;\n  }\n\n  getVariableInteger(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): number | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"integer\") as number | undefined;\n  }\n\n  getVariableDouble(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): number | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"double\") as number | undefined;\n  }\n\n  getVariableArray(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): string[] | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"array\") as string[] | undefined;\n  }\n\n  getVariableObject<T>(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): T | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"object\") as T | undefined;\n  }\n\n  getVariableJSON<T>(\n    featureKey: FeatureKey | Feature,\n    variableKey: string,\n    context: Context = {},\n  ): T | undefined {\n    const variableValue = this.getVariable(featureKey, variableKey, context);\n\n    return getValueByType(variableValue, \"json\") as T | undefined;\n  }\n}\n\nexport function createInstance(options: InstanceOptions): FeaturevisorInstance {\n  return new FeaturevisorInstance(options);\n}\n"],"names":["createBuffer","val","TextEncoder","encode","MurmurHashV3","key","seed","remainder","bytes","h1","h1b","c1","c2","k1","i","length","murmur","v2","str","k","l","h","v3","module","exports","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","HASH_SEED","MAX_HASH_VALUE","Math","pow","MAX_BUCKETED_NUMBER","getBucketedNumber","bucketKey","ratio","murmurhash","floor","getBucketKey","options","feature","context","logger","bucketKeySeparator","configureBucketKey","featureKey","type","attributeKeys","bucketBy","Array","isArray","or","error","Error","forEach","attributeKey","attributeValue","push","result","join","getBucket","configureBucketValue","value","bucketValue","loggerPrefix","defaultLogLevels","defaultLogHandler","level","message","details","console","log","info","warn","Logger","constructor","this","levels","handle","handler","setLevels","indexOf","debug","createLogger","logHandler","DatafileReader","datafileJson","schemaVersion","revision","datafileJsonV2","attributes","segments","features","datafileJsonV1","a","s","f","variablesSchema","reduce","acc","variable","getRevision","getSchemaVersion","getAllAttributes","keys","getAttribute","getSegment","segmentKey","segment","record","JSON","parse","e","parseJsonConditionsIfStringified","getFeature","Emitter","_listeners","addListener","eventName","fn","removeListener","index","splice","removeAllListeners","emit","args","compareVersions","v1","n1","validateAndParse","n2","p1","pop","p2","r","compareSegments","split","semver","version","TypeError","match","shift","isWildcard","tryParse","v","n","parseInt","isNaN","compareStrings","b","ap","bp","String","forceType","max","conditionIsMatched","condition","attribute","operator","valueInContext","dateInContext","Date","dateInCondition","startsWith","endsWith","allConditionsAreMatched","conditions","and","every","c","some","not","allGroupSegmentsAreMatched","groupSegments","datafileReader","segmentIsMatched","groupSegment","parseFromStringifiedSegments","EvaluationReason","evaluate","evaluation","variableKey","statuses","stickyFeatures","initialFeatures","interceptContext","flag","enabled","reason","DISABLED","STICKY","sticky","variationValue","variation","variables","variableValue","ready","INITIAL","initial","NOT_FOUND","variableSchema","deprecated","variations","NO_VARIATIONS","finalContext","force","forceIndex","currentForce","findForceFromFeature","FORCED","find","required","requiredFeaturesAreEnabled","requiredKey","requiredVariation","requiredVariationEvaluation","requiredVariationValue","REQUIRED","matchedTraffic","matchedAllocation","matched","traffic","t","allocation","start","end","range","getMatchedAllocation","getMatchedTrafficAndAllocation","percentage","getMatchedTraffic","ranges","ALLOCATED","ruleKey","OUT_OF_RANGE","OVERRIDE","RULE","variableFromVariation","overrides","override","NO_MATCH","DEFAULTED","defaultValue","ERROR","emptyDatafile","fetchDatafileContent","datafileUrl","handleDatafileFetch","fetch","then","res","json","getValueByType","fieldType","parseFloat","FeaturevisorInstance","refreshInterval","emitter","refreshInProgress","onReady","onRefresh","onUpdate","onActivation","on","bind","off","setDatafile","datafile","startRefreshing","catch","setTimeout","setLogLevels","Promise","resolve","cb","setStickyFeatures","isReady","refresh","isNotSameRevision","intervalId","setInterval","stopRefreshing","clearInterval","evaluateFlag","isEnabled","evaluateVariation","getVariation","activate","captureContext","filter","capture","evaluateVariable","getVariable","getVariableBoolean","getVariableString","getVariableInteger","getVariableDouble","getVariableArray","getVariableObject","getVariableJSON","createInstance"],"sourceRoot":""}