{"version":3,"file":"growthbook-runtime-snippet.min.js","mappings":"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","sources":["webpack://lange/../node_modules/dom-mutator/src/index.ts","webpack://lange/../node_modules/@growthbook/growthbook/dist/esm/util.mjs","webpack://lange/../node_modules/@growthbook/growthbook/dist/esm/feature-repository.mjs","webpack://lange/../node_modules/@growthbook/growthbook/dist/esm/mongrule.mjs","webpack://lange/../node_modules/@growthbook/growthbook/dist/esm/core.mjs","webpack://lange/../node_modules/@growthbook/growthbook/dist/esm/GrowthBook.mjs","webpack://lange/./lib/perf.ts","webpack://lange/../node_modules/@integrabeauty/cookie/src/index.ts","webpack://lange/./snippets/growthbook-runtime/id.ts","webpack://lange/../node_modules/@growthbook/growthbook/dist/esm/sticky-bucket-service.mjs","webpack://lange/./snippets/growthbook-runtime/sticky-bucket-service.ts","webpack://lange/./snippets/growthbook-runtime/index.ts"],"sourcesContent":["export const validAttributeName = /^[a-zA-Z:_][a-zA-Z0-9:_.-]*$/;\nconst nullController: MutationController = {\n  revert: () => {},\n};\n\nconst elements: Map<Element, ElementRecord> = new Map();\nconst mutations: Set<Mutation> = new Set();\n\nfunction getObserverInit(attr: string): MutationObserverInit {\n  return attr === 'html'\n    ? {\n        childList: true,\n        subtree: true,\n        attributes: true,\n        characterData: true,\n      }\n    : {\n        childList: false,\n        subtree: false,\n        attributes: true,\n        attributeFilter: [attr],\n      };\n}\n\nfunction getElementRecord(element: Element): ElementRecord {\n  let record = elements.get(element);\n\n  if (!record) {\n    record = { element, attributes: {} };\n    elements.set(element, record);\n  }\n\n  return record;\n}\n\nfunction createElementPropertyRecord(\n  el: Element,\n  attr: string,\n  getCurrentValue: (el: Element) => any,\n  setValue: (el: Element, val: any) => void,\n  mutationRunner: (record: ElementPropertyRecord<any, any>) => void\n) {\n  const currentValue = getCurrentValue(el);\n  const record: ElementPropertyRecord<any, any> = {\n    isDirty: false,\n    originalValue: currentValue,\n    virtualValue: currentValue,\n    mutations: [],\n    el,\n    _positionTimeout: null,\n    observer: new MutationObserver(() => {\n      // enact a 1 second timeout that blocks subsequent firing of the\n      // observer until the timeout is complete. This will prevent multiple\n      // mutations from firing in quick succession, which can cause the\n      // mutation to be reverted before the DOM has a chance to update.\n      if (attr === 'position' && record._positionTimeout) return;\n      else if (attr === 'position')\n        record._positionTimeout = setTimeout(() => {\n          record._positionTimeout = null;\n        }, 1000);\n\n      const currentValue = getCurrentValue(el);\n      if (\n        attr === 'position' &&\n        currentValue.parentNode === record.virtualValue.parentNode &&\n        currentValue.insertBeforeNode === record.virtualValue.insertBeforeNode\n      )\n        return;\n      if (currentValue === record.virtualValue) return;\n      record.originalValue = currentValue;\n      mutationRunner(record);\n    }),\n    mutationRunner,\n    setValue,\n    getCurrentValue,\n  };\n  if (attr === 'position' && el.parentNode) {\n    record.observer.observe(el.parentNode, {\n      childList: true,\n      subtree: true,\n      attributes: false,\n      characterData: false,\n    });\n  } else {\n    record.observer.observe(el, getObserverInit(attr));\n  }\n  return record;\n}\n\nfunction queueIfNeeded(\n  val: string | null | ElementPositionWithDomNode,\n  record: ElementPropertyRecord<any, any>\n) {\n  const currentVal = record.getCurrentValue(record.el);\n  record.virtualValue = val;\n  if (val && typeof val !== 'string') {\n    if (\n      !currentVal ||\n      val.parentNode !== currentVal.parentNode ||\n      val.insertBeforeNode !== currentVal.insertBeforeNode\n    ) {\n      record.isDirty = true;\n      runDOMUpdates();\n    }\n  } else if (val !== currentVal) {\n    record.isDirty = true;\n    runDOMUpdates();\n  }\n}\n\nfunction htmlMutationRunner(record: HTMLRecord) {\n  let val = record.originalValue;\n  record.mutations.forEach(m => (val = m.mutate(val)));\n  queueIfNeeded(getTransformedHTML(val), record);\n}\nfunction classMutationRunner(record: ClassnameRecord) {\n  const val = new Set(record.originalValue.split(/\\s+/).filter(Boolean));\n  record.mutations.forEach(m => m.mutate(val));\n  queueIfNeeded(\n    Array.from(val)\n      .filter(Boolean)\n      .join(' '),\n    record\n  );\n}\n\nfunction attrMutationRunner(record: AttributeRecord) {\n  let val: string | null = record.originalValue;\n  record.mutations.forEach(m => (val = m.mutate(val)));\n  queueIfNeeded(val, record);\n}\n\nfunction _loadDOMNodes({\n  parentSelector,\n  insertBeforeSelector,\n}: ElementPosition): ElementPositionWithDomNode | null {\n  const parentNode = document.querySelector<HTMLElement>(parentSelector);\n  if (!parentNode) return null;\n  const insertBeforeNode = insertBeforeSelector\n    ? document.querySelector<HTMLElement>(insertBeforeSelector)\n    : null;\n  if (insertBeforeSelector && !insertBeforeNode) return null;\n  return {\n    parentNode,\n    insertBeforeNode,\n  };\n}\n\nfunction positionMutationRunner(record: PositionRecord) {\n  let val = record.originalValue;\n  record.mutations.forEach(m => {\n    const selectors = m.mutate();\n    const newNodes = _loadDOMNodes(selectors);\n    val = newNodes || val;\n  });\n  queueIfNeeded(val, record);\n}\n\nconst getHTMLValue = (el: Element) => el.innerHTML;\nconst setHTMLValue = (el: Element, value: string) => (el.innerHTML = value);\nfunction getElementHTMLRecord(element: Element): HTMLRecord {\n  const elementRecord = getElementRecord(element);\n  if (!elementRecord.html) {\n    elementRecord.html = createElementPropertyRecord(\n      element,\n      'html',\n      getHTMLValue,\n      setHTMLValue,\n      htmlMutationRunner\n    );\n  }\n  return elementRecord.html;\n}\n\nconst getElementPosition = (el: Element): ElementPositionWithDomNode => {\n  return {\n    parentNode: el.parentElement as HTMLElement,\n    insertBeforeNode: el.nextElementSibling as HTMLElement | null,\n  };\n};\nconst setElementPosition = (el: Element, value: ElementPositionWithDomNode) => {\n  if (\n    value.insertBeforeNode &&\n    !value.parentNode.contains(value.insertBeforeNode)\n  ) {\n    // skip position mutation - insertBeforeNode not a child of parent. happens\n    // when mutation observer for indvidual element fires out of order\n    return;\n  }\n  value.parentNode.insertBefore(el, value.insertBeforeNode);\n};\nfunction getElementPositionRecord(element: Element): PositionRecord {\n  const elementRecord = getElementRecord(element);\n  if (!elementRecord.position) {\n    elementRecord.position = createElementPropertyRecord(\n      element,\n      'position',\n      getElementPosition,\n      setElementPosition,\n      positionMutationRunner\n    );\n  }\n  return elementRecord.position;\n}\n\nconst setClassValue = (el: Element, val: string) =>\n  val ? (el.className = val) : el.removeAttribute('class');\nconst getClassValue = (el: Element) => el.className;\nfunction getElementClassRecord(el: Element): ClassnameRecord {\n  const elementRecord = getElementRecord(el);\n  if (!elementRecord.classes) {\n    elementRecord.classes = createElementPropertyRecord(\n      el,\n      'class',\n      getClassValue,\n      setClassValue,\n      classMutationRunner\n    );\n  }\n  return elementRecord.classes;\n}\n\nconst getAttrValue = (attrName: string) => (el: Element) =>\n  el.getAttribute(attrName) ?? null;\nconst setAttrValue = (attrName: string) => (el: Element, val: string | null) =>\n  val !== null ? el.setAttribute(attrName, val) : el.removeAttribute(attrName);\nfunction getElementAttributeRecord(el: Element, attr: string): AttributeRecord {\n  const elementRecord = getElementRecord(el);\n  if (!elementRecord.attributes[attr]) {\n    elementRecord.attributes[attr] = createElementPropertyRecord(\n      el,\n      attr,\n      getAttrValue(attr),\n      setAttrValue(attr),\n      attrMutationRunner\n    );\n  }\n  return elementRecord.attributes[attr];\n}\n\nfunction deleteElementPropertyRecord(el: Element, attr: string) {\n  const element = elements.get(el);\n  if (!element) return;\n  if (attr === 'html') {\n    element.html?.observer?.disconnect();\n    delete element.html;\n  } else if (attr === 'class') {\n    element.classes?.observer?.disconnect();\n    delete element.classes;\n  } else if (attr === 'position') {\n    element.position?.observer?.disconnect();\n    delete element.position;\n  } else {\n    element.attributes?.[attr]?.observer?.disconnect();\n    delete element.attributes[attr];\n  }\n}\n\nlet transformContainer: HTMLDivElement;\nfunction getTransformedHTML(html: string) {\n  if (!transformContainer) {\n    transformContainer = document.createElement('div');\n  }\n  transformContainer.innerHTML = html;\n  return transformContainer.innerHTML;\n}\n\nfunction setPropertyValue<T extends ElementPropertyRecord<any, any>>(\n  el: Element,\n  attr: string,\n  m: T\n) {\n  if (!m.isDirty) return;\n  m.isDirty = false;\n  const val = m.virtualValue;\n  if (!m.mutations.length) {\n    deleteElementPropertyRecord(el, attr);\n  }\n  m.setValue(el, val);\n}\n\nfunction setValue(m: ElementRecord, el: Element) {\n  m.html && setPropertyValue<HTMLRecord>(el, 'html', m.html);\n  m.classes && setPropertyValue<ClassnameRecord>(el, 'class', m.classes);\n  m.position && setPropertyValue<PositionRecord>(el, 'position', m.position);\n  Object.keys(m.attributes).forEach(attr => {\n    setPropertyValue<AttributeRecord>(el, attr, m.attributes[attr]);\n  });\n}\n\nfunction runDOMUpdates() {\n  elements.forEach(setValue);\n}\n\n// find or create ElementPropertyRecord, add mutation to it, then run\nfunction startMutating(mutation: Mutation, element: Element) {\n  let record: ElementPropertyRecord<any, any> | null = null;\n  if (mutation.kind === 'html') {\n    record = getElementHTMLRecord(element);\n  } else if (mutation.kind === 'class') {\n    record = getElementClassRecord(element);\n  } else if (mutation.kind === 'attribute') {\n    record = getElementAttributeRecord(element, mutation.attribute);\n  } else if (mutation.kind === 'position') {\n    record = getElementPositionRecord(element);\n  }\n  if (!record) return;\n  record.mutations.push(mutation);\n  record.mutationRunner(record);\n}\n\n// get (existing) ElementPropertyRecord, remove mutation from it, then run\nfunction stopMutating(mutation: Mutation, el: Element) {\n  let record: ElementPropertyRecord<any, any> | null = null;\n  if (mutation.kind === 'html') {\n    record = getElementHTMLRecord(el);\n  } else if (mutation.kind === 'class') {\n    record = getElementClassRecord(el);\n  } else if (mutation.kind === 'attribute') {\n    record = getElementAttributeRecord(el, mutation.attribute);\n  } else if (mutation.kind === 'position') {\n    record = getElementPositionRecord(el);\n  }\n  if (!record) return;\n  const index = record.mutations.indexOf(mutation);\n  if (index !== -1) record.mutations.splice(index, 1);\n  record.mutationRunner(record);\n}\n\n// maintain list of elements associated with mutation\nfunction refreshElementsSet(mutation: Mutation) {\n  // if a position mutation has already found an element to move, don't move\n  // any more elements\n  if (mutation.kind === 'position' && mutation.elements.size === 1) return;\n\n  const existingElements = new Set(mutation.elements);\n  const matchingElements = document.querySelectorAll(mutation.selector);\n\n  matchingElements.forEach(el => {\n    if (!existingElements.has(el)) {\n      mutation.elements.add(el);\n      startMutating(mutation, el);\n    }\n  });\n}\n\nfunction revertMutation(mutation: Mutation) {\n  mutation.elements.forEach(el => stopMutating(mutation, el));\n  mutation.elements.clear();\n  mutations.delete(mutation);\n}\n\nfunction refreshAllElementSets() {\n  mutations.forEach(refreshElementsSet);\n}\n\n// Observer for elements that don't exist in the DOM yet\nlet observer: MutationObserver;\nexport function disconnectGlobalObserver() {\n  observer && observer.disconnect();\n}\nexport function connectGlobalObserver() {\n  if (typeof document === 'undefined') return;\n\n  if (!observer) {\n    observer = new MutationObserver(() => {\n      refreshAllElementSets();\n    });\n  }\n\n  refreshAllElementSets();\n  observer.observe(document.documentElement, {\n    childList: true,\n    subtree: true,\n    attributes: false,\n    characterData: false,\n  });\n}\n\n// run on init\nconnectGlobalObserver();\n\nfunction newMutation(m: Mutation): MutationController {\n  // Not in a browser\n  if (typeof document === 'undefined') return nullController;\n  // add to global index of mutations\n  mutations.add(m);\n  // run refresh on init to establish list of elements associated w/ mutation\n  refreshElementsSet(m);\n  return {\n    revert: () => {\n      revertMutation(m);\n    },\n  };\n}\n\nfunction html(\n  selector: HTMLMutation['selector'],\n  mutate: HTMLMutation['mutate']\n) {\n  return newMutation({\n    kind: 'html',\n    elements: new Set(),\n    mutate,\n    selector,\n  });\n}\n\nfunction position(\n  selector: PositionMutation['selector'],\n  mutate: PositionMutation['mutate']\n) {\n  return newMutation({\n    kind: 'position',\n    elements: new Set(),\n    mutate,\n    selector,\n  });\n}\n\nfunction classes(\n  selector: ClassnameMutation['selector'],\n  mutate: ClassnameMutation['mutate']\n) {\n  return newMutation({\n    kind: 'class',\n    elements: new Set(),\n    mutate,\n    selector,\n  });\n}\n\nfunction attribute(\n  selector: AttrMutation['selector'],\n  attribute: AttrMutation['attribute'],\n  mutate: AttrMutation['mutate']\n) {\n  if (!validAttributeName.test(attribute)) return nullController;\n\n  if (attribute === 'class' || attribute === 'className') {\n    return classes(selector, classnames => {\n      const mutatedClassnames = mutate(Array.from(classnames).join(' '));\n      classnames.clear();\n      if (!mutatedClassnames) return;\n      mutatedClassnames\n        .split(/\\s+/g)\n        .filter(Boolean)\n        .forEach(c => classnames.add(c));\n    });\n  }\n\n  return newMutation({\n    kind: 'attribute',\n    attribute,\n    elements: new Set(),\n    mutate,\n    selector,\n  });\n}\n\nfunction declarative({\n  selector,\n  action,\n  value,\n  attribute: attr,\n  parentSelector,\n  insertBeforeSelector,\n}: DeclarativeMutation): MutationController {\n  if (attr === 'html') {\n    if (action === 'append') {\n      return html(selector, val => val + (value ?? ''));\n    } else if (action === 'set') {\n      return html(selector, () => value ?? '');\n    }\n  } else if (attr === 'class') {\n    if (action === 'append') {\n      return classes(selector, val => {\n        if (value) val.add(value);\n      });\n    } else if (action === 'remove') {\n      return classes(selector, val => {\n        if (value) val.delete(value);\n      });\n    } else if (action === 'set') {\n      return classes(selector, val => {\n        val.clear();\n        if (value) val.add(value);\n      });\n    }\n  } else if (attr === 'position') {\n    if (action === 'set' && parentSelector) {\n      return position(selector, () => ({\n        insertBeforeSelector,\n        parentSelector,\n      }));\n    }\n  } else {\n    if (action === 'append') {\n      return attribute(selector, attr, val =>\n        val !== null ? val + (value ?? '') : value ?? ''\n      );\n    } else if (action === 'set') {\n      return attribute(selector, attr, () => value ?? '');\n    } else if (action === 'remove') {\n      return attribute(selector, attr, () => null);\n    }\n  }\n  return nullController;\n}\n\nexport type MutationController = {\n  revert: () => void;\n};\n\nexport type DeclarativeMutation = {\n  selector: string;\n  attribute: string;\n  action: 'append' | 'set' | 'remove';\n  value?: string;\n  parentSelector?: string;\n  insertBeforeSelector?: string;\n};\n\nexport default {\n  html,\n  classes,\n  attribute,\n  position,\n  declarative,\n};\n","const polyfills = {\n  fetch: globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined,\n  SubtleCrypto: globalThis.crypto ? globalThis.crypto.subtle : undefined,\n  EventSource: globalThis.EventSource\n};\nexport function getPolyfills() {\n  return polyfills;\n}\nfunction hashFnv32a(str) {\n  let hval = 0x811c9dc5;\n  const l = str.length;\n  for (let i = 0; i < l; i++) {\n    hval ^= str.charCodeAt(i);\n    hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);\n  }\n  return hval >>> 0;\n}\nexport function hash(seed, value, version) {\n  // New unbiased hashing algorithm\n  if (version === 2) {\n    return hashFnv32a(hashFnv32a(seed + value) + \"\") % 10000 / 10000;\n  }\n  // Original biased hashing algorithm (keep for backwards compatibility)\n  if (version === 1) {\n    return hashFnv32a(value + seed) % 1000 / 1000;\n  }\n\n  // Unknown hash version\n  return null;\n}\nexport function getEqualWeights(n) {\n  if (n <= 0) return [];\n  return new Array(n).fill(1 / n);\n}\nexport function inRange(n, range) {\n  return n >= range[0] && n < range[1];\n}\nexport function inNamespace(hashValue, namespace) {\n  const n = hash(\"__\" + namespace[0], hashValue, 1);\n  if (n === null) return false;\n  return n >= namespace[1] && n < namespace[2];\n}\nexport function chooseVariation(n, ranges) {\n  for (let i = 0; i < ranges.length; i++) {\n    if (inRange(n, ranges[i])) {\n      return i;\n    }\n  }\n  return -1;\n}\nexport function getUrlRegExp(regexString) {\n  try {\n    const escaped = regexString.replace(/([^\\\\])\\//g, \"$1\\\\/\");\n    return new RegExp(escaped);\n  } catch (e) {\n    console.error(e);\n    return undefined;\n  }\n}\nexport function isURLTargeted(url, targets) {\n  if (!targets.length) return false;\n  let hasIncludeRules = false;\n  let isIncluded = false;\n  for (let i = 0; i < targets.length; i++) {\n    const match = _evalURLTarget(url, targets[i].type, targets[i].pattern);\n    if (targets[i].include === false) {\n      if (match) return false;\n    } else {\n      hasIncludeRules = true;\n      if (match) isIncluded = true;\n    }\n  }\n  return isIncluded || !hasIncludeRules;\n}\nfunction _evalSimpleUrlPart(actual, pattern, isPath) {\n  try {\n    // Escape special regex characters and change wildcard `_____` to `.*`\n    let escaped = pattern.replace(/[*.+?^${}()|[\\]\\\\]/g, \"\\\\$&\").replace(/_____/g, \".*\");\n    if (isPath) {\n      // When matching pathname, make leading/trailing slashes optional\n      escaped = \"\\\\/?\" + escaped.replace(/(^\\/|\\/$)/g, \"\") + \"\\\\/?\";\n    }\n    const regex = new RegExp(\"^\" + escaped + \"$\", \"i\");\n    return regex.test(actual);\n  } catch (e) {\n    return false;\n  }\n}\nfunction _evalSimpleUrlTarget(actual, pattern) {\n  try {\n    // If a protocol is missing, but a host is specified, add `https://` to the front\n    // Use \"_____\" as the wildcard since `*` is not a valid hostname in some browsers\n    const expected = new URL(pattern.replace(/^([^:/?]*)\\./i, \"https://$1.\").replace(/\\*/g, \"_____\"), \"https://_____\");\n\n    // Compare each part of the URL separately\n    const comps = [[actual.host, expected.host, false], [actual.pathname, expected.pathname, true]];\n    // We only want to compare hashes if it's explicitly being targeted\n    if (expected.hash) {\n      comps.push([actual.hash, expected.hash, false]);\n    }\n    expected.searchParams.forEach((v, k) => {\n      comps.push([actual.searchParams.get(k) || \"\", v, false]);\n    });\n\n    // If any comparisons fail, the whole thing fails\n    return !comps.some(data => !_evalSimpleUrlPart(data[0], data[1], data[2]));\n  } catch (e) {\n    return false;\n  }\n}\nfunction _evalURLTarget(url, type, pattern) {\n  try {\n    const parsed = new URL(url, \"https://_\");\n    if (type === \"regex\") {\n      const regex = getUrlRegExp(pattern);\n      if (!regex) return false;\n      return regex.test(parsed.href) || regex.test(parsed.href.substring(parsed.origin.length));\n    } else if (type === \"simple\") {\n      return _evalSimpleUrlTarget(parsed, pattern);\n    }\n    return false;\n  } catch (e) {\n    return false;\n  }\n}\nexport function getBucketRanges(numVariations, coverage, weights) {\n  coverage = coverage === undefined ? 1 : coverage;\n\n  // Make sure coverage is within bounds\n  if (coverage < 0) {\n    if (process.env.NODE_ENV !== \"production\") {\n      console.error(\"Experiment.coverage must be greater than or equal to 0\");\n    }\n    coverage = 0;\n  } else if (coverage > 1) {\n    if (process.env.NODE_ENV !== \"production\") {\n      console.error(\"Experiment.coverage must be less than or equal to 1\");\n    }\n    coverage = 1;\n  }\n\n  // Default to equal weights if missing or invalid\n  const equal = getEqualWeights(numVariations);\n  weights = weights || equal;\n  if (weights.length !== numVariations) {\n    if (process.env.NODE_ENV !== \"production\") {\n      console.error(\"Experiment.weights array must be the same length as Experiment.variations\");\n    }\n    weights = equal;\n  }\n\n  // If weights don't add up to 1 (or close to it), default to equal weights\n  const totalWeight = weights.reduce((w, sum) => sum + w, 0);\n  if (totalWeight < 0.99 || totalWeight > 1.01) {\n    if (process.env.NODE_ENV !== \"production\") {\n      console.error(\"Experiment.weights must add up to 1\");\n    }\n    weights = equal;\n  }\n\n  // Convert weights to ranges\n  let cumulative = 0;\n  return weights.map(w => {\n    const start = cumulative;\n    cumulative += w;\n    return [start, start + coverage * w];\n  });\n}\nexport function getQueryStringOverride(id, url, numVariations) {\n  if (!url) {\n    return null;\n  }\n  const search = url.split(\"?\")[1];\n  if (!search) {\n    return null;\n  }\n  const match = search.replace(/#.*/, \"\") // Get rid of anchor\n  .split(\"&\") // Split into key/value pairs\n  .map(kv => kv.split(\"=\", 2)).filter(([k]) => k === id) // Look for key that matches the experiment id\n  .map(([, v]) => parseInt(v)); // Parse the value into an integer\n\n  if (match.length > 0 && match[0] >= 0 && match[0] < numVariations) return match[0];\n  return null;\n}\nexport function isIncluded(include) {\n  try {\n    return include();\n  } catch (e) {\n    console.error(e);\n    return false;\n  }\n}\nconst base64ToBuf = b => Uint8Array.from(atob(b), c => c.charCodeAt(0));\nexport async function decrypt(encryptedString, decryptionKey, subtle) {\n  decryptionKey = decryptionKey || \"\";\n  subtle = subtle || globalThis.crypto && globalThis.crypto.subtle || polyfills.SubtleCrypto;\n  if (!subtle) {\n    throw new Error(\"No SubtleCrypto implementation found\");\n  }\n  try {\n    const key = await subtle.importKey(\"raw\", base64ToBuf(decryptionKey), {\n      name: \"AES-CBC\",\n      length: 128\n    }, true, [\"encrypt\", \"decrypt\"]);\n    const [iv, cipherText] = encryptedString.split(\".\");\n    const plainTextBuffer = await subtle.decrypt({\n      name: \"AES-CBC\",\n      iv: base64ToBuf(iv)\n    }, key, base64ToBuf(cipherText));\n    return new TextDecoder().decode(plainTextBuffer);\n  } catch (e) {\n    throw new Error(\"Failed to decrypt\");\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function toString(input) {\n  if (typeof input === \"string\") return input;\n  return JSON.stringify(input);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function paddedVersionString(input) {\n  if (typeof input === \"number\") {\n    input = input + \"\";\n  }\n  if (!input || typeof input !== \"string\") {\n    input = \"0\";\n  }\n  // Remove build info and leading `v` if any\n  // Split version into parts (both core version numbers and pre-release tags)\n  // \"v1.2.3-rc.1+build123\" -> [\"1\",\"2\",\"3\",\"rc\",\"1\"]\n  const parts = input.replace(/(^v|\\+.*$)/g, \"\").split(/[-.]/);\n\n  // If it's SemVer without a pre-release, add `~` to the end\n  // [\"1\",\"0\",\"0\"] -> [\"1\",\"0\",\"0\",\"~\"]\n  // \"~\" is the largest ASCII character, so this will make \"1.0.0\" greater than \"1.0.0-beta\" for example\n  if (parts.length === 3) {\n    parts.push(\"~\");\n  }\n\n  // Left pad each numeric part with spaces so string comparisons will work (\"9\">\"10\", but \" 9\"<\"10\")\n  // Then, join back together into a single string\n  return parts.map(v => v.match(/^[0-9]+$/) ? v.padStart(5, \" \") : v).join(\"-\");\n}\nexport function loadSDKVersion() {\n  let version;\n  try {\n    // @ts-expect-error right-hand value to be replaced by build with string literal\n    version = \"1.8.0\";\n  } catch (e) {\n    version = \"\";\n  }\n  return version;\n}\nexport function mergeQueryStrings(oldUrl, newUrl) {\n  let currUrl;\n  let redirectUrl;\n  try {\n    currUrl = new URL(oldUrl);\n    redirectUrl = new URL(newUrl);\n  } catch (e) {\n    console.error(`Unable to merge query strings: ${e}`);\n    return newUrl;\n  }\n  currUrl.searchParams.forEach((value, key) => {\n    // skip  if search param already exists in redirectUrl\n    if (redirectUrl.searchParams.has(key)) {\n      return;\n    }\n    redirectUrl.searchParams.set(key, value);\n  });\n  return redirectUrl.toString();\n}\nfunction isObj(x) {\n  return typeof x === \"object\" && x !== null;\n}\nexport function getAutoExperimentChangeType(exp) {\n  if (exp.urlPatterns && exp.variations.some(variation => isObj(variation) && \"urlRedirect\" in variation)) {\n    return \"redirect\";\n  } else if (exp.variations.some(variation => isObj(variation) && (variation.domMutations || \"js\" in variation || \"css\" in variation))) {\n    return \"visual\";\n  }\n  return \"unknown\";\n}\n\n// Guarantee the promise always resolves within {timeout} ms\n// Resolved value will be `null` when there's an error or it takes too long\n// Note: The promise will continue running in the background, even if the timeout is hit\nexport async function promiseTimeout(promise, timeout) {\n  return new Promise(resolve => {\n    let resolved = false;\n    let timer;\n    const finish = data => {\n      if (resolved) return;\n      resolved = true;\n      timer && clearTimeout(timer);\n      resolve(data || null);\n    };\n    if (timeout) {\n      timer = setTimeout(() => finish(), timeout);\n    }\n    promise.then(data => finish(data)).catch(() => finish());\n  });\n}\n//# sourceMappingURL=util.mjs.map","import { getPolyfills, promiseTimeout } from \"./util.mjs\";\n// Config settings\nconst cacheSettings = {\n  // Consider a fetch stale after 1 minute\n  staleTTL: 1000 * 60,\n  // Max time to keep a fetch in cache (4 hours default)\n  maxAge: 1000 * 60 * 60 * 4,\n  cacheKey: \"gbFeaturesCache\",\n  backgroundSync: true,\n  maxEntries: 10,\n  disableIdleStreams: false,\n  idleStreamInterval: 20000,\n  disableCache: false\n};\nconst polyfills = getPolyfills();\nexport const helpers = {\n  fetchFeaturesCall: ({\n    host,\n    clientKey,\n    headers\n  }) => {\n    return polyfills.fetch(`${host}/api/features/${clientKey}`, {\n      headers\n    });\n  },\n  fetchRemoteEvalCall: ({\n    host,\n    clientKey,\n    payload,\n    headers\n  }) => {\n    const options = {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        ...headers\n      },\n      body: JSON.stringify(payload)\n    };\n    return polyfills.fetch(`${host}/api/eval/${clientKey}`, options);\n  },\n  eventSourceCall: ({\n    host,\n    clientKey,\n    headers\n  }) => {\n    if (headers) {\n      return new polyfills.EventSource(`${host}/sub/${clientKey}`, {\n        headers\n      });\n    }\n    return new polyfills.EventSource(`${host}/sub/${clientKey}`);\n  },\n  startIdleListener: () => {\n    let idleTimeout;\n    const isBrowser = typeof window !== \"undefined\" && typeof document !== \"undefined\";\n    if (!isBrowser) return;\n    const onVisibilityChange = () => {\n      if (document.visibilityState === \"visible\") {\n        window.clearTimeout(idleTimeout);\n        onVisible();\n      } else if (document.visibilityState === \"hidden\") {\n        idleTimeout = window.setTimeout(onHidden, cacheSettings.idleStreamInterval);\n      }\n    };\n    document.addEventListener(\"visibilitychange\", onVisibilityChange);\n    return () => document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n  },\n  stopIdleListener: () => {\n    // No-op, replaced by startIdleListener\n  }\n};\ntry {\n  if (globalThis.localStorage) {\n    polyfills.localStorage = globalThis.localStorage;\n  }\n} catch (e) {\n  // Ignore localStorage errors\n}\n\n// Global state\nconst subscribedInstances = new Map();\nlet cacheInitialized = false;\nconst cache = new Map();\nconst activeFetches = new Map();\nconst streams = new Map();\nconst pollers = new Map();\nconst supportsSSE = new Set();\nconst streamingWarnings = new Set();\n\n// Public functions\nexport function setPolyfills(overrides) {\n  Object.assign(polyfills, overrides);\n}\nexport function configureCache(overrides) {\n  Object.assign(cacheSettings, overrides);\n  if (!cacheSettings.backgroundSync) {\n    clearAutoRefresh();\n  }\n}\nexport async function clearCache() {\n  cache.clear();\n  activeFetches.clear();\n  clearAutoRefresh();\n  cacheInitialized = false;\n  await updatePersistentCache();\n}\n\n// Get or fetch features and refresh the SDK instance\nexport async function refreshFeatures({\n  instance,\n  timeout,\n  skipCache,\n  allowStale,\n  backgroundSync\n}) {\n  if (!backgroundSync) {\n    cacheSettings.backgroundSync = false;\n  }\n  return fetchFeaturesWithCache({\n    instance,\n    allowStale,\n    timeout,\n    skipCache\n  });\n}\n\n// Subscribe a GrowthBook instance to feature changes\nfunction subscribe(instance) {\n  const key = getKey(instance);\n  const subs = subscribedInstances.get(key) || new Set();\n  subs.add(instance);\n  subscribedInstances.set(key, subs);\n}\nexport function unsubscribe(instance) {\n  subscribedInstances.forEach((s, key) => {\n    s.delete(instance);\n    // Nothing left to refresh, so stop polling this key\n    const poller = s.size ? undefined : pollers.get(key);\n    if (poller) destroyPoller(poller, key);\n  });\n}\nexport function onHidden() {\n  streams.forEach(channel => {\n    if (!channel) return;\n    channel.state = \"idle\";\n    disableChannel(channel);\n  });\n}\nexport function onVisible() {\n  streams.forEach(channel => {\n    if (!channel) return;\n    if (channel.state !== \"idle\") return;\n    enableChannel(channel);\n  });\n}\n\n// Private functions\n\nconst MAX_BACKOFF_MS = 1000 * 60 * 5;\n\n// Exponential backoff. Jitter is proportional rather than flat, so that clients retrying\n// against the same host spread out instead of bunching at the same offset.\nfunction backoffDelay(base, factor, attempt) {\n  return Math.min(base * Math.pow(factor, attempt) * (1 + Math.random()), MAX_BACKOFF_MS);\n}\n\n// The only place the SDK warns directly rather than through the env-gated instance.log().\n// log() is debug-only, so routing a misconfiguration through it would hide the problem from\n// exactly the production users it affects. Diagnostics still belong in instance.log().\nfunction warnMisconfiguration(message) {\n  console.warn(`[GrowthBook] ${message}`);\n}\n\n// Deduped per reason, so a process warns once about each distinct cause\nfunction warnStreamingUnavailable(reason) {\n  if (streamingWarnings.has(reason)) return;\n  streamingWarnings.add(reason);\n  warnMisconfiguration(`Streaming is enabled, but not active: ${reason}. Features will not be updated in the background. Set \\`pollingInterval\\` to refresh on a timer instead, or see https://docs.growthbook.io/lib/node#refreshing-features`);\n}\nasync function updatePersistentCache() {\n  try {\n    if (!polyfills.localStorage) return;\n    await polyfills.localStorage.setItem(cacheSettings.cacheKey, JSON.stringify(Array.from(cache.entries())));\n  } catch (e) {\n    // Ignore localStorage errors\n  }\n}\n\n// SWR wrapper for fetching features. May indirectly or directly start SSE streaming.\nasync function fetchFeaturesWithCache({\n  instance,\n  allowStale,\n  timeout,\n  skipCache\n}) {\n  const key = getKey(instance);\n  const cacheKey = getCacheKey(instance);\n  const now = new Date();\n  const minStaleAt = new Date(now.getTime() - cacheSettings.maxAge + cacheSettings.staleTTL);\n  await initializeCache();\n  const existing = !cacheSettings.disableCache && !skipCache ? cache.get(cacheKey) : undefined;\n  if (existing && (allowStale || existing.staleAt > now) && existing.staleAt > minStaleAt) {\n    // Restore from cache whether SSE is supported\n    if (existing.sse) supportsSSE.add(key);\n\n    // Reload features in the background if stale\n    if (existing.staleAt < now) {\n      fetchFeatures(instance);\n    }\n    // Otherwise, if we don't need to refresh now, start a background sync\n    else {\n      startAutoRefresh(instance);\n    }\n    return {\n      data: existing.data,\n      success: true,\n      source: \"cache\"\n    };\n  } else {\n    const res = await promiseTimeout(fetchFeatures(instance), timeout);\n    return res || {\n      data: null,\n      success: false,\n      source: \"timeout\",\n      error: new Error(\"Timeout\")\n    };\n  }\n}\nfunction getKey(instance) {\n  const [apiHost, clientKey] = instance.getApiInfo();\n  return `${apiHost}||${clientKey}`;\n}\nfunction getCacheKey(instance) {\n  const baseKey = getKey(instance);\n  if (!(\"isRemoteEval\" in instance) || !instance.isRemoteEval()) return baseKey;\n  const attributes = instance.getAttributes();\n  const cacheKeyAttributes = instance.getCacheKeyAttributes() || Object.keys(instance.getAttributes());\n  const ca = {};\n  cacheKeyAttributes.forEach(key => {\n    ca[key] = attributes[key];\n  });\n  const fv = instance.getForcedVariations();\n  const url = instance.getUrl();\n  return `${baseKey}||${JSON.stringify({\n    ca,\n    fv,\n    url\n  })}`;\n}\n\n// Populate cache from localStorage (if available)\nasync function initializeCache() {\n  if (cacheInitialized) return;\n  cacheInitialized = true;\n  try {\n    if (polyfills.localStorage) {\n      const value = await polyfills.localStorage.getItem(cacheSettings.cacheKey);\n      if (!cacheSettings.disableCache && value) {\n        const parsed = JSON.parse(value);\n        if (parsed && Array.isArray(parsed)) {\n          parsed.forEach(([key, data]) => {\n            cache.set(key, {\n              ...data,\n              staleAt: new Date(data.staleAt)\n            });\n          });\n        }\n        cleanupCache();\n      }\n    }\n  } catch (e) {\n    // Ignore localStorage errors\n  }\n  if (!cacheSettings.disableIdleStreams) {\n    const cleanupFn = helpers.startIdleListener();\n    if (cleanupFn) {\n      helpers.stopIdleListener = cleanupFn;\n    }\n  }\n}\n\n// Enforce the maxEntries limit\nfunction cleanupCache() {\n  const entriesWithTimestamps = Array.from(cache.entries()).map(([key, value]) => ({\n    key,\n    staleAt: value.staleAt.getTime()\n  })).sort((a, b) => a.staleAt - b.staleAt);\n  const entriesToRemoveCount = Math.min(Math.max(0, cache.size - cacheSettings.maxEntries), cache.size);\n  for (let i = 0; i < entriesToRemoveCount; i++) {\n    cache.delete(entriesWithTimestamps[i].key);\n  }\n}\n\n// Called whenever new features are fetched from the API\nfunction onNewFeatureData(key, cacheKey, data) {\n  // If contents haven't changed, ignore the update, extend the stale TTL\n  const version = data.dateUpdated || \"\";\n  const staleAt = new Date(Date.now() + cacheSettings.staleTTL);\n  const existing = !cacheSettings.disableCache ? cache.get(cacheKey) : undefined;\n  if (existing && version && existing.version === version) {\n    existing.staleAt = staleAt;\n    updatePersistentCache();\n    return;\n  }\n  if (!cacheSettings.disableCache) {\n    // Update in-memory cache\n    cache.set(cacheKey, {\n      data,\n      version,\n      staleAt,\n      sse: supportsSSE.has(key)\n    });\n    cleanupCache();\n  }\n  // Update local storage (don't await this, just update asynchronously)\n  updatePersistentCache();\n\n  // Update features for all subscribed GrowthBook instances\n  const instances = subscribedInstances.get(key);\n  instances && instances.forEach(instance => refreshInstance(instance, data));\n}\nasync function refreshInstance(instance, data) {\n  await instance.setPayload(data || instance.getPayload());\n}\n\n// Fetch the features payload from helper function or from in-mem injected payload\nasync function fetchFeatures(instance) {\n  const {\n    apiHost,\n    apiRequestHeaders\n  } = instance.getApiHosts();\n  const clientKey = instance.getClientKey();\n  const remoteEval = \"isRemoteEval\" in instance && instance.isRemoteEval();\n  const key = getKey(instance);\n  const cacheKey = getCacheKey(instance);\n  let promise = activeFetches.get(cacheKey);\n  if (!promise) {\n    const fetcher = remoteEval ? helpers.fetchRemoteEvalCall({\n      host: apiHost,\n      clientKey,\n      payload: {\n        attributes: instance.getAttributes(),\n        forcedVariations: instance.getForcedVariations(),\n        forcedFeatures: Array.from(instance.getForcedFeatures().entries()),\n        url: instance.getUrl()\n      },\n      headers: apiRequestHeaders\n    }) : helpers.fetchFeaturesCall({\n      host: apiHost,\n      clientKey,\n      headers: apiRequestHeaders\n    });\n\n    // TODO: auto-retry if status code indicates a temporary error\n    promise = fetcher.then(res => {\n      if (!res.ok) {\n        throw new Error(`HTTP error: ${res.status}`);\n      }\n      if (res.headers.get(\"x-sse-support\") === \"enabled\") {\n        supportsSSE.add(key);\n      }\n      return res.json();\n    }).then(data => {\n      onNewFeatureData(key, cacheKey, data);\n      startAutoRefresh(instance);\n      activeFetches.delete(cacheKey);\n      return {\n        data,\n        success: true,\n        source: \"network\"\n      };\n    }).catch(e => {\n      process.env.NODE_ENV !== \"production\" && instance.log(\"Error fetching features\", {\n        apiHost,\n        clientKey,\n        error: e ? e.message : null\n      });\n      activeFetches.delete(cacheKey);\n      return {\n        data: null,\n        source: \"error\",\n        success: false,\n        error: e\n      };\n    });\n    activeFetches.set(cacheKey, promise);\n  }\n  return promise;\n}\n\n// Start SSE streaming, listens to feature payload changes and triggers a refresh or re-fetch\nfunction startAutoRefresh(instance, forceSSE = false) {\n  const key = getKey(instance);\n  const cacheKey = getCacheKey(instance);\n  const {\n    streamingHost,\n    streamingHostRequestHeaders\n  } = instance.getApiHosts();\n  const clientKey = instance.getClientKey();\n  if (forceSSE) {\n    supportsSSE.add(key);\n  }\n  if (cacheSettings.backgroundSync && supportsSSE.has(key) && polyfills.EventSource) {\n    if (streams.has(key)) return;\n    const channel = {\n      src: null,\n      key,\n      host: streamingHost,\n      clientKey,\n      headers: streamingHostRequestHeaders,\n      cb: event => {\n        try {\n          if (event.type === \"features-updated\") {\n            const instances = subscribedInstances.get(key);\n            instances && instances.forEach(instance => {\n              fetchFeatures(instance);\n            });\n          } else if (event.type === \"features\") {\n            const json = JSON.parse(event.data);\n            onNewFeatureData(key, cacheKey, json);\n          }\n          // Reset error count on success\n          channel.errors = 0;\n        } catch (e) {\n          process.env.NODE_ENV !== \"production\" && instance.log(\"SSE Error\", {\n            streamingHost,\n            clientKey,\n            error: e ? e.message : null\n          });\n          onSSEError(channel);\n        }\n      },\n      errors: 0,\n      state: \"active\"\n    };\n    streams.set(key, channel);\n    enableChannel(channel);\n  }\n}\nfunction onSSEError(channel) {\n  if (channel.state === \"idle\") return;\n  channel.errors++;\n  if (channel.errors > 3 || channel.src && channel.src.readyState === 2) {\n    // exponential backoff after 4 errors, with jitter\n    const delay = backoffDelay(1000, 3, channel.errors - 3);\n    disableChannel(channel);\n    setTimeout(() => {\n      if ([\"idle\", \"active\"].includes(channel.state)) return;\n      // A channel dropped while backing off (destroy, clearCache) must not reconnect:\n      // it would open an EventSource nothing tracks or can ever close\n      if (streams.get(channel.key) !== channel) return;\n      enableChannel(channel);\n    }, delay);\n  }\n}\nfunction disableChannel(channel) {\n  if (!channel.src) return;\n  channel.src.onopen = null;\n  channel.src.onerror = null;\n  channel.src.close();\n  channel.src = null;\n  if (channel.state === \"active\") {\n    channel.state = \"disabled\";\n  }\n}\nfunction enableChannel(channel) {\n  try {\n    channel.src = helpers.eventSourceCall({\n      host: channel.host,\n      clientKey: channel.clientKey,\n      headers: channel.headers\n    });\n    channel.state = \"active\";\n    channel.src.addEventListener(\"features\", channel.cb);\n    channel.src.addEventListener(\"features-updated\", channel.cb);\n    channel.src.onerror = () => onSSEError(channel);\n    channel.src.onopen = () => {\n      channel.errors = 0;\n      // Retire polling once the stream is confirmed open, not merely constructed -\n      // a stream blocked by a proxy is exactly why someone configured polling\n      const poller = pollers.get(channel.key);\n      if (poller) destroyPoller(poller, channel.key);\n    };\n  } catch (e) {\n    // A half-built connection may already be open, so close it before dropping the ref\n    try {\n      if (channel.src) {\n        channel.src.close();\n        channel.src.onerror = null;\n        channel.src.onopen = null;\n      }\n    } catch (closeError) {\n      // Ignore cleanup errors from incompatible implementations\n    }\n    channel.src = null;\n    channel.state = \"disabled\";\n    // Evict so the existing-key guard can't block a later retry, but only if this channel\n    // is still the registered one - a stale re-connect must not evict its replacement\n    if (streams.get(channel.key) === channel) streams.delete(channel.key);\n    warnStreamingUnavailable(`the EventSource implementation threw an error (${e ? e.message : \"unknown error\"})`);\n  }\n}\nfunction destroyChannel(channel, key) {\n  disableChannel(channel);\n  streams.delete(key);\n}\n\n// Refresh on a fixed interval. Deduped per key, so many instances sharing a clientKey poll once.\nfunction startPolling(key, interval) {\n  // setTimeout collapses an out-of-range delay to 1ms, turning a typo into a request loop\n  if (!Number.isFinite(interval) || interval < 1 || interval > 2147483647) {\n    warnMisconfiguration(`Ignoring invalid pollingInterval (${interval}). Expected a finite number of milliseconds between 1 and 2147483647.`);\n    return;\n  }\n  if (pollers.has(key)) return;\n  const poller = {\n    timer: null,\n    interval,\n    errors: 0\n  };\n  pollers.set(key, poller);\n  scheduleNextPoll(key, poller);\n}\nfunction scheduleNextPoll(key, poller) {\n  // Gentler curve than onSSEError's, since this one already starts from the\n  // user's configured interval rather than a fixed 1s\n  const delay = poller.errors > 0 ? backoffDelay(poller.interval, 2, poller.errors - 1) : poller.interval;\n  const timer = setTimeout(() => {\n    // Resolve a subscriber at poll time. The instance that started polling may have been\n    // destroyed, which clears its options and would send us to the wrong host.\n    const subs = subscribedInstances.get(key);\n    const instance = subs && subs.values().next().value;\n    if (!instance) {\n      destroyPoller(poller, key);\n      return;\n    }\n\n    // Bypass the cache so the interval, not staleTTL, decides how often we refresh\n    fetchFeatures(instance).then(res => {\n      poller.errors = res.success ? 0 : poller.errors + 1;\n      // Don't reschedule if polling was stopped while the request was in flight\n      if (pollers.get(key) === poller) {\n        scheduleNextPoll(key, poller);\n      }\n    });\n  }, delay);\n\n  // Never hold a short-lived process (serverless, CLI) open just to poll\n  if (timer.unref) timer.unref();\n  poller.timer = timer;\n}\nfunction destroyPoller(poller, key) {\n  if (poller.timer) clearTimeout(poller.timer);\n  pollers.delete(key);\n}\nexport function clearAutoRefresh() {\n  // Clear list of which keys are auto-updated\n  supportsSSE.clear();\n  streamingWarnings.clear();\n\n  // Stop listening for any SSE events\n  streams.forEach(destroyChannel);\n\n  // Stop any background polling\n  pollers.forEach(destroyPoller);\n\n  // Remove all references to GrowthBook instances\n  subscribedInstances.clear();\n\n  // Run the idle stream cleanup function\n  helpers.stopIdleListener();\n}\nexport function startBackgroundSync(instance, options) {\n  if (!options.streaming && options.pollingInterval === undefined) return;\n  if (!instance.getClientKey()) {\n    throw new Error(\"Must specify clientKey to enable streaming or polling\");\n  }\n  if (options.streaming) {\n    if (options.payload) {\n      startAutoRefresh(instance, true);\n    }\n    if (!polyfills.EventSource) {\n      warnStreamingUnavailable(\"no EventSource implementation is available. In Node.js, install the `eventsource` package and pass it to setPolyfills({ EventSource })\");\n    } else if (cacheSettings.backgroundSync && !supportsSSE.has(getKey(instance))) {\n      // Keyed on supportsSSE rather than an absent stream, so an EventSource that\n      // failed to start (already warned about above) doesn't also get blamed here\n      warnStreamingUnavailable(\"the API host did not report SSE support (missing `x-sse-support` response header). This is also expected when the initial payload fetch fails\");\n    }\n  }\n  subscribe(instance);\n\n  // Not gated on an existing stream: startAutoRefresh opens one whenever the host\n  // advertises SSE, so gating here would drop the polling that was asked for if that\n  // stream never connects. onopen retires the poller once it does.\n  // Checked against undefined so 0 reaches startPolling's validation warning\n  const key = getKey(instance);\n  if (options.pollingInterval !== undefined && cacheSettings.backgroundSync) {\n    startPolling(key, options.pollingInterval);\n  }\n}\n//# sourceMappingURL=feature-repository.mjs.map","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { paddedVersionString } from \"./util.mjs\";\nconst _regexCache = {};\n\n// The top-level condition evaluation function\nexport function evalCondition(obj, condition,\n// Must be included for `condition` to correctly evaluate group Operators\nsavedGroups,\n// Group ids already being resolved, to stop cycles\nvisited) {\n  savedGroups = savedGroups || {};\n  visited = visited || new Set();\n  // Condition is an object, keys are either specific operators or object paths\n  // values are either arguments for operators or conditions for paths\n  for (const [k, v] of Object.entries(condition)) {\n    switch (k) {\n      case \"$or\":\n        if (!evalOr(obj, v, savedGroups, visited)) return false;\n        break;\n      case \"$nor\":\n        if (evalOr(obj, v, savedGroups, visited)) return false;\n        break;\n      case \"$and\":\n        if (!evalAnd(obj, v, savedGroups, visited)) return false;\n        break;\n      case \"$not\":\n        if (evalCondition(obj, v, savedGroups, visited)) return false;\n        break;\n      case \"$savedGroup\":\n        if (!evalSavedGroup(obj, v, savedGroups, visited)) return false;\n        break;\n      default:\n        if (!evalConditionValue(v, getPath(obj, k), savedGroups, false, visited)) return false;\n    }\n  }\n  return true;\n}\n\n/** Resolves a `$savedGroup` reference. Anything unrecognized matches nobody. */\nfunction evalSavedGroup(obj, reference, savedGroups, visited) {\n  if (!reference || typeof reference !== \"object\" || Array.isArray(reference)) return false;\n  const {\n    id,\n    attributeKey\n  } = reference;\n  if (typeof id !== \"string\" || visited.has(id)) return false;\n  // Falling back to the entry's attribute would check a different population\n  if (attributeKey !== undefined && typeof attributeKey !== \"string\") return false;\n  const entry = savedGroups[id];\n  // Absent, or a v1 bare array\n  if (!entry || Array.isArray(entry) || typeof entry !== \"object\") return false;\n  const next = new Set(visited).add(id);\n  if (entry.type === \"list\") {\n    // The override wins over the entry's own attribute\n    const key = attributeKey ?? entry.attributeKey;\n    if (typeof key !== \"string\") return false;\n    if (!Array.isArray(entry.values)) return false;\n    return isIn(getPath(obj, key), entry.values);\n  }\n  if (entry.type === \"condition\") {\n    // A condition group has no single attribute, so any override is ignored\n    if (!entry.condition || typeof entry.condition !== \"object\") return false;\n    return evalCondition(obj, entry.condition, savedGroups, next);\n  }\n\n  // A group type added after this SDK was built\n  return false;\n}\n\n// Return value at dot-separated path of an object\nfunction getPath(obj, path) {\n  const parts = path.split(\".\");\n  let current = obj;\n  for (let i = 0; i < parts.length; i++) {\n    if (current && typeof current === \"object\" && parts[i] in current) {\n      current = current[parts[i]];\n    } else {\n      return null;\n    }\n  }\n  return current;\n}\n\n// Transform a regex string into a real RegExp object\nfunction getRegex(regex, insensitive = false) {\n  const cacheKey = `${regex}${insensitive ? \"/i\" : \"\"}`;\n  if (!_regexCache[cacheKey]) {\n    _regexCache[cacheKey] = new RegExp(regex.replace(/([^\\\\])\\//g, \"$1\\\\/\"), insensitive ? \"i\" : undefined);\n  }\n  return _regexCache[cacheKey];\n}\n\n// Evaluate a single value against a condition\nfunction evalConditionValue(condition, value, savedGroups, insensitive = false, visited = new Set()) {\n  // Simple equality comparisons\n  if (typeof condition === \"string\") {\n    if (insensitive) {\n      return String(value).toLowerCase() === condition.toLowerCase();\n    }\n    return value + \"\" === condition;\n  }\n  if (typeof condition === \"number\") {\n    return value * 1 === condition;\n  }\n  if (typeof condition === \"boolean\") {\n    return value !== null && !!value === condition;\n  }\n  if (condition === null) {\n    return value === null;\n  }\n  if (Array.isArray(condition) || !isOperatorObject(condition)) {\n    return JSON.stringify(value) === JSON.stringify(condition);\n  }\n\n  // This is a special operator condition and we should evaluate each one separately\n  for (const op in condition) {\n    if (!evalOperatorCondition(op, value, condition[op], savedGroups, visited)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// If the object has only keys that start with '$'\nfunction isOperatorObject(obj) {\n  const keys = Object.keys(obj);\n  return keys.length > 0 && keys.filter(k => k[0] === \"$\").length === keys.length;\n}\n\n// Return the data type of a value\nfunction getType(v) {\n  if (v === null) return \"null\";\n  if (Array.isArray(v)) return \"array\";\n  const t = typeof v;\n  if ([\"string\", \"number\", \"boolean\", \"object\", \"undefined\"].includes(t)) {\n    return t;\n  }\n  return \"unknown\";\n}\n\n// At least one element of actual must match the expected condition/value\nfunction elemMatch(actual, expected, savedGroups, visited) {\n  if (!Array.isArray(actual)) return false;\n  const check = isOperatorObject(expected) ? v => evalConditionValue(expected, v, savedGroups, false, visited) : v => evalCondition(v, expected, savedGroups, visited);\n  for (let i = 0; i < actual.length; i++) {\n    // Only skip nullish elements; falsy values like 0, \"\" and false are valid\n    // array members and must still be tested against the condition.\n    if ((actual[i] ?? null) !== null && check(actual[i])) {\n      return true;\n    }\n  }\n  return false;\n}\nfunction isIn(actual, expected, insensitive = false) {\n  if (insensitive) {\n    const caseFold = val => typeof val === \"string\" ? val.toLowerCase() : val;\n    // Do an intersection if attribute is an array (insensitive)\n    if (Array.isArray(actual)) {\n      return actual.some(el => expected.some(exp => caseFold(el) === caseFold(exp)));\n    }\n    return expected.some(exp => caseFold(actual) === caseFold(exp));\n  }\n  // Do an intersection if attribute is an array\n  if (Array.isArray(actual)) {\n    return actual.some(el => expected.includes(el));\n  }\n  return expected.includes(actual);\n}\n\n/**\n * Gets the array of values from a saved group. This can either be the legacy bare array\n * format, or it can pull the array from the v2 \"type: list\" format.\n */\nfunction getSavedGroupArrayValues(entry) {\n  // An unknown id has always behaved like an empty list. A malformed entry\n  // has not, and must not: $notInGroup would pass everyone.\n  if (entry === undefined) return [];\n  if (Array.isArray(entry)) return entry;\n\n  // These operators take their attribute from the condition they sit on\n  if (entry && typeof entry === \"object\" && entry.type === \"list\") {\n    return Array.isArray(entry.values) ? entry.values : null;\n  }\n\n  // A condition group, a malformed entry, or an unknown type\n  return null;\n}\nfunction isInAll(actual, expected, savedGroups, insensitive = false, visited = new Set()) {\n  if (!Array.isArray(actual)) return false;\n  for (let i = 0; i < expected.length; i++) {\n    let passed = false;\n    for (let j = 0; j < actual.length; j++) {\n      if (evalConditionValue(expected[i], actual[j], savedGroups, insensitive, visited)) {\n        passed = true;\n        break;\n      }\n    }\n    if (!passed) return false;\n  }\n  return true;\n}\n\n// Evaluate a single operator condition\nfunction evalOperatorCondition(operator, actual, expected, savedGroups, visited = new Set()) {\n  switch (operator) {\n    case \"$veq\":\n      return paddedVersionString(actual) === paddedVersionString(expected);\n    case \"$vne\":\n      return paddedVersionString(actual) !== paddedVersionString(expected);\n    case \"$vgt\":\n      return paddedVersionString(actual) > paddedVersionString(expected);\n    case \"$vgte\":\n      return paddedVersionString(actual) >= paddedVersionString(expected);\n    case \"$vlt\":\n      return paddedVersionString(actual) < paddedVersionString(expected);\n    case \"$vlte\":\n      return paddedVersionString(actual) <= paddedVersionString(expected);\n    case \"$eq\":\n      return actual === expected;\n    case \"$ne\":\n      return actual !== expected;\n    case \"$lt\":\n      return actual < expected;\n    case \"$lte\":\n      return actual <= expected;\n    case \"$gt\":\n      return actual > expected;\n    case \"$gte\":\n      return actual >= expected;\n    case \"$exists\":\n      // Using `!=` and `==` instead of strict checks so it also matches for undefined\n      return expected ? actual != null : actual == null;\n    case \"$in\":\n      if (!Array.isArray(expected)) return false;\n      return isIn(actual, expected);\n    case \"$ini\":\n      if (!Array.isArray(expected)) return false;\n      return isIn(actual, expected, true);\n    case \"$inGroup\":\n      {\n        const values = getSavedGroupArrayValues(savedGroups[expected]);\n        return values === null ? false : isIn(actual, values);\n      }\n    case \"$notInGroup\":\n      {\n        // No values means matching nobody. An empty list would pass everyone.\n        const values = getSavedGroupArrayValues(savedGroups[expected]);\n        return values === null ? false : !isIn(actual, values);\n      }\n    case \"$nin\":\n      if (!Array.isArray(expected)) return false;\n      return !isIn(actual, expected);\n    case \"$nini\":\n      if (!Array.isArray(expected)) return false;\n      return !isIn(actual, expected, true);\n    case \"$not\":\n      return !evalConditionValue(expected, actual, savedGroups, false, visited);\n    case \"$size\":\n      if (!Array.isArray(actual)) return false;\n      return evalConditionValue(expected, actual.length, savedGroups, false, visited);\n    case \"$elemMatch\":\n      return elemMatch(actual, expected, savedGroups, visited);\n    case \"$all\":\n      if (!Array.isArray(expected)) return false;\n      return isInAll(actual, expected, savedGroups, false, visited);\n    case \"$alli\":\n      if (!Array.isArray(expected)) return false;\n      return isInAll(actual, expected, savedGroups, true, visited);\n    case \"$regex\":\n      try {\n        return getRegex(expected).test(actual);\n      } catch (e) {\n        return false;\n      }\n    case \"$regexi\":\n      try {\n        return getRegex(expected, true).test(actual);\n      } catch (e) {\n        return false;\n      }\n    case \"$type\":\n      return getType(actual) === expected;\n    default:\n      console.error(\"Unknown operator: \" + operator);\n      return false;\n  }\n}\n\n// Recursive $or rule\nfunction evalOr(obj, conditions, savedGroups, visited) {\n  if (!conditions.length) return true;\n  for (let i = 0; i < conditions.length; i++) {\n    if (evalCondition(obj, conditions[i], savedGroups, visited)) {\n      return true;\n    }\n  }\n  return false;\n}\n\n// Recursive $and rule\nfunction evalAnd(obj, conditions, savedGroups, visited) {\n  for (let i = 0; i < conditions.length; i++) {\n    if (!evalCondition(obj, conditions[i], savedGroups, visited)) {\n      return false;\n    }\n  }\n  return true;\n}\n//# sourceMappingURL=mongrule.mjs.map","import { evalCondition } from \"./mongrule.mjs\";\nimport { chooseVariation, decrypt, getBucketRanges, getEqualWeights, getQueryStringOverride, getUrlRegExp, hash, inNamespace, inRange, isIncluded, isURLTargeted, toString } from \"./util.mjs\";\nexport const EVENT_FEATURE_EVALUATED = \"Feature Evaluated\";\nexport const EVENT_EXPERIMENT_VIEWED = \"Experiment Viewed\";\nfunction getForcedFeatureValues(ctx) {\n  // Merge user and global values\n  const ret = new Map();\n  if (ctx.global.forcedFeatureValues) {\n    ctx.global.forcedFeatureValues.forEach((v, k) => ret.set(k, v));\n  }\n  if (ctx.user.forcedFeatureValues) {\n    ctx.user.forcedFeatureValues.forEach((v, k) => ret.set(k, v));\n  }\n  return ret;\n}\nfunction getForcedVariations(ctx) {\n  // Merge user and global values\n  if (ctx.global.forcedVariations && ctx.user.forcedVariations) {\n    return {\n      ...ctx.global.forcedVariations,\n      ...ctx.user.forcedVariations\n    };\n  } else if (ctx.global.forcedVariations) {\n    return ctx.global.forcedVariations;\n  } else if (ctx.user.forcedVariations) {\n    return ctx.user.forcedVariations;\n  } else {\n    return {};\n  }\n}\nasync function safeCall(fn) {\n  try {\n    await fn();\n  } catch (e) {\n    // Do nothing\n  }\n}\nfunction onExperimentViewed(ctx, experiment, result) {\n  // Make sure a tracking callback is only fired once per unique experiment\n  if (ctx.user.trackedExperiments) {\n    const k = getExperimentDedupeKey(experiment, result);\n    if (ctx.user.trackedExperiments.has(k)) {\n      return [];\n    }\n    ctx.user.trackedExperiments.add(k);\n  }\n  if (ctx.user.enableDevMode && ctx.user.devLogs) {\n    ctx.user.devLogs.push({\n      experiment,\n      result,\n      timestamp: Date.now().toString(),\n      logType: \"experiment\"\n    });\n  }\n  const calls = [];\n  if (ctx.global.trackingCallback) {\n    const cb = ctx.global.trackingCallback;\n    calls.push(safeCall(() => cb(experiment, result, getTrackingUserContext(ctx.user))));\n  }\n  if (ctx.user.trackingCallback) {\n    const cb = ctx.user.trackingCallback;\n    calls.push(safeCall(() => cb(experiment, result, getTrackingUserContext(ctx.user))));\n  }\n  if (ctx.global.eventLogger) {\n    const cb = ctx.global.eventLogger;\n    calls.push(safeCall(() => cb(EVENT_EXPERIMENT_VIEWED, {\n      experimentId: experiment.key,\n      variationId: result.key,\n      hashAttribute: result.hashAttribute,\n      hashValue: result.hashValue\n    }, getTrackingUserContext(ctx.user))));\n  }\n\n  // Deduped above — subscribers fire once per unique experiment assignment.\n  if (ctx.user.experimentViewedSubs?.size) {\n    const user = getTrackingUserContext(ctx.user);\n    ctx.user.experimentViewedSubs.forEach(cb => {\n      try {\n        cb(experiment, result, user);\n      } catch (e) {\n        console.error(e);\n      }\n    });\n  }\n  return calls;\n}\nfunction onFeatureUsage(ctx, key, ret) {\n  // Only track a feature once, unless the assigned value changed\n  if (ctx.user.trackedFeatureUsage) {\n    const stringifiedValue = JSON.stringify(ret.value);\n    if (ctx.user.trackedFeatureUsage[key] === stringifiedValue) return;\n    ctx.user.trackedFeatureUsage[key] = stringifiedValue;\n    if (ctx.user.enableDevMode && ctx.user.devLogs) {\n      ctx.user.devLogs.push({\n        featureKey: key,\n        result: ret,\n        timestamp: Date.now().toString(),\n        logType: \"feature\"\n      });\n    }\n\n    // Deduped by value above — subscribers only fire on value changes, not every eval.\n    if (ctx.user.featureUsageSubs?.size) {\n      ctx.user.featureUsageSubs.forEach(cb => {\n        try {\n          cb(key, ret);\n        } catch (e) {\n          console.error(e);\n        }\n      });\n    }\n  }\n  if (ctx.global.onFeatureUsage) {\n    const cb = ctx.global.onFeatureUsage;\n    safeCall(() => cb(key, ret, getTrackingUserContext(ctx.user)));\n  }\n  if (ctx.user.onFeatureUsage) {\n    const cb = ctx.user.onFeatureUsage;\n    safeCall(() => cb(key, ret));\n  }\n  if (ctx.global.eventLogger) {\n    const cb = ctx.global.eventLogger;\n    safeCall(() => cb(EVENT_FEATURE_EVALUATED, {\n      feature: key,\n      source: ret.source,\n      value: ret.value,\n      ruleId: ret.source === \"defaultValue\" ? \"$default\" : ret.ruleId || \"\",\n      variationId: ret.experimentResult ? ret.experimentResult.key : \"\"\n    }, getTrackingUserContext(ctx.user)));\n  }\n}\nexport function evalFeature(id, ctx) {\n  if (ctx.stack.evaluatedFeatures.has(id)) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(`evalFeature: circular dependency detected: ${ctx.stack.id} -> ${id}`, {\n      from: ctx.stack.id,\n      to: id\n    });\n    return getFeatureResult(ctx, id, null, \"cyclicPrerequisite\");\n  }\n  ctx.stack.evaluatedFeatures.add(id);\n  ctx.stack.id = id;\n\n  // Global override\n  const forcedValues = getForcedFeatureValues(ctx);\n  if (forcedValues.has(id)) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Global override\", {\n      id,\n      value: forcedValues.get(id)\n    });\n    return getFeatureResult(ctx, id, forcedValues.get(id), \"override\");\n  }\n\n  // Unknown feature id\n  if (!ctx.global.features || !ctx.global.features[id]) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Unknown feature\", {\n      id\n    });\n    return getFeatureResult(ctx, id, null, \"unknownFeature\");\n  }\n\n  // Get the feature\n  const feature = ctx.global.features[id];\n\n  // Loop through the rules\n  if (feature.rules) {\n    const evaluatedFeatures = new Set(ctx.stack.evaluatedFeatures);\n    rules: for (const rule of feature.rules) {\n      // If there are prerequisite flag(s), evaluate them\n      if (rule.parentConditions) {\n        for (const parentCondition of rule.parentConditions) {\n          ctx.stack.evaluatedFeatures = new Set(evaluatedFeatures);\n          const parentResult = evalFeature(parentCondition.id, ctx);\n          // break out for cyclic prerequisites\n          if (parentResult.source === \"cyclicPrerequisite\") {\n            return getFeatureResult(ctx, id, null, \"cyclicPrerequisite\");\n          }\n          const evalObj = {\n            value: parentResult.value\n          };\n          const evaled = evalCondition(evalObj, parentCondition.condition || {}, ctx.global.savedGroups || {});\n          if (!evaled) {\n            // blocking prerequisite eval failed: feature evaluation fails\n            if (parentCondition.gate) {\n              process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Feature blocked by prerequisite\", {\n                id,\n                rule\n              });\n              return getFeatureResult(ctx, id, null, \"prerequisite\");\n            }\n            // non-blocking prerequisite eval failed: break out of parentConditions loop, jump to the next rule\n            process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip rule because prerequisite evaluation fails\", {\n              id,\n              rule\n            });\n            continue rules;\n          }\n        }\n      }\n\n      // If there are filters for who is included (e.g. namespaces)\n      if (rule.filters && isFilteredOut(rule.filters, ctx)) {\n        process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip rule because of filters\", {\n          id,\n          rule\n        });\n        continue;\n      }\n\n      // Feature value is being forced\n      if (\"force\" in rule) {\n        // If it's a conditional rule, skip if the condition doesn't pass\n        if (rule.condition && !conditionPasses(rule.condition, ctx)) {\n          process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip rule because of condition ff\", {\n            id,\n            rule\n          });\n          continue;\n        }\n\n        // If this is a percentage rollout, skip if not included\n        if (!isIncludedInRollout(ctx, rule.seed || id, rule.hashAttribute, ctx.user.saveStickyBucketAssignmentDoc && !rule.disableStickyBucketing ? rule.fallbackAttribute : undefined, rule.range, rule.coverage, rule.hashVersion)) {\n          process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip rule because user not included in rollout\", {\n            id,\n            rule\n          });\n          continue;\n        }\n        process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Force value from rule\", {\n          id,\n          rule\n        });\n\n        // If this was a remotely evaluated experiment, fire the tracking callbacks\n        if (rule.tracks) {\n          rule.tracks.forEach(t => {\n            const calls = onExperimentViewed(ctx, t.experiment, t.result);\n            if (!calls.length && ctx.global.saveDeferredTrack) {\n              ctx.global.saveDeferredTrack({\n                experiment: t.experiment,\n                result: t.result,\n                user: getTrackingUserContext(ctx.user)\n              });\n            }\n          });\n        }\n        return getFeatureResult(ctx, id, rule.force, \"force\", rule.id);\n      }\n      // Contextual bandit rules carry their variations under\n      // `contextualVariations` so older SDKs skip them; read either field here.\n      const ruleVariations = rule.contextualVariations ?? rule.variations;\n      if (!ruleVariations) {\n        process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip invalid rule\", {\n          id,\n          rule\n        });\n        continue;\n      }\n\n      // For experiment rules, run an experiment\n      const exp = {\n        variations: ruleVariations,\n        key: rule.key || id\n      };\n      if (\"coverage\" in rule) exp.coverage = rule.coverage;\n      if (rule.weights) exp.weights = rule.weights;\n      if (rule.hashAttribute) exp.hashAttribute = rule.hashAttribute;\n      if (rule.fallbackAttribute) exp.fallbackAttribute = rule.fallbackAttribute;\n      if (rule.disableStickyBucketing) exp.disableStickyBucketing = rule.disableStickyBucketing;\n      if (rule.bucketVersion !== undefined) exp.bucketVersion = rule.bucketVersion;\n      if (rule.minBucketVersion !== undefined) exp.minBucketVersion = rule.minBucketVersion;\n      if (rule.namespace) exp.namespace = rule.namespace;\n      if (rule.meta) exp.meta = rule.meta;\n      if (rule.ranges) exp.ranges = rule.ranges;\n      if (rule.name) exp.name = rule.name;\n      if (rule.phase) exp.phase = rule.phase;\n      if (rule.seed) exp.seed = rule.seed;\n      if (rule.hashVersion) exp.hashVersion = rule.hashVersion;\n      if (rule.filters) exp.filters = rule.filters;\n      if (rule.condition) exp.condition = rule.condition;\n      if (rule.contextualBanditRef) {\n        buildContextualBanditExperiment(exp, rule.contextualBanditRef, id, ctx);\n      }\n\n      // Only return a value if the user is part of the experiment\n      const {\n        result\n      } = runExperiment(exp, id, ctx);\n      if (exp.contextualBandit && !(result.hashUsed && result.inExperiment)) {\n        delete exp.contextualBandit;\n      }\n      ctx.global.onExperimentEval && ctx.global.onExperimentEval(exp, result);\n      if (result.inExperiment && !result.passthrough) {\n        return getFeatureResult(ctx, id, result.value, \"experiment\", rule.id, exp, result);\n      }\n    }\n  }\n  process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Use default value\", {\n    id,\n    value: feature.defaultValue\n  });\n\n  // Fall back to using the default value\n  return getFeatureResult(ctx, id, feature.defaultValue === undefined ? null : feature.defaultValue, \"defaultValue\");\n}\nexport function runExperiment(experiment, featureId, ctx) {\n  const key = experiment.key;\n  const numVariations = experiment.variations.length;\n\n  // 1. If experiment has less than 2 variations, return immediately\n  if (numVariations < 2) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Invalid experiment\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 2. If the context is disabled, return immediately\n  if (ctx.global.enabled === false || ctx.user.enabled === false) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Context disabled\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 2.5. Merge in experiment overrides from the context\n  experiment = mergeOverrides(experiment, ctx);\n  if (experiment.contextualBandit && experiment.weights) {\n    experiment.contextualBandit = {\n      ...experiment.contextualBandit,\n      variationWeights: experiment.weights\n    };\n  }\n\n  // 2.6 New, more powerful URL targeting\n  if (experiment.urlPatterns && !isURLTargeted(ctx.user.url || \"\", experiment.urlPatterns)) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of url targeting\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 3. If a variation is forced from a querystring, return the forced variation\n  const qsOverride = getQueryStringOverride(key, ctx.user.url || \"\", numVariations);\n  if (qsOverride !== null) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Force via querystring\", {\n      id: key,\n      variation: qsOverride\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, qsOverride, false, featureId)\n    };\n  }\n\n  // 4. If a variation is forced in the context, return the forced variation\n  const forcedVariations = getForcedVariations(ctx);\n  if (key in forcedVariations) {\n    const variation = forcedVariations[key];\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Force via dev tools\", {\n      id: key,\n      variation\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, variation, false, featureId)\n    };\n  }\n\n  // 5. Exclude if a draft experiment or not active\n  if (experiment.status === \"draft\" || experiment.active === false) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because inactive\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 6. Get the hash attribute and return if empty\n  const {\n    hashAttribute,\n    hashValue\n  } = getHashAttribute(ctx, experiment.hashAttribute, ctx.user.saveStickyBucketAssignmentDoc && !experiment.disableStickyBucketing ? experiment.fallbackAttribute : undefined);\n  if (!hashValue) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because missing hashAttribute\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n  let assigned = -1;\n  let foundStickyBucket = false;\n  let stickyBucketVersionIsBlocked = false;\n  if (ctx.user.saveStickyBucketAssignmentDoc && !experiment.disableStickyBucketing) {\n    const {\n      variation,\n      versionIsBlocked\n    } = getStickyBucketVariation({\n      ctx,\n      expKey: experiment.key,\n      expBucketVersion: experiment.bucketVersion,\n      expHashAttribute: experiment.hashAttribute,\n      expFallbackAttribute: experiment.fallbackAttribute,\n      expMinBucketVersion: experiment.minBucketVersion,\n      expMeta: experiment.meta\n    });\n    foundStickyBucket = variation >= 0;\n    assigned = variation;\n    stickyBucketVersionIsBlocked = !!versionIsBlocked;\n  }\n\n  // Some checks are not needed if we already have a sticky bucket\n  if (!foundStickyBucket) {\n    // 7. Exclude if user is filtered out (used to be called \"namespace\")\n    if (experiment.filters) {\n      if (isFilteredOut(experiment.filters, ctx)) {\n        process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of filters\", {\n          id: key\n        });\n        return {\n          result: getExperimentResult(ctx, experiment, -1, false, featureId)\n        };\n      }\n    } else if (experiment.namespace && !inNamespace(hashValue, experiment.namespace)) {\n      process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of namespace\", {\n        id: key\n      });\n      return {\n        result: getExperimentResult(ctx, experiment, -1, false, featureId)\n      };\n    }\n\n    // 7.5. Exclude if experiment.include returns false or throws\n    if (experiment.include && !isIncluded(experiment.include)) {\n      process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of include function\", {\n        id: key\n      });\n      return {\n        result: getExperimentResult(ctx, experiment, -1, false, featureId)\n      };\n    }\n\n    // 8. Exclude if condition is false\n    if (experiment.condition && !conditionPasses(experiment.condition, ctx)) {\n      process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of condition exp\", {\n        id: key\n      });\n      return {\n        result: getExperimentResult(ctx, experiment, -1, false, featureId)\n      };\n    }\n\n    // 8.05. Exclude if prerequisites are not met\n    if (experiment.parentConditions) {\n      const evaluatedFeatures = new Set(ctx.stack.evaluatedFeatures);\n      for (const parentCondition of experiment.parentConditions) {\n        ctx.stack.evaluatedFeatures = new Set(evaluatedFeatures);\n        const parentResult = evalFeature(parentCondition.id, ctx);\n        // break out for cyclic prerequisites\n        if (parentResult.source === \"cyclicPrerequisite\") {\n          return {\n            result: getExperimentResult(ctx, experiment, -1, false, featureId)\n          };\n        }\n        const evalObj = {\n          value: parentResult.value\n        };\n        if (!evalCondition(evalObj, parentCondition.condition || {}, ctx.global.savedGroups || {})) {\n          process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because prerequisite evaluation fails\", {\n            id: key\n          });\n          return {\n            result: getExperimentResult(ctx, experiment, -1, false, featureId)\n          };\n        }\n      }\n    }\n\n    // 8.1. Exclude if user is not in a required group\n    if (experiment.groups && !hasGroupOverlap(experiment.groups, ctx)) {\n      process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of groups\", {\n        id: key\n      });\n      return {\n        result: getExperimentResult(ctx, experiment, -1, false, featureId)\n      };\n    }\n  }\n\n  // 8.2. Old style URL targeting\n  if (experiment.url && !urlIsValid(experiment.url, ctx)) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of url\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 9. Get the variation from the sticky bucket or get bucket ranges and choose variation\n  const n = hash(experiment.seed || key, hashValue, experiment.hashVersion || 1);\n  if (n === null) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of invalid hash version\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n  if (!foundStickyBucket) {\n    const ranges = experiment.ranges || getBucketRanges(numVariations, experiment.coverage === undefined ? 1 : experiment.coverage, experiment.weights);\n    assigned = chooseVariation(n, ranges);\n  }\n\n  // 9.5 Unenroll if any prior sticky buckets are blocked by version\n  if (stickyBucketVersionIsBlocked) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because sticky bucket version is blocked\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId, undefined, true)\n    };\n  }\n\n  // 10. Return if not in experiment\n  if (assigned < 0) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because of coverage\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 11. Experiment has a forced variation\n  if (\"force\" in experiment) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Force variation\", {\n      id: key,\n      variation: experiment.force\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, experiment.force === undefined ? -1 : experiment.force, false, featureId)\n    };\n  }\n\n  // 12. Exclude if in QA mode\n  if (ctx.global.qaMode || ctx.user.qaMode) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because QA mode\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 12.5. Exclude if experiment is stopped\n  if (experiment.status === \"stopped\") {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Skip because stopped\", {\n      id: key\n    });\n    return {\n      result: getExperimentResult(ctx, experiment, -1, false, featureId)\n    };\n  }\n\n  // 13. Build the result object\n  const result = getExperimentResult(ctx, experiment, assigned, true, featureId, n, foundStickyBucket);\n\n  // 13.5. Persist sticky bucket\n  if (ctx.user.saveStickyBucketAssignmentDoc && !experiment.disableStickyBucketing) {\n    const {\n      changed,\n      key: attrKey,\n      doc\n    } = generateStickyBucketAssignmentDoc(ctx, hashAttribute, toString(hashValue), {\n      [getStickyBucketExperimentKey(experiment.key, experiment.bucketVersion)]: result.key\n    });\n    if (changed) {\n      // update local docs\n      ctx.user.stickyBucketAssignmentDocs = ctx.user.stickyBucketAssignmentDocs || {};\n      ctx.user.stickyBucketAssignmentDocs[attrKey] = doc;\n      // save doc\n      ctx.user.saveStickyBucketAssignmentDoc(doc);\n    }\n  }\n\n  // 14. Fire the tracking callback(s)\n  // Store the promise in case we're awaiting it (ex: browser url redirects)\n  const trackingCalls = onExperimentViewed(ctx, experiment, result);\n  if (trackingCalls.length === 0 && ctx.global.saveDeferredTrack) {\n    ctx.global.saveDeferredTrack({\n      experiment,\n      result,\n      user: getTrackingUserContext(ctx.user)\n    });\n  }\n  const trackingCall = !trackingCalls.length ? undefined : trackingCalls.length === 1 ? trackingCalls[0] : Promise.all(trackingCalls).then(() => {});\n\n  // 14.1 Keep track of completed changeIds\n  \"changeId\" in experiment && experiment.changeId && ctx.global.recordChangeId && ctx.global.recordChangeId(experiment.changeId);\n\n  // 15. Return the result\n  process.env.NODE_ENV !== \"production\" && ctx.global.log(\"In experiment\", {\n    id: key,\n    variation: result.variationId\n  });\n  return {\n    result,\n    trackingCall\n  };\n}\nfunction getFeatureResult(ctx, key, value, source, ruleId, experiment, result) {\n  const ret = {\n    value,\n    on: !!value,\n    off: !value,\n    source,\n    ruleId: ruleId || \"\"\n  };\n  if (experiment) ret.experiment = experiment;\n  if (result) ret.experimentResult = result;\n\n  // Track the usage of this feature in real-time\n  if (source !== \"override\") {\n    onFeatureUsage(ctx, key, ret);\n  }\n  return ret;\n}\nfunction getAttributes(user) {\n  return {\n    ...user.attributes,\n    ...user.attributeOverrides\n  };\n}\nexport function getTrackingUserContext(user) {\n  return {\n    attributes: getAttributes(user),\n    url: user.url\n  };\n}\nfunction getContextualBanditLeaf(cbDefinition, ctx) {\n  for (const context of cbDefinition.contexts || []) {\n    if (conditionPasses(context.condition || {}, ctx)) {\n      return {\n        leafId: context.leafId,\n        weights: context.weights\n      };\n    }\n  }\n  return null;\n}\nconst CONTEXTUAL_BANDIT_FALLBACK_LEAF_ID = -1;\nfunction buildContextualBanditExperiment(experiment, contextualBanditRef, id, ctx) {\n  const cbDefinition = ctx.global.contextualBandits?.[contextualBanditRef];\n  if (!cbDefinition) {\n    process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Contextual bandit ref not found in payload, using aggregate weights\", {\n      id,\n      contextualBanditRef\n    });\n    return;\n  }\n  let leaf = null;\n  if (cbDefinition.contexts && cbDefinition.contexts.length) {\n    try {\n      leaf = getContextualBanditLeaf(cbDefinition, ctx);\n    } catch (e) {\n      process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Contextual bandit leaf selection threw, using fallback weights\", {\n        id,\n        contextualBanditRef,\n        error: e\n      });\n    }\n  }\n  if (leaf) {\n    experiment.weights = leaf.weights;\n    experiment.contextualBandit = {\n      leafId: leaf.leafId,\n      variationWeights: leaf.weights,\n      banditVersion: cbDefinition.banditVersion\n    };\n    return;\n  }\n  process.env.NODE_ENV !== \"production\" && ctx.global.log(\"Contextual bandit: no matching leaf, using fallback weights\", {\n    id,\n    contextualBanditRef\n  });\n  experiment.contextualBandit = {\n    leafId: CONTEXTUAL_BANDIT_FALLBACK_LEAF_ID,\n    variationWeights: experiment.weights ?? getEqualWeights(experiment.variations.length),\n    banditVersion: cbDefinition.banditVersion\n  };\n}\nfunction conditionPasses(condition, ctx) {\n  return evalCondition(getAttributes(ctx.user), condition, ctx.global.savedGroups || {});\n}\nfunction isFilteredOut(filters, ctx) {\n  return filters.some(filter => {\n    const {\n      hashValue\n    } = getHashAttribute(ctx, filter.attribute);\n    if (!hashValue) return true;\n    const n = hash(filter.seed, hashValue, filter.hashVersion || 2);\n    if (n === null) return true;\n    return !filter.ranges.some(r => inRange(n, r));\n  });\n}\nfunction isIncludedInRollout(ctx, seed, hashAttribute, fallbackAttribute, range, coverage, hashVersion) {\n  if (!range && coverage === undefined) return true;\n  if (!range && coverage === 0) return false;\n  const {\n    hashValue\n  } = getHashAttribute(ctx, hashAttribute, fallbackAttribute);\n  if (!hashValue) {\n    return false;\n  }\n  const n = hash(seed, hashValue, hashVersion || 1);\n  if (n === null) return false;\n  return range ? inRange(n, range) : coverage !== undefined ? n <= coverage : true;\n}\nexport function getExperimentResult(ctx, experiment, variationIndex, hashUsed, featureId, bucket, stickyBucketUsed) {\n  let inExperiment = true;\n  // If assigned variation is not valid, use the baseline and mark the user as not in the experiment\n  if (variationIndex < 0 || variationIndex >= experiment.variations.length) {\n    variationIndex = 0;\n    inExperiment = false;\n  }\n  const {\n    hashAttribute,\n    hashValue\n  } = getHashAttribute(ctx, experiment.hashAttribute, ctx.user.saveStickyBucketAssignmentDoc && !experiment.disableStickyBucketing ? experiment.fallbackAttribute : undefined);\n  const meta = experiment.meta ? experiment.meta[variationIndex] : {};\n  const res = {\n    key: meta.key || \"\" + variationIndex,\n    featureId,\n    inExperiment,\n    hashUsed,\n    variationId: variationIndex,\n    value: experiment.variations[variationIndex],\n    hashAttribute,\n    hashValue,\n    stickyBucketUsed: !!stickyBucketUsed\n  };\n  if (meta.name) res.name = meta.name;\n  if (bucket !== undefined) res.bucket = bucket;\n  if (meta.passthrough) res.passthrough = meta.passthrough;\n  const cb = experiment.contextualBandit;\n  if (cb && hashUsed && inExperiment) {\n    res.leafId = cb.leafId;\n    res.variationWeights = cb.variationWeights;\n    if (cb.banditVersion !== undefined) res.banditVersion = cb.banditVersion;\n  }\n  return res;\n}\nfunction mergeOverrides(experiment, ctx) {\n  const key = experiment.key;\n  const o = ctx.global.overrides;\n  if (o && o[key]) {\n    experiment = Object.assign({}, experiment, o[key]);\n    if (typeof experiment.url === \"string\") {\n      experiment.url = getUrlRegExp(\n      // eslint-disable-next-line\n      experiment.url);\n    }\n  }\n  return experiment;\n}\nexport function getHashAttribute(ctx, attr, fallback) {\n  let hashAttribute = attr || \"id\";\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  let hashValue = \"\";\n  const attributes = getAttributes(ctx.user);\n  if (attributes[hashAttribute]) {\n    hashValue = attributes[hashAttribute];\n  }\n\n  // if no match, try fallback\n  if (!hashValue && fallback) {\n    if (attributes[fallback]) {\n      hashValue = attributes[fallback];\n    }\n    if (hashValue) {\n      hashAttribute = fallback;\n    }\n  }\n  return {\n    hashAttribute,\n    hashValue\n  };\n}\nfunction urlIsValid(urlRegex, ctx) {\n  const url = ctx.user.url;\n  if (!url) return false;\n  const pathOnly = url.replace(/^https?:\\/\\//, \"\").replace(/^[^/]*\\//, \"/\");\n  if (urlRegex.test(url)) return true;\n  if (urlRegex.test(pathOnly)) return true;\n  return false;\n}\nfunction hasGroupOverlap(expGroups, ctx) {\n  const groups = ctx.global.groups || {};\n  for (let i = 0; i < expGroups.length; i++) {\n    if (groups[expGroups[i]]) return true;\n  }\n  return false;\n}\nfunction getStickyBucketVariation({\n  ctx,\n  expKey,\n  expBucketVersion,\n  expHashAttribute,\n  expFallbackAttribute,\n  expMinBucketVersion,\n  expMeta\n}) {\n  expBucketVersion = expBucketVersion || 0;\n  expMinBucketVersion = expMinBucketVersion || 0;\n  expHashAttribute = expHashAttribute || \"id\";\n  expMeta = expMeta || [];\n  const id = getStickyBucketExperimentKey(expKey, expBucketVersion);\n  const assignments = getStickyBucketAssignments(ctx, expHashAttribute, expFallbackAttribute);\n\n  // users with any blocked bucket version (0 to minExperimentBucketVersion - 1) are excluded from the test\n  if (expMinBucketVersion > 0) {\n    for (let i = 0; i < expMinBucketVersion; i++) {\n      const blockedKey = getStickyBucketExperimentKey(expKey, i);\n      if (assignments[blockedKey] !== undefined) {\n        return {\n          variation: -1,\n          versionIsBlocked: true\n        };\n      }\n    }\n  }\n  const variationKey = assignments[id];\n  if (variationKey === undefined)\n    // no assignment found\n    return {\n      variation: -1\n    };\n  const variation = expMeta.findIndex(m => m.key === variationKey);\n  if (variation < 0)\n    // invalid assignment, treat as \"no assignment found\"\n    return {\n      variation: -1\n    };\n  return {\n    variation\n  };\n}\nfunction getStickyBucketExperimentKey(experimentKey, experimentBucketVersion) {\n  experimentBucketVersion = experimentBucketVersion || 0;\n  return `${experimentKey}__${experimentBucketVersion}`;\n}\nexport function getStickyBucketAttributeKey(attributeName, attributeValue) {\n  return `${attributeName}||${attributeValue}`;\n}\nfunction getStickyBucketAssignments(ctx, expHashAttribute, expFallbackAttribute) {\n  if (!ctx.user.stickyBucketAssignmentDocs) return {};\n  const {\n    hashAttribute,\n    hashValue\n  } = getHashAttribute(ctx, expHashAttribute);\n  const hashKey = getStickyBucketAttributeKey(hashAttribute, toString(hashValue));\n  const {\n    hashAttribute: fallbackAttribute,\n    hashValue: fallbackValue\n  } = getHashAttribute(ctx, expFallbackAttribute);\n  const fallbackKey = fallbackValue ? getStickyBucketAttributeKey(fallbackAttribute, toString(fallbackValue)) : null;\n  const assignments = {};\n  if (fallbackKey && ctx.user.stickyBucketAssignmentDocs[fallbackKey]) {\n    Object.assign(assignments, ctx.user.stickyBucketAssignmentDocs[fallbackKey].assignments || {});\n  }\n  if (ctx.user.stickyBucketAssignmentDocs[hashKey]) {\n    Object.assign(assignments, ctx.user.stickyBucketAssignmentDocs[hashKey].assignments || {});\n  }\n  return assignments;\n}\nfunction generateStickyBucketAssignmentDoc(ctx, attributeName, attributeValue, assignments) {\n  const key = getStickyBucketAttributeKey(attributeName, attributeValue);\n  const existingAssignments = ctx.user.stickyBucketAssignmentDocs && ctx.user.stickyBucketAssignmentDocs[key] ? ctx.user.stickyBucketAssignmentDocs[key].assignments || {} : {};\n  const newAssignments = {\n    ...existingAssignments,\n    ...assignments\n  };\n  const changed = JSON.stringify(existingAssignments) !== JSON.stringify(newAssignments);\n  return {\n    key,\n    doc: {\n      attributeName,\n      attributeValue,\n      assignments: newAssignments\n    },\n    changed\n  };\n}\nfunction deriveStickyBucketIdentifierAttributes(ctx, data) {\n  const attributes = new Set();\n  const features = data && data.features ? data.features : ctx.global.features || {};\n  const experiments = data && data.experiments ? data.experiments : ctx.global.experiments || [];\n  Object.keys(features).forEach(id => {\n    const feature = features[id];\n    if (feature.rules) {\n      for (const rule of feature.rules) {\n        // Contextual bandit rules carry their variations under `contextualVariations`\n        if (rule.variations || rule.contextualVariations) {\n          attributes.add(rule.hashAttribute || \"id\");\n          if (rule.fallbackAttribute) {\n            attributes.add(rule.fallbackAttribute);\n          }\n        }\n      }\n    }\n  });\n  experiments.map(experiment => {\n    attributes.add(experiment.hashAttribute || \"id\");\n    if (experiment.fallbackAttribute) {\n      attributes.add(experiment.fallbackAttribute);\n    }\n  });\n  return Array.from(attributes);\n}\nexport async function getAllStickyBucketAssignmentDocs(ctx, stickyBucketService, data) {\n  const attributes = getStickyBucketAttributes(ctx, data);\n  return stickyBucketService.getAllAssignments(attributes);\n}\nexport function getStickyBucketAttributes(ctx, data) {\n  const attributes = {};\n  const stickyBucketIdentifierAttributes = deriveStickyBucketIdentifierAttributes(ctx, data);\n  stickyBucketIdentifierAttributes.forEach(attr => {\n    const {\n      hashValue\n    } = getHashAttribute(ctx, attr);\n    attributes[attr] = toString(hashValue);\n  });\n  return attributes;\n}\nexport async function decryptPayload(data, decryptionKey, subtle) {\n  data = {\n    ...data\n  };\n  if (data.encryptedFeatures) {\n    try {\n      data.features = JSON.parse(await decrypt(data.encryptedFeatures, decryptionKey, subtle));\n    } catch (e) {\n      console.error(e);\n    }\n    delete data.encryptedFeatures;\n  }\n  if (data.encryptedExperiments) {\n    try {\n      data.experiments = JSON.parse(await decrypt(data.encryptedExperiments, decryptionKey, subtle));\n    } catch (e) {\n      console.error(e);\n    }\n    delete data.encryptedExperiments;\n  }\n  if (data.encryptedSavedGroups) {\n    try {\n      data.savedGroups = JSON.parse(await decrypt(data.encryptedSavedGroups, decryptionKey, subtle));\n    } catch (e) {\n      console.error(e);\n    }\n    delete data.encryptedSavedGroups;\n  }\n  if (data.encryptedContextualBandits) {\n    try {\n      data.contextualBandits = JSON.parse(await decrypt(data.encryptedContextualBandits, decryptionKey, subtle));\n    } catch (e) {\n      console.error(e);\n    }\n    delete data.encryptedContextualBandits;\n  }\n  return data;\n}\nexport function getApiHosts(options) {\n  const defaultHost = options.apiHost || \"https://cdn.growthbook.io\";\n  return {\n    apiHost: defaultHost.replace(/\\/*$/, \"\"),\n    streamingHost: (options.streamingHost || defaultHost).replace(/\\/*$/, \"\"),\n    apiRequestHeaders: options.apiHostRequestHeaders,\n    streamingHostRequestHeaders: options.streamingHostRequestHeaders\n  };\n}\nexport function getExperimentDedupeKey(experiment, result) {\n  return result.hashAttribute + result.hashValue + experiment.key + result.variationId;\n}\n//# sourceMappingURL=core.mjs.map","import mutate from \"dom-mutator\";\nimport { decrypt, getAutoExperimentChangeType, isURLTargeted, loadSDKVersion, mergeQueryStrings, promiseTimeout } from \"./util.mjs\";\nimport { clearAutoRefresh, configureCache, refreshFeatures, startBackgroundSync, unsubscribe } from \"./feature-repository.mjs\";\nimport { runExperiment, evalFeature as _evalFeature, getExperimentResult, getAllStickyBucketAssignmentDocs, decryptPayload, getApiHosts, getExperimentDedupeKey, getStickyBucketAttributes, getTrackingUserContext } from \"./core.mjs\";\nconst isBrowser = typeof window !== \"undefined\" && typeof document !== \"undefined\";\nconst SDK_VERSION = loadSDKVersion();\nexport class GrowthBook {\n  // context is technically private, but some tools depend on it so we can't mangle the name\n\n  // Properties and methods that start with \"_\" are mangled by Terser (saves ~150 bytes)\n\n  constructor(options) {\n    options = options || {};\n    // These properties are all initialized in the constructor instead of above\n    // This saves ~80 bytes in the final output\n    this.version = SDK_VERSION;\n    this._options = this.context = options;\n    this._renderer = options.renderer || null;\n    this._trackedExperiments = new Set();\n    this._completedChangeIds = new Set();\n    this._trackedFeatures = {};\n    this.debug = !!options.debug;\n    this._subscriptions = new Set();\n    this._featureUsageSubs = new Set();\n    this._customEventSubs = new Set();\n    this._experimentViewedSubs = new Set();\n    this.ready = false;\n    this._assigned = new Map();\n    this._activeAutoExperiments = new Map();\n    this._triggeredExpKeys = new Set();\n    this._initialized = false;\n    this._redirectedUrl = \"\";\n    this._deferredTrackingCalls = new Map();\n    this._autoExperimentsAllowed = !options.disableExperimentsOnLoad;\n    this._destroyCallbacks = [];\n    this.logs = [];\n    this.log = this.log.bind(this);\n    this._saveDeferredTrack = this._saveDeferredTrack.bind(this);\n    this._onExperimentEval = this._onExperimentEval.bind(this);\n    this._fireSubscriptions = this._fireSubscriptions.bind(this);\n    this._recordChangedId = this._recordChangedId.bind(this);\n    if (options.remoteEval) {\n      if (options.decryptionKey) {\n        throw new Error(\"Encryption is not available for remoteEval\");\n      }\n      if (!options.clientKey) {\n        throw new Error(\"Missing clientKey\");\n      }\n      let isGbHost = false;\n      try {\n        isGbHost = !!new URL(options.apiHost || \"\").hostname.match(/growthbook\\.io$/i);\n      } catch (e) {\n        // ignore invalid URLs\n      }\n      if (isGbHost) {\n        throw new Error(\"Cannot use remoteEval on GrowthBook Cloud\");\n      }\n    } else {\n      if (options.cacheKeyAttributes) {\n        throw new Error(\"cacheKeyAttributes are only used for remoteEval\");\n      }\n    }\n    if (options.stickyBucketService) {\n      const s = options.stickyBucketService;\n      this._saveStickyBucketAssignmentDoc = doc => {\n        return s.saveAssignments(doc);\n      };\n    }\n    if (options.plugins) {\n      for (const plugin of options.plugins) {\n        plugin(this);\n      }\n    }\n    if (options.features) {\n      this.ready = true;\n    }\n    if (isBrowser && options.enableDevMode) {\n      window._growthbook = this;\n      document.dispatchEvent(new Event(\"gbloaded\"));\n    }\n    if (options.experiments) {\n      this.ready = true;\n      this._updateAllAutoExperiments();\n    }\n\n    // Hydrate sticky bucket service\n    if (this._options.stickyBucketService && this._options.stickyBucketAssignmentDocs) {\n      for (const key in this._options.stickyBucketAssignmentDocs) {\n        const doc = this._options.stickyBucketAssignmentDocs[key];\n        if (doc) {\n          this._options.stickyBucketService.saveAssignments(doc).catch(() => {\n            // Ignore hydration errors\n          });\n        }\n      }\n    }\n\n    // Legacy - passing in features/experiments into the constructor instead of using init\n    if (this.ready) {\n      this.refreshStickyBuckets(this.getPayload());\n    }\n  }\n  async setPayload(payload) {\n    this._payload = payload;\n    const data = await decryptPayload(payload, this._options.decryptionKey);\n    this._decryptedPayload = data;\n    await this.refreshStickyBuckets(data);\n    if (data.features) {\n      this._options.features = data.features;\n    }\n    if (data.savedGroups) {\n      this._options.savedGroups = data.savedGroups;\n    }\n    if (data.contextualBandits) {\n      this._options.contextualBandits = data.contextualBandits;\n    }\n    if (data.experiments) {\n      this._options.experiments = data.experiments;\n      this._updateAllAutoExperiments();\n    }\n    this.ready = true;\n    this._render();\n  }\n  initSync(options) {\n    this._initialized = true;\n    const payload = options.payload;\n    if (payload.encryptedExperiments || payload.encryptedFeatures) {\n      throw new Error(\"initSync does not support encrypted payloads\");\n    }\n    if (this._options.stickyBucketService && !this._options.stickyBucketAssignmentDocs) {\n      this._options.stickyBucketAssignmentDocs = this.generateStickyBucketAssignmentDocsSync(this._options.stickyBucketService, payload);\n    }\n    this._payload = payload;\n    this._decryptedPayload = payload;\n    if (payload.features) {\n      this._options.features = payload.features;\n    }\n    if (payload.savedGroups) {\n      this._options.savedGroups = payload.savedGroups;\n    }\n    if (payload.contextualBandits) {\n      this._options.contextualBandits = payload.contextualBandits;\n    }\n    if (payload.experiments) {\n      this._options.experiments = payload.experiments;\n      this._updateAllAutoExperiments();\n    }\n    this.ready = true;\n    startBackgroundSync(this, options);\n    return this;\n  }\n  async init(options) {\n    this._initialized = true;\n    options = options || {};\n    if (options.cacheSettings) {\n      configureCache(options.cacheSettings);\n    }\n    if (options.payload) {\n      await this.setPayload(options.payload);\n      startBackgroundSync(this, options);\n      return {\n        success: true,\n        source: \"init\"\n      };\n    } else {\n      const {\n        data,\n        ...res\n      } = await this._refresh({\n        ...options,\n        allowStale: true\n      });\n      startBackgroundSync(this, options);\n      await this.setPayload(data || {});\n      return res;\n    }\n  }\n\n  /** @deprecated Use {@link init} */\n  async loadFeatures(options) {\n    options = options || {};\n    await this.init({\n      skipCache: options.skipCache,\n      timeout: options.timeout,\n      streaming: (this._options.backgroundSync ?? true) && (options.autoRefresh || this._options.subscribeToChanges)\n    });\n  }\n  async refreshFeatures(options) {\n    const res = await this._refresh({\n      ...(options || {}),\n      allowStale: false\n    });\n    if (res.data) {\n      await this.setPayload(res.data);\n    }\n  }\n  getApiInfo() {\n    return [this.getApiHosts().apiHost, this.getClientKey()];\n  }\n  getApiHosts() {\n    return getApiHosts(this._options);\n  }\n  getClientKey() {\n    return this._options.clientKey || \"\";\n  }\n  getPayload() {\n    return this._payload || {\n      features: this.getFeatures(),\n      experiments: this.getExperiments()\n    };\n  }\n  getDecryptedPayload() {\n    return this._decryptedPayload || this.getPayload();\n  }\n  isRemoteEval() {\n    return this._options.remoteEval || false;\n  }\n  getCacheKeyAttributes() {\n    return this._options.cacheKeyAttributes;\n  }\n  async _refresh({\n    timeout,\n    skipCache,\n    allowStale,\n    streaming\n  }) {\n    if (!this._options.clientKey) {\n      throw new Error(\"Missing clientKey\");\n    }\n    // Trigger refresh in feature repository\n    return refreshFeatures({\n      instance: this,\n      timeout,\n      skipCache: skipCache || this._options.disableCache,\n      allowStale,\n      backgroundSync: streaming ?? this._options.backgroundSync ?? true\n    });\n  }\n  _render() {\n    if (this._renderer) {\n      try {\n        this._renderer();\n      } catch (e) {\n        console.error(\"Failed to render\", e);\n      }\n    }\n  }\n\n  /** @deprecated Use {@link setPayload} */\n  setFeatures(features) {\n    this._options.features = features;\n    this.ready = true;\n    this._render();\n  }\n\n  /** @deprecated Use {@link setPayload} */\n  async setEncryptedFeatures(encryptedString, decryptionKey, subtle) {\n    const featuresJSON = await decrypt(encryptedString, decryptionKey || this._options.decryptionKey, subtle);\n    this.setFeatures(JSON.parse(featuresJSON));\n  }\n\n  /** @deprecated Use {@link setPayload} */\n  setExperiments(experiments) {\n    this._options.experiments = experiments;\n    this.ready = true;\n    this._updateAllAutoExperiments();\n  }\n\n  /** @deprecated Use {@link setPayload} */\n  async setEncryptedExperiments(encryptedString, decryptionKey, subtle) {\n    const experimentsJSON = await decrypt(encryptedString, decryptionKey || this._options.decryptionKey, subtle);\n    this.setExperiments(JSON.parse(experimentsJSON));\n  }\n  async setAttributes(attributes) {\n    this._options.attributes = attributes;\n    if (this._options.stickyBucketService) {\n      await this.refreshStickyBuckets();\n    }\n    if (this._options.remoteEval) {\n      await this._refreshForRemoteEval();\n      return;\n    }\n    this._render();\n    this._updateAllAutoExperiments();\n  }\n  async updateAttributes(attributes) {\n    return this.setAttributes({\n      ...this._options.attributes,\n      ...attributes\n    });\n  }\n  async setAttributeOverrides(overrides) {\n    this._options.attributeOverrides = overrides;\n    if (this._options.stickyBucketService) {\n      await this.refreshStickyBuckets();\n    }\n    if (this._options.remoteEval) {\n      await this._refreshForRemoteEval();\n      return;\n    }\n    this._render();\n    this._updateAllAutoExperiments();\n  }\n  async setForcedVariations(vars) {\n    this._options.forcedVariations = vars || {};\n    if (this._options.remoteEval) {\n      await this._refreshForRemoteEval();\n      return;\n    }\n    this._render();\n    this._updateAllAutoExperiments();\n  }\n\n  // eslint-disable-next-line\n  setForcedFeatures(map) {\n    this._options.forcedFeatureValues = map;\n    this._render();\n  }\n  async setURL(url) {\n    if (url === this._options.url) return;\n    this._options.url = url;\n    this._redirectedUrl = \"\";\n    if (this._options.remoteEval) {\n      await this._refreshForRemoteEval();\n      this._updateAllAutoExperiments(true);\n      return;\n    }\n    this._updateAllAutoExperiments(true);\n  }\n  getAttributes() {\n    return {\n      ...this._options.attributes,\n      ...this._options.attributeOverrides\n    };\n  }\n  getForcedVariations() {\n    return this._options.forcedVariations || {};\n  }\n  getForcedFeatures() {\n    // eslint-disable-next-line\n    return this._options.forcedFeatureValues || new Map();\n  }\n  getStickyBucketAssignmentDocs() {\n    return this._options.stickyBucketAssignmentDocs || {};\n  }\n  getUrl() {\n    return this._options.url || \"\";\n  }\n  getFeatures() {\n    return this._options.features || {};\n  }\n  getExperiments() {\n    return this._options.experiments || [];\n  }\n  getCompletedChangeIds() {\n    return Array.from(this._completedChangeIds);\n  }\n  subscribe(cb) {\n    this._subscriptions.add(cb);\n    return () => {\n      this._subscriptions.delete(cb);\n    };\n  }\n\n  // Internal — first-party plugin use only.\n  // Currently singleton-only. UserScopedGrowthBook could use the same signatures;\n  // GrowthBookClient would need UserContext in callbacks to identify the user.\n  // Fires on deduped feature value changes (not every evalFeature call). Overrides excluded.\n  // One of three plugin streams: feature usage, experiment assignments (_subscribeExperimentViewed), custom events.\n  _subscribeFeatureUsage(cb) {\n    this._featureUsageSubs.add(cb);\n    return () => this._featureUsageSubs.delete(cb);\n  }\n\n  // Internal — first-party plugin use only.\n  // Fires once per deduped experiment assignment, alongside (not instead of) trackingCallback.\n  _subscribeExperimentViewed(cb) {\n    this._experimentViewedSubs.add(cb);\n    return () => this._experimentViewedSubs.delete(cb);\n  }\n\n  // Internal — first-party plugin use only.\n  // Fires for explicit logEvent() calls only, not SDK-internal events.\n  _subscribeCustomEvents(cb) {\n    this._customEventSubs.add(cb);\n    return () => this._customEventSubs.delete(cb);\n  }\n  async _refreshForRemoteEval() {\n    if (!this._options.remoteEval) return;\n    if (!this._initialized) return;\n    const res = await this._refresh({\n      allowStale: false\n    });\n    if (res.data) {\n      await this.setPayload(res.data);\n    }\n  }\n  getAllResults() {\n    return new Map(this._assigned);\n  }\n  onDestroy(cb) {\n    this._destroyCallbacks.push(cb);\n  }\n  isDestroyed() {\n    return !!this._destroyed;\n  }\n  destroy(options) {\n    options = options || {};\n    this._destroyed = true;\n\n    // Custom callbacks\n    // Do this first in case it needs access to the below data that is cleared\n    this._destroyCallbacks.forEach(cb => {\n      try {\n        cb();\n      } catch (e) {\n        console.error(e);\n      }\n    });\n\n    // Release references to save memory\n    this._subscriptions.clear();\n    this._featureUsageSubs.clear();\n    this._customEventSubs.clear();\n    this._experimentViewedSubs.clear();\n    this._assigned.clear();\n    this._trackedExperiments.clear();\n    this._completedChangeIds.clear();\n    this._deferredTrackingCalls.clear();\n    this._trackedFeatures = {};\n    this._destroyCallbacks = [];\n    this._payload = undefined;\n    this._saveStickyBucketAssignmentDoc = undefined;\n    unsubscribe(this);\n    if (options.destroyAllStreams) {\n      clearAutoRefresh();\n    }\n    this.logs = [];\n    if (isBrowser && window._growthbook === this) {\n      delete window._growthbook;\n    }\n\n    // Undo any active auto experiments\n    this._activeAutoExperiments.forEach(exp => {\n      exp.undo();\n    });\n    this._activeAutoExperiments.clear();\n    this._triggeredExpKeys.clear();\n  }\n  setRenderer(renderer) {\n    this._renderer = renderer;\n  }\n  forceVariation(key, variation) {\n    this._options.forcedVariations = this._options.forcedVariations || {};\n    this._options.forcedVariations[key] = variation;\n    if (this._options.remoteEval) {\n      this._refreshForRemoteEval();\n      return;\n    }\n    this._updateAllAutoExperiments();\n    this._render();\n  }\n  run(experiment) {\n    const {\n      result\n    } = runExperiment(experiment, null, this._getEvalContext());\n    this._onExperimentEval(experiment, result);\n    return result;\n  }\n  triggerExperiment(key) {\n    this._triggeredExpKeys.add(key);\n    if (!this._options.experiments) return null;\n    const experiments = this._options.experiments.filter(exp => exp.key === key);\n    return experiments.map(exp => {\n      return this._runAutoExperiment(exp);\n    }).filter(res => res !== null);\n  }\n  triggerAutoExperiments() {\n    this._autoExperimentsAllowed = true;\n    this._updateAllAutoExperiments(true);\n  }\n  _getEvalContext() {\n    return {\n      user: this._getUserContext(),\n      global: this._getGlobalContext(),\n      stack: {\n        evaluatedFeatures: new Set()\n      }\n    };\n  }\n  _getUserContext() {\n    return {\n      attributes: this._options.user ? {\n        ...this._options.user,\n        ...this._options.attributes\n      } : this._options.attributes,\n      enableDevMode: this._options.enableDevMode,\n      blockedChangeIds: this._options.blockedChangeIds,\n      stickyBucketAssignmentDocs: this._options.stickyBucketAssignmentDocs,\n      url: this._getContextUrl(),\n      forcedVariations: this._options.forcedVariations,\n      forcedFeatureValues: this._options.forcedFeatureValues,\n      attributeOverrides: this._options.attributeOverrides,\n      saveStickyBucketAssignmentDoc: this._saveStickyBucketAssignmentDoc,\n      trackingCallback: this._options.trackingCallback,\n      onFeatureUsage: this._options.onFeatureUsage,\n      devLogs: this.logs,\n      featureUsageSubs: this._featureUsageSubs,\n      experimentViewedSubs: this._experimentViewedSubs,\n      trackedExperiments: this._trackedExperiments,\n      trackedFeatureUsage: this._trackedFeatures\n    };\n  }\n  _getGlobalContext() {\n    return {\n      features: this._options.features,\n      experiments: this._options.experiments,\n      log: this.log,\n      enabled: this._options.enabled,\n      qaMode: this._options.qaMode,\n      savedGroups: this._options.savedGroups,\n      contextualBandits: this._options.contextualBandits,\n      groups: this._options.groups,\n      overrides: this._options.overrides,\n      onExperimentEval: this._onExperimentEval,\n      recordChangeId: this._recordChangedId,\n      saveDeferredTrack: this._saveDeferredTrack,\n      eventLogger: this._options.eventLogger\n    };\n  }\n  _runAutoExperiment(experiment, forceRerun) {\n    const existing = this._activeAutoExperiments.get(experiment);\n\n    // If this is a manual experiment and it's not already running, skip\n    if (experiment.manual && !this._triggeredExpKeys.has(experiment.key) && !existing) return null;\n\n    // Check if this particular experiment is blocked by options settings\n    // For example, if all visualEditor experiments are disabled\n    const isBlocked = this._isAutoExperimentBlockedByContext(experiment);\n    if (isBlocked) {\n      process.env.NODE_ENV !== \"production\" && this.log(\"Auto experiment blocked\", {\n        id: experiment.key\n      });\n    }\n    let result;\n    let trackingCall;\n    // Run the experiment (if blocked exclude)\n    if (isBlocked) {\n      result = getExperimentResult(this._getEvalContext(), experiment, -1, false, \"\");\n    } else {\n      ({\n        result,\n        trackingCall\n      } = runExperiment(experiment, null, this._getEvalContext()));\n      this._onExperimentEval(experiment, result);\n    }\n\n    // A hash to quickly tell if the assigned value changed\n    const valueHash = JSON.stringify(result.value);\n\n    // If the changes are already active, no need to re-apply them\n    if (!forceRerun && result.inExperiment && existing && existing.valueHash === valueHash) {\n      return result;\n    }\n\n    // Undo any existing changes\n    if (existing) this._undoActiveAutoExperiment(experiment);\n\n    // Apply new changes\n    if (result.inExperiment) {\n      const changeType = getAutoExperimentChangeType(experiment);\n      if (changeType === \"redirect\" && result.value.urlRedirect && experiment.urlPatterns) {\n        const url = experiment.persistQueryString ? mergeQueryStrings(this._getContextUrl(), result.value.urlRedirect) : result.value.urlRedirect;\n        if (isURLTargeted(url, experiment.urlPatterns)) {\n          this.log(\"Skipping redirect because original URL matches redirect URL\", {\n            id: experiment.key\n          });\n          return result;\n        }\n        this._redirectedUrl = url;\n        const {\n          navigate,\n          delay\n        } = this._getNavigateFunction();\n        if (navigate) {\n          if (isBrowser) {\n            // Wait for the possibly-async tracking callback, bound by min and max delays\n            Promise.all([...(trackingCall ? [promiseTimeout(trackingCall, this._options.maxNavigateDelay ?? 1000)] : []), new Promise(resolve => window.setTimeout(resolve, this._options.navigateDelay ?? delay))]).then(() => {\n              try {\n                navigate(url);\n              } catch (e) {\n                console.error(e);\n              }\n            });\n          } else {\n            try {\n              navigate(url);\n            } catch (e) {\n              console.error(e);\n            }\n          }\n        }\n      } else if (changeType === \"visual\") {\n        const undo = this._options.applyDomChangesCallback ? this._options.applyDomChangesCallback(result.value) : this._applyDOMChanges(result.value);\n        if (undo) {\n          this._activeAutoExperiments.set(experiment, {\n            undo,\n            valueHash\n          });\n        }\n      }\n    }\n    return result;\n  }\n  _undoActiveAutoExperiment(exp) {\n    const data = this._activeAutoExperiments.get(exp);\n    if (data) {\n      data.undo();\n      this._activeAutoExperiments.delete(exp);\n    }\n  }\n  _updateAllAutoExperiments(forceRerun) {\n    if (!this._autoExperimentsAllowed) return;\n    const experiments = this._options.experiments || [];\n\n    // Stop any experiments that are no longer defined\n    const keys = new Set(experiments);\n    this._activeAutoExperiments.forEach((v, k) => {\n      if (!keys.has(k)) {\n        v.undo();\n        this._activeAutoExperiments.delete(k);\n      }\n    });\n\n    // Re-run all new/updated experiments\n    for (const exp of experiments) {\n      const result = this._runAutoExperiment(exp, forceRerun);\n\n      // Once you're in a redirect experiment, break out of the loop and don't run any further experiments\n      if (result && result.inExperiment && getAutoExperimentChangeType(exp) === \"redirect\") {\n        break;\n      }\n    }\n  }\n  _onExperimentEval(experiment, result) {\n    const prev = this._assigned.get(experiment.key);\n    this._assigned.set(experiment.key, {\n      experiment,\n      result\n    });\n    if (this._subscriptions.size > 0) {\n      this._fireSubscriptions(experiment, result, prev);\n    }\n  }\n  _fireSubscriptions(experiment, result,\n  // eslint-disable-next-line\n  prev) {\n    // If assigned variation has changed, fire subscriptions\n    // TODO: what if the experiment definition has changed?\n    if (!prev || prev.result.inExperiment !== result.inExperiment || prev.result.variationId !== result.variationId) {\n      this._subscriptions.forEach(cb => {\n        try {\n          cb(experiment, result);\n        } catch (e) {\n          console.error(e);\n        }\n      });\n    }\n  }\n  _recordChangedId(id) {\n    this._completedChangeIds.add(id);\n  }\n  isOn(key) {\n    return this.evalFeature(key).on;\n  }\n  isOff(key) {\n    return this.evalFeature(key).off;\n  }\n  getFeatureValue(key, defaultValue) {\n    const value = this.evalFeature(key).value;\n    return value === null ? defaultValue : value;\n  }\n\n  /**\n   * @deprecated Use {@link evalFeature}\n   * @param id\n   */\n\n  feature(id) {\n    return this.evalFeature(id);\n  }\n  evalFeature(id) {\n    return _evalFeature(id, this._getEvalContext());\n  }\n  log(msg, ctx) {\n    if (!this.debug) return;\n    if (this._options.log) this._options.log(msg, ctx);else console.log(msg, ctx);\n  }\n  getDeferredTrackingCalls() {\n    return Array.from(this._deferredTrackingCalls.values());\n  }\n  setDeferredTrackingCalls(calls) {\n    this._deferredTrackingCalls = new Map(calls.filter(c => c && c.experiment && c.result).map(c => {\n      return [getExperimentDedupeKey(c.experiment, c.result), c];\n    }));\n  }\n  async fireDeferredTrackingCalls() {\n    if (!this._options.trackingCallback) return;\n    const promises = [];\n    this._deferredTrackingCalls.forEach(call => {\n      if (!call || !call.experiment || !call.result) {\n        console.error(\"Invalid deferred tracking call\", {\n          call: call\n        });\n      } else {\n        promises.push(this._options.trackingCallback(call.experiment, call.result, call.user));\n      }\n    });\n    this._deferredTrackingCalls.clear();\n    await Promise.all(promises);\n  }\n  setTrackingCallback(callback) {\n    this._options.trackingCallback = callback;\n    this.fireDeferredTrackingCalls();\n  }\n  setFeatureUsageCallback(callback) {\n    this._options.onFeatureUsage = callback;\n  }\n  setEventLogger(logger) {\n    this._options.eventLogger = logger;\n  }\n  async logEvent(eventName, properties) {\n    if (this._destroyed) {\n      console.error(\"Cannot log event to destroyed GrowthBook instance\");\n      return;\n    }\n    if (this._options.enableDevMode) {\n      this.logs.push({\n        eventName,\n        properties,\n        timestamp: Date.now().toString(),\n        logType: \"event\"\n      });\n    }\n    if (this._customEventSubs.size) {\n      this._customEventSubs.forEach(cb => {\n        try {\n          cb(eventName, properties || {});\n        } catch (e) {\n          console.error(e);\n        }\n      });\n    }\n    if (this._options.eventLogger) {\n      try {\n        await this._options.eventLogger(eventName, properties || {}, getTrackingUserContext(this._getUserContext()));\n      } catch (e) {\n        console.error(e);\n      }\n    } else {\n      console.error(\"No event logger configured\");\n    }\n  }\n  _saveDeferredTrack(data) {\n    this._deferredTrackingCalls.set(getExperimentDedupeKey(data.experiment, data.result), data);\n  }\n  _getContextUrl() {\n    return this._options.url || (isBrowser ? window.location.href : \"\");\n  }\n  _isAutoExperimentBlockedByContext(experiment) {\n    const changeType = getAutoExperimentChangeType(experiment);\n    if (changeType === \"visual\") {\n      if (this._options.disableVisualExperiments) return true;\n      if (this._options.disableJsInjection) {\n        if (experiment.variations.some(v => v.js)) {\n          return true;\n        }\n      }\n    } else if (changeType === \"redirect\") {\n      if (this._options.disableUrlRedirectExperiments) return true;\n\n      // Validate URLs\n      try {\n        const current = new URL(this._getContextUrl());\n        for (const v of experiment.variations) {\n          if (!v || !v.urlRedirect) continue;\n          const url = new URL(v.urlRedirect);\n\n          // If we're blocking cross origin redirects, block if the protocol or host is different\n          if (this._options.disableCrossOriginUrlRedirectExperiments) {\n            if (url.protocol !== current.protocol) return true;\n            if (url.host !== current.host) return true;\n          }\n        }\n      } catch (e) {\n        // Problem parsing one of the URLs\n        this.log(\"Error parsing current or redirect URL\", {\n          id: experiment.key,\n          error: e\n        });\n        return true;\n      }\n    } else {\n      // Block any unknown changeTypes\n      return true;\n    }\n    if (experiment.changeId && (this._options.blockedChangeIds || []).includes(experiment.changeId)) {\n      return true;\n    }\n    return false;\n  }\n  getRedirectUrl() {\n    return this._redirectedUrl;\n  }\n  _getNavigateFunction() {\n    if (this._options.navigate) {\n      return {\n        navigate: this._options.navigate,\n        delay: 0\n      };\n    } else if (isBrowser) {\n      return {\n        navigate: url => {\n          window.location.replace(url);\n        },\n        delay: 100\n      };\n    }\n    return {\n      navigate: null,\n      delay: 0\n    };\n  }\n  _applyDOMChanges(changes) {\n    if (!isBrowser) return;\n    const undo = [];\n    if (changes.css) {\n      const s = document.createElement(\"style\");\n      s.innerHTML = changes.css;\n      document.head.appendChild(s);\n      undo.push(() => s.remove());\n    }\n    if (changes.js) {\n      const script = document.createElement(\"script\");\n      script.innerHTML = changes.js;\n      if (this._options.jsInjectionNonce) {\n        script.nonce = this._options.jsInjectionNonce;\n      }\n      document.head.appendChild(script);\n      undo.push(() => script.remove());\n    }\n    if (changes.domMutations) {\n      changes.domMutations.forEach(mutation => {\n        undo.push(mutate.declarative(mutation).revert);\n      });\n    }\n    return () => {\n      undo.forEach(fn => fn());\n    };\n  }\n  async refreshStickyBuckets(data) {\n    if (this._options.stickyBucketService) {\n      const ctx = this._getEvalContext();\n      const docs = await getAllStickyBucketAssignmentDocs(ctx, this._options.stickyBucketService, data);\n      this._options.stickyBucketAssignmentDocs = docs;\n    }\n  }\n  generateStickyBucketAssignmentDocsSync(stickyBucketService, payload) {\n    if (!(\"getAllAssignmentsSync\" in stickyBucketService)) {\n      console.error(\"generating StickyBucketAssignmentDocs docs requires StickyBucketServiceSync\");\n      return;\n    }\n    const ctx = this._getEvalContext();\n    const attributes = getStickyBucketAttributes(ctx, payload);\n    return stickyBucketService.getAllAssignmentsSync(attributes);\n  }\n  inDevMode() {\n    return !!this._options.enableDevMode;\n  }\n}\nexport async function prefetchPayload(options) {\n  // Create a temporary instance, just to fetch the payload\n  const instance = new GrowthBook(options);\n  await refreshFeatures({\n    instance,\n    skipCache: options.skipCache,\n    allowStale: false,\n    backgroundSync: options.streaming\n  });\n  instance.destroy();\n}\n//# sourceMappingURL=GrowthBook.mjs.map","/**\n * Returns a timestamp in milliseconds for measuring durations.\n *\n * This decorates performance.now().\n *\n * This tries to use the native high-resolution epoch, falling back to Date.now().\n *\n * If native throws, this still returns a value, but it logs a message as a side effect.\n *\n * This happens in a try/catch, so it is safe.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance/now\n */\nexport function now() {\n  try {\n    if (typeof performance?.now === 'function') {\n      return performance.now();\n    }\n  } catch (error) {\n    console.debug(error);\n  }\n\n  return Date.now();\n}\n\n/**\n * Records a named point on the User Timing timeline in devtools.\n *\n * This decorates performance.mark within a try/catch that suppresses errors.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark\n */\nexport function mark(name: string) {\n  try {\n    if (typeof performance?.mark === 'function') {\n      performance.mark(name);\n    }\n  } catch (error) {\n    console.debug(error);\n  }\n}\n\n/**\n * Records a named span between two timestamps on the User Timing timeline in devtools.\n *\n * This decorates performance.measure within a try/catch that suppresses errors.\n *\n * The bounds are explicit timestamps rather than named marks, which avoids the error the marked\n * name form throws when a start mark was never recorded.\n *\n * The detail param is optional and must be structured-cloneable. It should be a plain object. If\n * the value cannot be cloned, then performance.measure throws, which is caught and logged by this\n * wrapper. If specified, the detail shows up in the tooltip in the devtools panel.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure\n */\nexport function measure(name: string, start: number, end: number, detail?: unknown) {\n  try {\n    if (typeof performance?.measure === 'function') {\n      performance.measure(name, { start, end, detail });\n    }\n  } catch (error) {\n    console.debug(error);\n  }\n}\n","/**\n * Represents the properties of a cookie.\n */\nexport interface Cookie {\n  /**\n   * Include a leading \".\" to include subdomains.\n   *\n   * @example \".langehair.com\"\n   */\n  domain: string;\n\n  /**\n   * Indicates the maximum lifetime of the cookie as an HTTP-date timestamp. See Date for the\n   * required formatting.\n   *\n   * If unspecified, the cookie becomes a session cookie. A session finishes when the client shuts\n   * down, after which the session cookie is removed.\n   *\n   * Warning: Many web browsers have a session restore feature that will save all tabs and restore\n   * them the next time the browser is used. Session cookies will also be restored, as if the\n   * browser was never closed.\n   *\n   * When an Expires date is set, the deadline is relative to the client the cookie is being set on,\n   * not the server.\n   */\n  expires: Date;\n\n  /**\n   * A <cookie-name> can contain any US-ASCII characters except for: control characters (ASCII\n   * characters `0` up to `31` and ASCII character `127`) or separator characters (space, tab and\n   * the characters: `( ) < > @ , ; : \\ \" / [ ] ? = { })`.\n   */\n  name: string;\n\n  /**\n   * Path is generally \"/\" which is for all pages for a domain. Otherwise the cookie is specific to\n   * the given path (e.g. particular page).\n   */\n  path: string;\n\n  /**\n   * Controls whether or not a cookie is sent with cross-site requests, providing some protection\n   * against cross-site request forgery attacks (CSRF).\n   *\n   * * Strict Means that the browser sends the cookie only for same-site requests, that is, requests\n   *   originating from the same site that set the cookie. If a request originates from a different\n   *   domain or scheme (even with the same domain), no cookies with the SameSite=Strict attribute\n   *   are sent.\n   * * Lax Means that the cookie is not sent on cross-site requests, such as on requests to load\n   *   images or frames, but is sent when a user is navigating to the origin site from an external\n   *   site (for example, when following a link). This is the default behavior if the SameSite\n   *   attribute is not specified.\n   * * None means that the browser sends the cookie with both cross-site and same-site requests. The\n   *   Secure attribute must also be set when setting this value, like so SameSite=None; Secure. If\n   *   Secure is missing an error will be logged\n   *\n   * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie\n   */\n  same_site: 'Lax' | 'None' | 'Strict';\n\n  /**\n   * Indicates that the cookie is sent to the server only when a request is made with the https:\n   * scheme (except on localhost), and therefore, is more resistant to man-in-the-middle attacks.\n   */\n  secure: boolean;\n\n  /**\n   * A <cookie-value> can optionally be wrapped in double quotes and include any US-ASCII character\n   * excluding control characters (ASCII characters 0 up to 31 and ASCII character 127), Whitespace,\n   * double quotes, commas, semicolons, and backslashes.\n   */\n  value: string;\n}\n\n/**\n * Decodes a percent-encoded cookie name or value, falling back to the raw input when decoding is\n * not possible.\n *\n * Cookie storage is shared by every script on a domain, including third party libraries that write\n * raw, improperly-encoded values. A single cookie whose value contains a malformed percent-\n * sequence, such as a literal percent sign that is not followed by two hexadecimal digits, makes\n * decodeURIComponent throw a URIError. Because the whole cookie string is parsed at once, one such\n * cookie would otherwise poison every read on the page rather than just its own entry. Returning\n * the undecoded text keeps the remaining cookies readable, and a value that was never percent-\n * encoded is returned unchanged anyway.\n */\nfunction safeDecode(value: string) {\n  try {\n    return decodeURIComponent(value);\n  } catch (error) {\n    return value;\n  }\n}\n\n/**\n * Parses the value of document.cookie into an an array of cookie objects.\n *\n * **This decodes the cookie name and value. You should not decode the cookie name or value\n * yourself**.\n *\n * Cookies can be set with separate flags. When there are two cookies with the same name but with\n * different flags, the name will appear twice in document.cookie. Therefore, this returns an array\n * of Cookie objects instead of a single object where each name is a property.\n *\n * @throws {Error} if document is undefined, if document.cookie cannot be accessed for some reason\n * such as security restrictions on iframes or browser restrictions, or if document.cookie does not\n * produce a string\n */\nexport function parse() {\n  return document.cookie.split(';').map<Pick<Cookie, 'name' | 'value'>>(parts => {\n    const index = parts.indexOf('=');\n    // decodeURIComponent(undefined) produces strange results in some browsers, such as the string\n    // undefined, so we have to avoid that\n    const encodedValue = parts.slice(index + 1)?.trim();\n    return {\n      name: safeDecode(parts.slice(0, index).trim()),\n      value: typeof encodedValue === 'string' ? safeDecode(encodedValue) : undefined\n    };\n  });\n}\n\n/**\n * Retrieves the value of a particular cookie by name.\n *\n * If a cookie with the given name is not found, then undefined is returned.\n *\n * Internally this calls a private function to parse the cookie and that function accesses\n * document.cookie and for that reason this function can throw. This will almost never happen except\n * when attempting to access cookies cross-context, e.g. accessing parent window cookies from within\n * an iframe where the iframe has certain attributes. Some third party libraries do this naively and\n * without concern for the security constraints imposed by browsers. As a result, you should always\n * consider handling errors when calling this function.\n *\n * Because this can throw, **please implement proper error handling** when calling this function.\n *\n * **This decodes the cookie name and value. You should not decode the cookie name or value\n * yourself**.\n *\n * Cookie values are always strings. If you happen to be storing something like a JSON-like object\n * in the cookie value, then the raw JSON string is returned and is not parsed on your behalf. If\n * you are enclosing your value in double quotes, the leading and trailing double quote characters\n * are included in the returned value.\n *\n * **WARNING**: This is a naive read. When examining the list of cookies, this returns the first one\n * in the list. More than one cookie can have the same name when two or more cookies have the same\n * name but different flags. This is entirely dependent on the order of the names in\n * document.cookie, which is completely unknown and can change at any time and probably varies by\n * browser. Therefore, when there is more than one cookie with the same name, it is possible this\n * returns an unexpected cookie value.\n *\n * @throws {SecurityError}\n * @throws {Error}\n */\nexport function read(name: string) {\n  return readAll(name).shift();\n}\n\nexport function readAll(name: string) {\n  return parse().filter(cookie => cookie.name === name).map(cookie => cookie.value);\n}\n\n/**\n * Given a cookie, generate the string that can be supplied to document.cookie\n *\n * **This encodes the cookie name and cookie. Do not encode these yourself**.\n */\nexport function serialize(cookie: Partial<Cookie>) {\n  if (!cookie.name) {\n    throw new Error('Cookie name is required');\n  }\n\n  const parts: string[] = [];\n\n  parts.push(`${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value || '')}`);\n\n  if (typeof cookie.path === 'string') {\n    parts.push(`Path=${cookie.path}`);\n  }\n\n  if (typeof cookie.domain === 'string') {\n    parts.push(`Domain=${cookie.domain}`);\n  }\n\n  if (cookie.expires && typeof cookie.expires.getTime === 'function') {\n    parts.push(`Expires=${cookie.expires.toUTCString()}`);\n  }\n\n  if (typeof cookie.same_site === 'string') {\n    parts.push(`SameSite=${cookie.same_site}`);\n  }\n\n  if (cookie.secure) {\n    parts.push('Secure');\n  }\n\n  // The delimiter must include a single space after semicolon\n\n  return parts.join('; ');\n}\n\n/**\n * This function can throw because setting document.cookie sometimes throws an error.\n *\n * This function can throw on invalid input, such as when not specifying a required property such as\n * cookie name.\n *\n * **This encodes the cookie name and cookie. Do not encode these yourself**.\n */\nexport function write(cookie: Partial<Cookie>) {\n  document.cookie = serialize(cookie);\n}\n\n/**\n * Deletes a cookie.\n *\n * Of the cookie properties, only the name is required. However, some browsers are extremely strict\n * about how a cookie is deleted. To delete a cookie the exact same other properties must also be\n * provided, other than the cookie's value and expiration date. For example, if the cookie to be\n * deleted is secure, then you must specify the secure property to delete the cookie.\n *\n * If the properties do not match, this completes without error and the cookie that was to be\n * deleted still remains.\n *\n * Deleting a cookie is done by setting its value to an empty string and then assigning the full\n * cookie value to document.cookie.\n *\n * This function may throw an error because deleting a cookie is done by assigning a value to\n * document.cookie which can sometimes throw.\n *\n * The expires property is ignored. This sets expiration date to 1970 to force cookie to become\n * expired.\n *\n * Insecure cookies cannot be removed. These are cookies belonging to the http protocol.\n */\nexport function remove(cookie: Partial<Cookie>) {\n  write({ ...cookie, value: '', expires: new Date(0) });\n}\n","import { read, write } from '@integrabeauty/cookie';\n\n// Everything about the id GrowthBook buckets a visitor on, including the cookie we keep our own in.\n// Nothing else needs an id, so this is not a general purpose id utility and there is no reason to\n// grow it into one.\n\n/**\n * Reads a cookie, treating an unreachable `document.cookie` the same as an absent value.\n *\n * Cookie access throws cross-context, such as from inside an iframe, and there is nothing useful to\n * do about that here beyond moving on to the next place an id might come from.\n */\nfunction readCookie(name: string) {\n  try {\n    return read(name);\n  } catch (error) {\n    console.debug('Failed to read cookie', name, error);\n  }\n}\n\n/**\n * Produces a random hex string to use as an id.\n *\n * Web crypto is preferred but not required, so reaching it is guarded. It is absent outside a\n * secure context and in older browsers, and a hardened or proxied environment can throw from it.\n * The guard covers both, since reaching through a missing global throws the same way a refusal\n * does.\n *\n * Nothing here is a secret and the id carries no meaning. It only has to differ from other\n * visitors' ids, so weaker randomness is an acceptable fallback and keeps a visitor in the\n * experiment rather than dropping them over the quality of the bytes.\n */\nfunction generateId() {\n  // Typed arrays date to the IE10 and iOS 4 era, so this needs no guard of its own. Every browser\n  // this theme supports is far newer than that, and the crypto call below is the only thing here\n  // whose availability is in question.\n\n  const bytes = new Uint8Array(16);\n\n  try {\n    crypto.getRandomValues(bytes);\n  } catch (error) {\n    console.debug('Web crypto is unavailable for minting an anonymous id', error);\n\n    for (let index = 0; index < bytes.length; index++) {\n      bytes[index] = Math.floor(Math.random() * 256);\n    }\n  }\n\n  let value = '';\n  for (const byte of bytes) {\n    value += byte.toString(16).padStart(2, '0');\n  }\n\n  return value;\n}\n\n/**\n * Mints a random id of our own and persists it in a cookie, handing it back only once the cookie is\n * confirmed to have stuck.\n *\n * Apple ITP caps anything written from script at roughly seven days whatever the expiry says, so\n * the year expresses intent rather than a real lifetime, the same way the sticky bucket store\n * alongside this file treats its own expiry.\n *\n * An id is only handed back once it has been seen to survive a round trip. One that failed to\n * persist would land the visitor in a different variation on every page load, and the exposure each\n * of those records turns one person into a stream of phantom visitors spread across the variations,\n * which corrupts an experiment worse than leaving them out of it.\n */\nfunction mint() {\n  const value = generateId();\n\n  const expires = new Date();\n  expires.setFullYear(expires.getFullYear() + 1);\n\n  try {\n    write({\n      expires,\n      name: 'ib_gb_id',\n      path: '/',\n      same_site: 'Lax',\n      secure: true,\n      value\n    });\n  } catch (error) {\n    console.debug('Failed to write a minted GrowthBook anonymous id', error);\n    return;\n  }\n\n  // Reading the id back rather than returning the value that was just written. A browser with\n  // cookies blocked makes the write a silent no-op instead of a throw, so getting this far says\n  // nothing about whether anything was stored. The read back is also the more useful question,\n  // since what matters is what a later page load will find rather than what this one meant to\n  // store.\n\n  return readCookie('ib_gb_id');\n}\n\n/**\n * Resolves the id GrowthBook buckets the visitor on, reusing the minted id from an earlier page\n * load when there is one so the same id comes back on every page load and an assignment holds.\n */\nexport function resolve() {\n  const mintedId = readCookie('ib_gb_id');\n  if (mintedId) {\n    return mintedId;\n  }\n\n  return mint();\n}\n","import { toString } from \"./util.mjs\";\nimport { getStickyBucketAttributeKey } from \"./core.mjs\";\n/**\n * Responsible for reading and writing documents which describe sticky bucket assignments.\n */\nexport class StickyBucketService {\n  constructor(opts) {\n    opts = opts || {};\n    this.prefix = opts.prefix || \"\";\n  }\n  /**\n   * The SDK calls getAllAssignments to populate sticky buckets. This in turn will\n   * typically loop through individual getAssignments calls. However, some StickyBucketService\n   * instances (i.e. Redis) will instead perform a multi-query inside getAllAssignments instead.\n   */\n  async getAllAssignments(attributes) {\n    const docs = {};\n    (await Promise.all(Object.entries(attributes).map(([attributeName, attributeValue]) => this.getAssignments(attributeName, attributeValue)))).forEach(doc => {\n      if (doc) {\n        const key = getStickyBucketAttributeKey(doc.attributeName, doc.attributeValue);\n        docs[key] = doc;\n      }\n    });\n    return docs;\n  }\n  getKey(attributeName, attributeValue) {\n    return `${this.prefix}${attributeName}||${attributeValue}`;\n  }\n}\nexport class StickyBucketServiceSync extends StickyBucketService {\n  async getAssignments(attributeName, attributeValue) {\n    return this.getAssignmentsSync(attributeName, attributeValue);\n  }\n  async saveAssignments(doc) {\n    this.saveAssignmentsSync(doc);\n  }\n  getAllAssignmentsSync(attributes) {\n    const docs = {};\n    Object.entries(attributes).map(([attributeName, attributeValue]) => this.getAssignmentsSync(attributeName, attributeValue)).forEach(doc => {\n      if (doc) {\n        const key = getStickyBucketAttributeKey(doc.attributeName, doc.attributeValue);\n        docs[key] = doc;\n      }\n    });\n    return docs;\n  }\n}\nexport class LocalStorageStickyBucketService extends StickyBucketService {\n  constructor(opts) {\n    opts = opts || {};\n    super();\n    this.prefix = opts.prefix || \"gbStickyBuckets__\";\n    try {\n      this.localStorage = opts.localStorage || globalThis.localStorage;\n    } catch (e) {\n      // Ignore localStorage errors\n    }\n  }\n  async getAssignments(attributeName, attributeValue) {\n    const key = this.getKey(attributeName, attributeValue);\n    let doc = null;\n    if (!this.localStorage) return doc;\n    try {\n      const raw = (await this.localStorage.getItem(key)) || \"{}\";\n      const data = JSON.parse(raw);\n      if (data.attributeName && data.attributeValue && data.assignments) {\n        doc = data;\n      }\n    } catch (e) {\n      // Ignore localStorage errors\n    }\n    return doc;\n  }\n  async saveAssignments(doc) {\n    const key = this.getKey(doc.attributeName, doc.attributeValue);\n    if (!this.localStorage) return;\n    try {\n      await this.localStorage.setItem(key, JSON.stringify(doc));\n    } catch (e) {\n      // Ignore localStorage errors\n    }\n  }\n}\nexport class ExpressCookieStickyBucketService extends StickyBucketServiceSync {\n  /**\n   * Intended to be used with cookieParser() middleware from npm: 'cookie-parser'.\n   * Assumes:\n   *  - reading a cookie is automatically decoded via decodeURIComponent() or similar\n   *  - writing a cookie name & value must be manually encoded via encodeURIComponent() or similar\n   *  - all cookie bodies are JSON encoded strings and are manually encoded/decoded\n   */\n\n  constructor({\n    prefix = \"gbStickyBuckets__\",\n    req,\n    res,\n    cookieAttributes = {\n      maxAge: 180 * 24 * 3600 * 1000\n    } // 180 days\n  }) {\n    super();\n    this.prefix = prefix;\n    this.req = req;\n    this.res = res;\n    this.cookieAttributes = cookieAttributes;\n  }\n  getAssignmentsSync(attributeName, attributeValue) {\n    const key = this.getKey(attributeName, attributeValue);\n    let doc = null;\n    if (!this.req) return doc;\n    try {\n      const raw = this.req.cookies[key] || \"{}\";\n      const data = JSON.parse(raw);\n      if (data.attributeName && data.attributeValue && data.assignments) {\n        doc = data;\n      }\n    } catch (e) {\n      // Ignore cookie errors\n    }\n    return doc;\n  }\n  saveAssignmentsSync(doc) {\n    const key = this.getKey(doc.attributeName, doc.attributeValue);\n    if (!this.res) return;\n    const str = JSON.stringify(doc);\n    this.res.cookie(encodeURIComponent(key), encodeURIComponent(str), this.cookieAttributes);\n  }\n}\nexport class BrowserCookieStickyBucketService extends StickyBucketServiceSync {\n  /**\n   * Intended to be used with npm: 'js-cookie'.\n   * Assumes:\n   *  - reading a cookie is automatically decoded via decodeURIComponent() or similar\n   *  - writing a cookie name & value is automatically encoded via encodeURIComponent() or similar\n   *  - all cookie bodies are JSON encoded strings and are manually encoded/decoded\n   */\n\n  constructor({\n    prefix = \"gbStickyBuckets__\",\n    jsCookie,\n    cookieAttributes = {\n      expires: 180\n    } // 180 days\n  }) {\n    super();\n    this.prefix = prefix;\n    this.jsCookie = jsCookie;\n    this.cookieAttributes = cookieAttributes;\n  }\n  getAssignmentsSync(attributeName, attributeValue) {\n    const key = this.getKey(attributeName, attributeValue);\n    let doc = null;\n    if (!this.jsCookie) return doc;\n    try {\n      const raw = this.jsCookie.get(key);\n      const data = JSON.parse(raw || \"{}\");\n      if (data.attributeName && data.attributeValue && data.assignments) {\n        doc = data;\n      }\n    } catch (e) {\n      // Ignore cookie errors\n    }\n    return doc;\n  }\n  async saveAssignmentsSync(doc) {\n    const key = this.getKey(doc.attributeName, doc.attributeValue);\n    if (!this.jsCookie) return;\n    const str = JSON.stringify(doc);\n    const {\n      domain,\n      ...hostOnlyAttributes\n    } = this.cookieAttributes;\n    if (!domain) {\n      this.jsCookie.set(key, str, this.cookieAttributes);\n      return;\n    }\n    // Remove any legacy host-only cookie first - it would shadow the\n    // domain-scoped one on reads\n    this.jsCookie.remove(key, hostOnlyAttributes);\n    this.jsCookie.set(key, str, this.cookieAttributes);\n    // Browsers silently reject a cookie whose domain doesn't cover this host\n    // (e.g. a typo) - fall back to host-only so assignments still persist\n    if (this.jsCookie.get(key) !== str) {\n      this.jsCookie.set(key, str, hostOnlyAttributes);\n    }\n  }\n}\nexport class RedisStickyBucketService extends StickyBucketService {\n  /** Intended to be used with npm: 'ioredis'. **/\n\n  constructor({\n    redis\n  }) {\n    super();\n    this.redis = redis;\n  }\n  async getAllAssignments(attributes) {\n    const docs = {};\n    const keys = Object.entries(attributes).map(([attributeName, attributeValue]) => getStickyBucketAttributeKey(attributeName, attributeValue));\n    if (!this.redis) return docs;\n    await this.redis.mget(...keys).then(values => {\n      values.forEach(raw => {\n        try {\n          const data = JSON.parse(raw || \"{}\");\n          if (data.attributeName && \"attributeValue\" in data && data.assignments) {\n            const key = getStickyBucketAttributeKey(data.attributeName, toString(data.attributeValue));\n            docs[key] = data;\n          }\n        } catch (e) {\n          // ignore redis doc parse errors\n        }\n      });\n    });\n    return docs;\n  }\n  async getAssignments(_attributeName, _attributeValue) {\n    // not implemented\n    return null;\n  }\n  async saveAssignments(doc) {\n    const key = this.getKey(doc.attributeName, doc.attributeValue);\n    if (!this.redis) return;\n    await this.redis.set(key, JSON.stringify(doc));\n  }\n}\n//# sourceMappingURL=sticky-bucket-service.mjs.map","import { StickyBucketServiceSync } from '@growthbook/growthbook';\nimport type { StickyAssignmentsDocument } from '@growthbook/growthbook';\nimport { read, write } from '@integrabeauty/cookie';\n\n// A sticky bucket store backed by cookies rather than localStorage. GrowthBook ships a browser\n// cookie implementation of its own, but it is written against the js-cookie package, and adapting\n// our cookie library to that interface takes more code than the two storage methods it would save.\n// So this subclasses their sync base directly, which is the third option their docs describe, and\n// inherits the key building and the loop over attributes from it.\n\n// This exists because most of our traffic is in iOS in-app browsers where localStorage does not\n// work, so their LocalStorageStickyBucketService silently persists nothing and every page load\n// assigns the visitor a fresh bucket. Cookies survive there.\n\n// The prefix is deliberately ours rather than GrowthBook's. Our cookie library and js-cookie do not\n// encode a cookie name the same way, and their key format puts a pair of pipes in the name, so\n// sharing a prefix would leave two cookies that look like the same key but are not. Keeping the\n// names distinct means adopting their implementation later is a clean switch instead of a silent\n// half-read.\n\n/**\n * Whether a value parsed out of a cookie body is a usable sticky assignments document. Cookie\n * contents are attacker-editable and can also be left over from an older shape, so nothing about\n * what comes back can be assumed.\n */\nfunction isAssignmentsDocument(value: any): value is StickyAssignmentsDocument {\n  if (typeof value !== 'object') {\n    return false;\n  }\n\n  if (!value) {\n    return false;\n  }\n\n  if (typeof value.attributeName !== 'string') {\n    return false;\n  }\n\n  if (typeof value.attributeValue !== 'string') {\n    return false;\n  }\n\n  if (typeof value.assignments !== 'object') {\n    return false;\n  }\n\n  if (!value.assignments) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Persists GrowthBook's sticky bucket assignments in cookies, one cookie per bucketing attribute.\n *\n * Both methods are effectively synchronous. The sync base class wraps them into the promises the\n * SDK's async paths want, and keeps the synchronous variants available for its initSync entry\n * point.\n *\n * @see https://docs.growthbook.io/app/sticky-bucketing What sticky bucketing is for\n * @see https://docs.growthbook.io/lib/js#sticky-bucketing The service interface being implemented\n */\nexport class CookieStickyBucketService extends StickyBucketServiceSync {\n  constructor() {\n    super({ prefix: 'ib_gb_sb_' });\n  }\n\n  getAssignmentsSync(attributeName: string, attributeValue: string) {\n    // Despite the name, the inherited getKey only builds a string. Here that string is the cookie\n    // name, where in the localStorage sibling it is a storage key.\n\n    const cookieName = this.getKey(attributeName, attributeValue);\n\n    let raw;\n\n    // Reading a cookie throws when document.cookie is unreachable, such as cross-context in an\n    // iframe. Treat that as having no assignment rather than an error, so bucketing falls back to\n    // hashing the visitor's id instead of failing the whole feature lookup.\n\n    try {\n      raw = read(cookieName);\n    } catch (error) {\n      console.debug(error);\n      return null;\n    }\n\n    if (!raw) {\n      return null;\n    }\n\n    let parsed;\n\n    try {\n      parsed = JSON.parse(raw);\n    } catch (error) {\n      console.debug(error);\n      return null;\n    }\n\n    if (!isAssignmentsDocument(parsed)) {\n      return null;\n    }\n\n    return parsed;\n  }\n\n  saveAssignmentsSync(doc: StickyAssignmentsDocument) {\n    const cookieName = this.getKey(doc.attributeName, doc.attributeValue);\n    const value = JSON.stringify(doc);\n\n    // 180 days, matching the expiry GrowthBook's own cookie implementation defaults to. Apple ITP\n    // caps a cookie set from script at 7 days regardless, so the 180 is a match for their default\n    // rather than a real lifetime.\n\n    const expires = new Date();\n    expires.setDate(expires.getDate() + 180);\n\n    try {\n      write({\n        expires,\n        name: cookieName,\n        path: '/',\n        same_site: 'Lax',\n        secure: true,\n        value\n      });\n    } catch (error) {\n      console.debug(error);\n    }\n  }\n}\n","import { type Experiment, type Result, GrowthBook } from '@growthbook/growthbook';\nimport { mark, measure, now } from '../../lib/perf.js';\nimport { resolve as resolveAnonymousId } from './id.js';\nimport { CookieStickyBucketService } from './sticky-bucket-service.js';\n\n// GrowthBook pixel — entry point script that initializes the GrowthBook SDK once at page load and\n// stores the result on `growthbook_runtime` for consumption by individual sections.\n\n// Sections do not read the client directly. They go through the feature accessor lib, which waits\n// on the pair this module produces once the load reaches a terminal state, the load state on the\n// runtime global and a broadcast event. The pair is what makes load order stop mattering. A\n// consumer arriving after the broadcast reads the state and proceeds, and one arriving before it\n// registers for the event. That is load bearing rather than defensive, because the snippet loads\n// this script async, so it really can execute after a section has already asked for a feature\n// value.\n\n// Every way this can end is a terminal state and every one of them broadcasts, the failures\n// included. A consumer therefore learns that no client is coming rather than sitting out its\n// timeout waiting for a signal that was already decided. The timeout stays as a floor anyway, for\n// the case where this script never runs at all, and because a slow GrowthBook load must never block\n// rendering.\n\n// The client itself still hangs off `growthbook_runtime.client_loader`, and reading it is only safe\n// once the load state says a client is ready.\n\n// On preview, the loader is deliberately held open for a few seconds after init to let the\n// GrowthBook DevTools browser extension apply forced variant overrides before any section commits\n// to a variant, and the signal waits for that too. On production the loader resolves as soon as\n// init completes — no wait.\n\n// The boot is timed onto the User Timing timeline, so how long it takes and where it falls in the\n// page can be read off a real load in the devtools performance panel rather than reasoned about.\n// Where it falls is the interesting half, since this script loads async from the layout head and so\n// has no fixed position relative to the sections consuming it. The timings are readable\n// programmatically too, so a lab run can pull them without a devtools session.\n\n// One of them measures the page rather than the boot. A slow boot here has so far turned out to be\n// the page being busy rather than anything GrowthBook did, so the timings are hard to read without\n// something saying how contended the main thread was at the time.\n\n/**\n * This function is called automatically by the GrowthBook SDK when the assigned variation for an\n * experiment is accessed. GrowthBook only calls this function when the experiment is active, so\n * that we do not report on experiments that are finished or not yet started.\n *\n * Worth knowing how it gets called, because the mechanism surprises people. Asking the SDK for a\n * feature value is not a passive read. The SDK walks the feature's rules, and if it reaches an\n * experiment rule it buckets the visitor there and then, and calls this on the way back out. So the\n * read is what records the exposure, and nothing anywhere reports an exposure on its own. Reading a\n * feature the visitor cannot see therefore records an exposure that never happened, which is why\n * the sections gate their reads on the thing being on the page.\n *\n * The call is synchronous, so by the time the SDK returns a value to its caller the event below has\n * already been dispatched.\n *\n * This function is written to carefully use the same signature as GrowthBook's TrackingCallback\n * type. Keep the signature in sync with what GrowthBook uses.\n *\n * This previously checked for and prevented duplicate events. However, the check was subtly\n * incorrect and it also was redundant, as the GrowthBook SDK has builtin idempotency. The SDK has\n * its own Set that tracks what has been reported per visitor+experiment+variation. This previously\n * only deduplicated on visitor+experiment.\n */\nfunction trackingCallback(experiment: Experiment<any>, result: Result<any>) {\n  // The feature id is null for an experiment that is not attached to a feature (e.g. redirect).\n\n  // The hash value is the value that GrowthBook actually used for bucketing. This is usually the\n  // value GrowthBook was seeded with but it can differ in the case of fallback. Using the hash\n  // value is more accurate than using the seed value because they can differ.\n\n  type ExperimentExposedEvent = WindowEventMap['experiment-exposed'];\n  const event = new CustomEvent<ExperimentExposedEvent['detail']>('experiment-exposed', {\n    detail: {\n      experiment_id: experiment.key,\n      feature_id: result.featureId ?? '',\n      param_name: 'variation',\n      param_value: result.value,\n      stable_id: result.hashValue\n    }\n  });\n  dispatchEvent(event);\n}\n\n/**\n * Creates and initializes a GrowthBook client using the SDK key from growthbook_runtime. Throws if\n * initialization fails so the caller can handle it gracefully.\n *\n * The returned promise is the one the whole runtime hangs off, so everything that has to happen\n * before a consumer may read a variant happens before it resolves. On preview that normally\n * includes the deliberate hold for the DevTools extension, which is why the promise can stay\n * pending for several seconds there. On production it resolves as soon as init completes, and so\n * does preview when the hold has been turned off for profiling.\n *\n * Enabling dev mode allows the DevTools extension to discover and connect to the SDK\n *\n * @see sticky-bucketing.md for details about its use here\n */\nasync function initGrowthBookClient() {\n  const viewMode = Shopify.previewMode ? 'preview' : 'production';\n\n  const growthbook = new GrowthBook({\n    apiHost: growthbook_runtime.api_host,\n    attributes: {\n      id: growthbook_runtime.anonymous_id\n    },\n    clientKey: growthbook_runtime.key,\n    debug: false,\n    enableDevMode: viewMode === 'preview',\n    trackingCallback,\n    stickyBucketService: new CookieStickyBucketService()\n  });\n\n  // We are using GrowthBook for experiments only and we don't want to keep the connection open for\n  // real time config updates.\n\n  // this is the payload fetch and everything the SDK does with it, and it is as close as we get to\n  // timing the request on its own, since the SDK owns the request and we never see it\n\n  // the source is what makes the number readable. the SDK caches the payload for a few hours, so a\n  // fast init means a cache read rather than a fast network, and the two are not comparable. taking\n  // the measurement ahead of the checks below also keeps the slow failures, which are the ones most\n  // worth having a number for\n\n  const initStartMillis = now();\n  const result = await growthbook.init({ streaming: false });\n  measure('growthbook-init', initStartMillis, now(), {\n    source: result?.source,\n    view_mode: viewMode\n  });\n\n  if (!result) {\n    throw new Error('Failed to initialize GrowthBook');\n  }\n\n  if (!result.success) {\n    throw result.error;\n  }\n\n  // a hold of zero is the profiling switch the snippet seeds off the url. skipping the wait\n  // outright rather than running it with a zero length timer is what makes the boot timing\n  // production shaped, because the wait resolves on a timer and a busy page can leave even a zero\n  // length one sitting for hundreds of milliseconds, where production settles straight off this\n  // promise\n\n  if (viewMode === 'preview' && growthbook_runtime.preview_hold_ms > 0) {\n    return waitForDevToolsOverrides(growthbook);\n  }\n\n  return growthbook;\n}\n\n/**\n * Preview-only: wraps an initialized SDK instance in a promise that deliberately stays pending\n * until the GrowthBook DevTools browser extension has had time to apply forced variant overrides.\n *\n * **Why this exists:** The DevTools extension is a content script — it injects into the page only\n * after the document loads, so it always arrives after the SDK has already initialized. Sections\n * that consume `growthbook_runtime.client_loader` are one-shot: they `await` the loader exactly\n * once and immediately commit to whatever variant they get. Without this wait, the extension's\n * overrides arrive too late and are silently ignored.\n *\n * **What triggers the renderer:** the SDK calls the registered renderer whenever\n * `setForcedFeatures`, `setForcedVariations`, `setAttributeOverrides`, or `setPayload` is called —\n * exactly the methods the DevTools extension invokes to push overrides onto the page.\n */\nfunction waitForDevToolsOverrides(growthbook: GrowthBook) {\n  return new Promise<GrowthBook>(resolve => {\n    let renderCount = 0;\n    let debounceTimer: ReturnType<typeof setTimeout>;\n    const startedAt = new Date();\n\n    const settle = () => {\n      // ceiling and debounce are mutually cancelling — whichever fires first clears the other\n      clearTimeout(ceilingTimer);\n      clearTimeout(debounceTimer);\n      console.log('[GrowthBook] preview override wait settled after ' +\n        `${new Date().getTime() - startedAt.getTime()}ms with ${renderCount} renders`);\n\n      // swap to a post-load renderer so mid-session panel edits prompt a reload rather than\n      // silently updating SDK state that one-shot consumers will never re-read\n      growthbook.setRenderer(() => {\n        console.debug('[GrowthBook] Variant overrides changed — refresh the page to apply them. ' +\n          `${ new Date().getTime() - startedAt.getTime()}ms since initial load`);\n      });\n\n      resolve(growthbook);\n    };\n\n    // how long to give the extension to connect and push its overrides. the feature accessor adds\n    // the same figure to every consumer's timeout on preview, which is why it is seeded once rather\n    // than written down in both places.\n    const ceilingTimer = setTimeout(settle, growthbook_runtime.preview_hold_ms);\n\n    // the extension may fire several override methods in quick succession, so wait for quiet rather\n    // than settling on the first call and missing the rest\n    const debounceMillis = 200;\n    growthbook.setRenderer(() => {\n      renderCount++;\n      clearTimeout(debounceTimer);\n      debounceTimer = setTimeout(settle, debounceMillis);\n    });\n  });\n}\n\n/**\n * Closes the span measuring how long a zero length timer took to fire.\n *\n * This exists as its own function so the end of the span is read when the timer fires rather than\n * when it was scheduled. Handing `measure` straight to `setTimeout` would stamp both ends at\n * scheduling time and always report nothing.\n */\nfunction measureScheduleDelay(startMillis: number) {\n  measure('growthbook-schedule-delay', startMillis, now());\n}\n\n/**\n * Records how the load ended and tells anyone already waiting.\n *\n * The state is written before the broadcast, so a consumer reacting to the event and one reading\n * the state afterwards cannot disagree about what happened.\n *\n * The span is closed first because the broadcast has to come after it. Dispatching runs every\n * waiting consumer synchronously, so measuring afterwards would bill their work to the boot.\n *\n * Every terminal path comes through here, the early failures included, so the span covers the whole\n * boot however it ended and the state it ended in rides along as the detail. The caller passes in\n * where the boot began rather than this reading it off module state, since the only thing that has\n * to know is the function that started it.\n *\n * The view mode rides along because preview is where this span is least comparable. The deliberate\n * hold for the DevTools extension falls inside it there, which is seconds rather than the\n * milliseconds a live visit takes, and nothing else on the span says which one is being read.\n *\n * The state type comes off the global rather than from an import, since the union is an\n * implementation detail of that declaration.\n */\nfunction settle(state: typeof growthbook_runtime.load_state, startMillis: number) {\n  measure('growthbook-settle', startMillis, now(), {\n    load_state: state,\n    view_mode: Shopify.previewMode ? 'preview' : 'production'\n  });\n  growthbook_runtime.load_state = state;\n  dispatchEvent(new Event('growthbook-load-settled'));\n}\n\n/**\n * Initialize the global GrowthBook client and keep it in a global variable to be reused by sections\n */\nfunction loadGrowthBook() {\n  if (!window.growthbook_runtime) {\n    return;\n  }\n\n  // this is where the boot span starts, and it doubles as the mark showing where the async bundle\n  // landed relative to the rest of the page\n\n  const startMillis = now();\n  mark('growthbook-boot-start');\n\n  // GrowthBook decides which variation a visitor gets by hashing this id together with the\n  // experiment key. That is the whole reason it is required. The same id on every page load means\n  // the same variation on every page load, and an id that changed between loads would reshuffle the\n  // visitor into a different variation each time, which would corrupt the experiment.\n\n  // Without an id there is nothing to hash, and GrowthBook leaves the visitor out of every\n  // experiment rather than assigning one at random. So there is no answer left to wait for and\n  // returning here gives up nothing.\n\n  // Reaching the failure below means no cookie was readable and a fresh one could not be made to\n  // stick, which is a locked down or tampered browser rather than anything expected.\n\n  const anonymousId = resolveAnonymousId();\n\n  if (!anonymousId) {\n    console.log('GrowthBook anonymous id is unavailable');\n    settle('failure_anonymous_id_missing', startMillis);\n    return;\n  }\n\n  growthbook_runtime.anonymous_id = anonymousId;\n\n  // store the promise globally to avoid multiple costly inits, we don't need to await it here\n  growthbook_runtime.client_loader = initGrowthBookClient();\n\n  // a zero length timer firing late means the main thread is saturated, and that is what says\n  // whether a slow init was growthbook's own work or just the page around it. sampling from here\n  // rather than from boot start is deliberate, since this is the moment init is competing for, and\n  // main thread pressure moves a lot across a page load\n\n  setTimeout(measureScheduleDelay, 0, now());\n\n  growthbook_runtime.client_loader.then(() => {\n    settle('ready', startMillis);\n  }).catch(error => {\n    console.warn(error);\n    settle('failure_init', startMillis);\n  });\n}\n\nloadGrowthBook();\n"],"names":["validAttributeName","nullController","revert","dom_mutator_esm_elements","Map","mutations","Set","getElementRecord","element","record","get","attributes","set","createElementPropertyRecord","el","attr","getCurrentValue","setValue","mutationRunner","currentValue","isDirty","originalValue","virtualValue","_positionTimeout","observer","MutationObserver","setTimeout","parentNode","insertBeforeNode","observe","childList","subtree","characterData","attributeFilter","getObserverInit","queueIfNeeded","val","currentVal","runDOMUpdates","htmlMutationRunner","forEach","m","mutate","html","transformContainer","document","createElement","innerHTML","getTransformedHTML","classMutationRunner","split","filter","Boolean","Array","from","join","attrMutationRunner","positionMutationRunner","newNodes","_ref","parentSelector","insertBeforeSelector","querySelector","_loadDOMNodes","getHTMLValue","setHTMLValue","value","getElementHTMLRecord","elementRecord","getElementPosition","parentElement","nextElementSibling","setElementPosition","contains","insertBefore","getElementPositionRecord","position","setClassValue","className","removeAttribute","getClassValue","getElementClassRecord","classes","getElementAttributeRecord","attrName","_el$getAttribute","getAttribute","setAttribute","setAttrValue","setPropertyValue","length","_element$html","_element$html$observe","disconnect","_element$classes","_element$classes$obse","_element$position","_element$position$obs","_element$attributes","_element$attributes$a","_element$attributes$a2","deleteElementPropertyRecord","Object","keys","refreshElementsSet","mutation","kind","elements","size","existingElements","querySelectorAll","selector","has","add","attribute","push","startMutating","revertMutation","index","indexOf","splice","stopMutating","clear","refreshAllElementSets","newMutation","test","classnames","mutatedClassnames","c","documentElement","declarative","_ref2","action","polyfills","fetch","globalThis","bind","undefined","SubtleCrypto","crypto","subtle","EventSource","hashFnv32a","str","hval","l","i","charCodeAt","hash","seed","version","getEqualWeights","n","fill","inRange","range","getUrlRegExp","regexString","escaped","replace","RegExp","e","console","error","isURLTargeted","url","targets","hasIncludeRules","isIncluded","match","_evalURLTarget","type","pattern","include","_evalSimpleUrlTarget","actual","expected","URL","comps","host","pathname","searchParams","v","k","some","data","isPath","_evalSimpleUrlPart","parsed","regex","href","substring","origin","base64ToBuf","b","Uint8Array","atob","async","decrypt","encryptedString","decryptionKey","Error","key","importKey","name","iv","cipherText","plainTextBuffer","TextDecoder","decode","util_toString","input","JSON","stringify","paddedVersionString","parts","map","padStart","isObj","x","getAutoExperimentChangeType","exp","urlPatterns","variations","variation","domMutations","promiseTimeout","promise","timeout","Promise","resolve","timer","resolved","finish","clearTimeout","then","catch","cacheSettings","staleTTL","maxAge","cacheKey","backgroundSync","maxEntries","disableIdleStreams","idleStreamInterval","disableCache","feature_repository_polyfills","helpers","fetchFeaturesCall","clientKey","headers","fetchRemoteEvalCall","payload","options","method","body","eventSourceCall","startIdleListener","idleTimeout","window","onVisibilityChange","visibilityState","streams","channel","state","enableChannel","onHidden","addEventListener","removeEventListener","stopIdleListener","localStorage","subscribedInstances","cacheInitialized","cache","activeFetches","pollers","supportsSSE","streamingWarnings","refreshFeatures","instance","skipCache","allowStale","getKey","getCacheKey","now","Date","minStaleAt","getTime","getItem","parse","isArray","staleAt","cleanupCache","cleanupFn","initializeCache","existing","sse","fetchFeatures","startAutoRefresh","success","source","fetchFeaturesWithCache","disableChannel","MAX_BACKOFF_MS","backoffDelay","base","factor","attempt","Math","min","pow","random","warnMisconfiguration","message","warn","warnStreamingUnavailable","reason","updatePersistentCache","setItem","entries","apiHost","getApiInfo","baseKey","isRemoteEval","getAttributes","cacheKeyAttributes","getCacheKeyAttributes","ca","fv","getForcedVariations","getUrl","entriesWithTimestamps","sort","a","entriesToRemoveCount","max","delete","onNewFeatureData","dateUpdated","instances","setPayload","getPayload","refreshInstance","apiRequestHeaders","getApiHosts","getClientKey","remoteEval","forcedVariations","forcedFeatures","getForcedFeatures","res","ok","status","json","forceSSE","streamingHost","streamingHostRequestHeaders","src","cb","event","errors","onSSEError","readyState","delay","includes","onopen","onerror","close","poller","destroyPoller","closeError","destroyChannel","startPolling","interval","Number","isFinite","scheduleNextPoll","subs","values","next","unref","clearAutoRefresh","startBackgroundSync","streaming","pollingInterval","subscribe","_regexCache","evalCondition","obj","condition","savedGroups","visited","evalOr","evalAnd","evalSavedGroup","evalConditionValue","getPath","reference","id","attributeKey","entry","isIn","path","current","getRegex","insensitive","String","toLowerCase","isOperatorObject","op","evalOperatorCondition","caseFold","getSavedGroupArrayValues","isInAll","passed","j","operator","check","elemMatch","t","getType","conditions","safeCall","fn","onExperimentViewed","ctx","experiment","result","user","trackedExperiments","getExperimentDedupeKey","enableDevMode","devLogs","timestamp","toString","logType","calls","global","trackingCallback","getTrackingUserContext","eventLogger","experimentId","variationId","hashAttribute","hashValue","experimentViewedSubs","evalFeature","stack","evaluatedFeatures","getFeatureResult","forcedValues","ret","forcedFeatureValues","getForcedFeatureValues","features","feature","rules","rule","parentConditions","parentCondition","parentResult","gate","filters","isFilteredOut","conditionPasses","isIncludedInRollout","saveStickyBucketAssignmentDoc","disableStickyBucketing","fallbackAttribute","coverage","hashVersion","tracks","saveDeferredTrack","force","ruleVariations","contextualVariations","weights","bucketVersion","minBucketVersion","namespace","meta","ranges","phase","contextualBanditRef","buildContextualBanditExperiment","runExperiment","contextualBandit","hashUsed","inExperiment","onExperimentEval","passthrough","defaultValue","featureId","numVariations","getExperimentResult","enabled","o","overrides","assign","mergeOverrides","variationWeights","qsOverride","search","kv","parseInt","getQueryStringOverride","active","getHashAttribute","assigned","foundStickyBucket","stickyBucketVersionIsBlocked","versionIsBlocked","expKey","expBucketVersion","expHashAttribute","expFallbackAttribute","expMinBucketVersion","expMeta","getStickyBucketExperimentKey","assignments","stickyBucketAssignmentDocs","hashKey","getStickyBucketAttributeKey","fallbackValue","fallbackKey","getStickyBucketAssignments","variationKey","findIndex","getStickyBucketVariation","inNamespace","groups","expGroups","hasGroupOverlap","urlRegex","pathOnly","urlIsValid","equal","totalWeight","reduce","w","sum","cumulative","start","getBucketRanges","chooseVariation","qaMode","changed","attrKey","doc","attributeName","attributeValue","existingAssignments","newAssignments","generateStickyBucketAssignmentDoc","trackingCalls","trackingCall","all","changeId","recordChangeId","ruleId","on","off","experimentResult","trackedFeatureUsage","stringifiedValue","featureKey","featureUsageSubs","onFeatureUsage","attributeOverrides","CONTEXTUAL_BANDIT_FALLBACK_LEAF_ID","cbDefinition","contextualBandits","leaf","contexts","context","leafId","getContextualBanditLeaf","banditVersion","r","variationIndex","bucket","stickyBucketUsed","fallback","experimentKey","experimentBucketVersion","getStickyBucketAttributes","stickyBucketIdentifierAttributes","experiments","deriveStickyBucketIdentifierAttributes","isBrowser","SDK_VERSION","loadSDKVersion","GrowthBook","constructor","this","_options","_renderer","renderer","_trackedExperiments","_completedChangeIds","_trackedFeatures","debug","_subscriptions","_featureUsageSubs","_customEventSubs","_experimentViewedSubs","ready","_assigned","_activeAutoExperiments","_triggeredExpKeys","_initialized","_redirectedUrl","_deferredTrackingCalls","_autoExperimentsAllowed","disableExperimentsOnLoad","_destroyCallbacks","logs","log","_saveDeferredTrack","_onExperimentEval","_fireSubscriptions","_recordChangedId","isGbHost","hostname","stickyBucketService","s","_saveStickyBucketAssignmentDoc","saveAssignments","plugins","plugin","_growthbook","dispatchEvent","Event","_updateAllAutoExperiments","refreshStickyBuckets","_payload","encryptedFeatures","encryptedExperiments","encryptedSavedGroups","encryptedContextualBandits","decryptPayload","_decryptedPayload","_render","initSync","generateStickyBucketAssignmentDocsSync","init","_refresh","loadFeatures","autoRefresh","subscribeToChanges","defaultHost","apiHostRequestHeaders","getFeatures","getExperiments","getDecryptedPayload","setFeatures","setEncryptedFeatures","featuresJSON","setExperiments","setEncryptedExperiments","experimentsJSON","setAttributes","_refreshForRemoteEval","updateAttributes","setAttributeOverrides","setForcedVariations","vars","setForcedFeatures","setURL","getStickyBucketAssignmentDocs","getCompletedChangeIds","_subscribeFeatureUsage","_subscribeExperimentViewed","_subscribeCustomEvents","getAllResults","onDestroy","isDestroyed","_destroyed","destroy","destroyAllStreams","undo","setRenderer","forceVariation","run","_getEvalContext","triggerExperiment","_runAutoExperiment","triggerAutoExperiments","_getUserContext","_getGlobalContext","blockedChangeIds","_getContextUrl","forceRerun","manual","isBlocked","_isAutoExperimentBlockedByContext","valueHash","_undoActiveAutoExperiment","changeType","urlRedirect","persistQueryString","oldUrl","newUrl","currUrl","redirectUrl","mergeQueryStrings","navigate","_getNavigateFunction","maxNavigateDelay","navigateDelay","applyDomChangesCallback","_applyDOMChanges","prev","isOn","isOff","getFeatureValue","msg","getDeferredTrackingCalls","setDeferredTrackingCalls","fireDeferredTrackingCalls","promises","call","setTrackingCallback","callback","setFeatureUsageCallback","setEventLogger","logger","logEvent","eventName","properties","location","disableVisualExperiments","disableJsInjection","js","disableUrlRedirectExperiments","disableCrossOriginUrlRedirectExperiments","protocol","getRedirectUrl","changes","css","head","appendChild","remove","script","jsInjectionNonce","nonce","dom_mutator_esm","docs","getAllAssignments","getAllStickyBucketAssignmentDocs","getAllAssignmentsSync","inDevMode","_performance","performance","measure","end","detail","_performance3","safeDecode","decodeURIComponent","read","cookie","_parts$slice","encodedValue","slice","trim","readAll","shift","write","encodeURIComponent","domain","expires","toUTCString","same_site","secure","serialize","readCookie","mint","bytes","getRandomValues","floor","byte","generateId","setFullYear","getFullYear","StickyBucketService","opts","prefix","getAssignments","StickyBucketServiceSync","getAssignmentsSync","saveAssignmentsSync","CookieStickyBucketService","super","cookieName","raw","setDate","getDate","_result$featureId","CustomEvent","experiment_id","feature_id","param_name","param_value","stable_id","initGrowthBookClient","viewMode","Shopify","previewMode","growthbook","growthbook_runtime","api_host","anonymous_id","initStartMillis","view_mode","preview_hold_ms","debounceTimer","renderCount","startedAt","settle","ceilingTimer","debounceMillis","waitForDevToolsOverrides","measureScheduleDelay","startMillis","load_state","_performance2","mark","anonymousId","client_loader","loadGrowthBook"],"sourceRoot":""}