{"version":3,"file":"client.mjs","sources":["../../../../src/clients/guide/client.ts"],"sourcesContent":["import { GenericData } from \"@knocklabs/types\";\nimport { Store } from \"@tanstack/store\";\nimport { Channel, Socket } from \"phoenix\";\nimport { URLPattern } from \"urlpattern-polyfill\";\n\nimport Knock from \"../../knock\";\n\nimport {\n  DEFAULT_GROUP_KEY,\n  byKey,\n  checkStateIfThrottled,\n  findDefaultGroup,\n  formatFilters,\n  formatGroupStage,\n  formatState,\n  getToolbarRunConfigFromUrl,\n  mockDefaultGroup,\n  newUrl,\n  predicateUrlPatterns,\n  predicateUrlRules,\n} from \"./helpers\";\nimport {\n  Any,\n  ConstructorOpts,\n  DebugState,\n  GetGuidesQueryParams,\n  GetGuidesResponse,\n  GroupStage,\n  GuideAddedEvent,\n  GuideData,\n  GuideGroupAddedEvent,\n  GuideGroupUpdatedEvent,\n  GuideLivePreviewUpdatedEvent,\n  GuideRemovedEvent,\n  GuideSocketEvent,\n  GuideStepData,\n  GuideUpdatedEvent,\n  KnockGuide,\n  KnockGuideStep,\n  MarkAsArchivedParams,\n  MarkAsInteractedParams,\n  MarkAsSeenParams,\n  MarkGuideAsResponse,\n  QueryFilterParams,\n  QueryStatus,\n  SelectFilterParams,\n  SelectGuideOpts,\n  SelectGuidesOpts,\n  SelectQueryLimit,\n  SelectionResult,\n  StepMessageState,\n  StoreState,\n  TargetParams,\n} from \"./types\";\n\n// How long to wait until we resolve the guides order and determine the\n// prevailing guide.\nconst DEFAULT_ORDER_RESOLUTION_DURATION = 50; // in milliseconds\n\n// How often we should increment the counter to refresh the store state and\n// trigger subscribed callbacks.\nconst DEFAULT_COUNTER_INCREMENT_INTERVAL = 30 * 1000; // in milliseconds\n\n// Maximum number of retry attempts for channel subscription\nconst SUBSCRIBE_RETRY_LIMIT = 3;\n\n// Debug query param keys\nexport const DEBUG_QUERY_PARAMS = {\n  GUIDE_KEY: \"knock_guide_key\",\n  PREVIEW_SESSION_ID: \"knock_preview_session_id\",\n};\n\nconst DEBUG_STORAGE_KEY = \"knock_guide_debug\";\n\n// Return the global window object if defined, so to safely guard against SSR.\nconst checkForWindow = () => {\n  if (typeof window !== \"undefined\") {\n    return window;\n  }\n};\n\nexport const guidesApiRootPath = (userId: string | undefined | null) =>\n  `/v1/users/${userId}/guides`;\n\n// Detect debug params from URL or local storage\nconst detectDebugParams = (): DebugState => {\n  const win = checkForWindow();\n  if (!win || !win.location) {\n    return { forcedGuideKey: null, previewSessionId: null };\n  }\n\n  const urlParams = new URLSearchParams(win.location.search);\n  const urlGuideKey = urlParams.get(DEBUG_QUERY_PARAMS.GUIDE_KEY);\n  const urlPreviewSessionId = urlParams.get(\n    DEBUG_QUERY_PARAMS.PREVIEW_SESSION_ID,\n  );\n\n  // If URL params exist, persist them to localStorage and return them\n  if (urlGuideKey || urlPreviewSessionId) {\n    if (win.localStorage) {\n      try {\n        const debugState = {\n          forcedGuideKey: urlGuideKey,\n          previewSessionId: urlPreviewSessionId,\n        };\n        win.localStorage.setItem(DEBUG_STORAGE_KEY, JSON.stringify(debugState));\n      } catch {\n        // Silently fail in privacy mode\n      }\n    }\n    return {\n      forcedGuideKey: urlGuideKey,\n      previewSessionId: urlPreviewSessionId,\n    };\n  }\n\n  // Check local storage if no URL params\n  let storedGuideKey = null;\n  let storedPreviewSessionId = null;\n\n  if (win.localStorage) {\n    try {\n      const storedDebugState = win.localStorage.getItem(DEBUG_STORAGE_KEY);\n      if (storedDebugState) {\n        const parsedDebugState = safeJsonParseDebugParams(storedDebugState);\n        storedGuideKey = parsedDebugState.forcedGuideKey;\n        storedPreviewSessionId = parsedDebugState.previewSessionId;\n      }\n    } catch {\n      // Silently fail in privacy mode\n    }\n  }\n\n  return {\n    forcedGuideKey: storedGuideKey,\n    previewSessionId: storedPreviewSessionId,\n  };\n};\n\nconst safeJsonParseDebugParams = (value: string): DebugState => {\n  try {\n    const parsed = JSON.parse(value);\n    return {\n      forcedGuideKey: parsed?.forcedGuideKey ?? null,\n      previewSessionId: parsed?.previewSessionId ?? null,\n    };\n  } catch {\n    return {\n      forcedGuideKey: null,\n      previewSessionId: null,\n    };\n  }\n};\n\ntype SelectQueryMetadata = {\n  limit: SelectQueryLimit;\n  opts: SelectGuideOpts;\n};\n\nconst select = (\n  state: StoreState,\n  filters: SelectFilterParams,\n  metadata: SelectQueryMetadata,\n) => {\n  // A map of selected guides as values, with its order index as keys.\n  const result = new SelectionResult();\n\n  const defaultGroup = findDefaultGroup(state.guideGroups);\n  if (!defaultGroup) return result;\n\n  const displaySequence = defaultGroup.display_sequence;\n  const location = state.location;\n\n  for (const [index, guideKey] of displaySequence.entries()) {\n    const guide = state.previewGuides[guideKey] || state.guides[guideKey];\n    if (!guide) continue;\n\n    const affirmed = predicate(guide, filters, {\n      location,\n      ineligibleGuides: state.ineligibleGuides,\n      debug: state.debug,\n    });\n\n    if (!affirmed) continue;\n\n    result.set(index, guide);\n  }\n\n  result.metadata = { guideGroup: defaultGroup, filters, ...metadata };\n\n  return result;\n};\n\ntype PredicateOpts = Pick<\n  StoreState,\n  \"location\" | \"ineligibleGuides\" | \"debug\"\n>;\n\nconst predicate = (\n  guide: KnockGuide,\n  filters: SelectFilterParams,\n  { location, ineligibleGuides = {}, debug = {} }: PredicateOpts,\n) => {\n  if (filters.type && filters.type !== guide.type) {\n    return false;\n  }\n\n  if (filters.key && filters.key !== guide.key) {\n    return false;\n  }\n\n  // If in debug mode with a forced guide key, bypass other filtering and always\n  // return true for that guide only. This should always run AFTER checking the\n  // filters but BEFORE checking archived status and location rules.\n  if (\n    debug.focusedGuideKeys &&\n    Object.keys(debug.focusedGuideKeys).length > 0\n  ) {\n    return !!debug.focusedGuideKeys[guide.key];\n  }\n  if (debug.forcedGuideKey) {\n    return debug.forcedGuideKey === guide.key;\n  }\n\n  const ineligible = ineligibleGuides[guide.key];\n  if (ineligible) {\n    return false;\n  }\n\n  if (!guide.active) {\n    return false;\n  }\n\n  if (guide.steps.every((s) => !!s.message.archived_at)) {\n    return false;\n  }\n\n  return checkActivatable(guide, location);\n};\n\nexport const checkActivatable = (\n  guide: KnockGuide,\n  location: string | undefined,\n) => {\n  const url = location ? newUrl(location) : undefined;\n\n  const urlRules = guide.activation_url_rules || [];\n  const urlPatterns = guide.activation_url_patterns || [];\n\n  // A guide can have either activation url rules XOR url patterns, but not both.\n  if (url && urlRules.length > 0) {\n    const allowed = predicateUrlRules(url, urlRules);\n    if (!allowed) return false;\n  } else if (url && urlPatterns.length > 0) {\n    const allowed = predicateUrlPatterns(url, urlPatterns);\n    if (!allowed) return false;\n  }\n\n  return true;\n};\n\nexport class KnockGuideClient {\n  public store: Store<StoreState, (state: StoreState) => StoreState>;\n\n  // Phoenix channels for real time guide updates over websocket\n  private socket: Socket | undefined;\n  private socketChannel: Channel | undefined;\n  private socketChannelTopic: string;\n  private socketEventTypes = [\n    \"guide.added\",\n    \"guide.updated\",\n    \"guide.removed\",\n    \"guide_group.added\",\n    \"guide_group.updated\",\n    \"guide.live_preview_updated\",\n  ];\n  private subscribeRetryCount = 0;\n\n  // Original history methods to monkey patch, or restore in cleanups.\n  private pushStateFn: History[\"pushState\"] | undefined;\n  private replaceStateFn: History[\"replaceState\"] | undefined;\n\n  // Guides that are competing to render are \"staged\" first without rendering\n  // and ranked based on its relative order in the group over a duration of time\n  // to resolve and render the prevailing one.\n  private stage: GroupStage | undefined;\n\n  private counterIntervalId: ReturnType<typeof setInterval> | undefined;\n\n  constructor(\n    readonly knock: Knock,\n    readonly channelId: string,\n    readonly targetParams: TargetParams = {},\n    readonly options: ConstructorOpts = {},\n  ) {\n    const {\n      trackLocationFromWindow = true,\n      // TODO(KNO-11523): Remove once we ship guide toolbar v2, and offload as\n      // much debugging specific logic and responsibilities to toolbar.\n      trackDebugParams = false,\n      throttleCheckInterval = DEFAULT_COUNTER_INCREMENT_INTERVAL,\n    } = options;\n    const win = checkForWindow();\n\n    const location = trackLocationFromWindow ? win?.location?.href : undefined;\n    const debug = trackDebugParams ? detectDebugParams() : undefined;\n\n    this.store = new Store<StoreState>({\n      guideGroups: [],\n      guideGroupDisplayLogs: {},\n      guides: {},\n      ineligibleGuides: {},\n      previewGuides: {},\n      queries: {},\n      location,\n      // Increment to update the state store and trigger re-selection.\n      counter: 0,\n      debug,\n    });\n\n    // In server environments we might not have a socket connection.\n    const { socket: maybeSocket } = this.knock.client();\n    this.socket = maybeSocket;\n    this.socketChannelTopic = `guides:${channelId}`;\n\n    if (trackLocationFromWindow) {\n      this.listenForLocationChangesFromWindow();\n    }\n\n    if (throttleCheckInterval) {\n      // Start the counter loop to increment at an interval.\n      this.startCounterInterval(throttleCheckInterval);\n    }\n\n    this.knock.log(\"[Guide] Initialized a guide client\");\n  }\n\n  private incrementCounter() {\n    this.knock.log(\"[Guide] Incrementing the counter\");\n    this.store.setState((state) => ({ ...state, counter: state.counter + 1 }));\n  }\n\n  private startCounterInterval(delay: number) {\n    this.counterIntervalId = setInterval(() => {\n      this.knock.log(\"[Guide] Counter interval tick\");\n      if (this.stage && this.stage.status !== \"closed\") return;\n\n      this.incrementCounter();\n    }, delay);\n  }\n\n  private clearCounterInterval() {\n    if (this.counterIntervalId) {\n      clearInterval(this.counterIntervalId);\n      this.counterIntervalId = undefined;\n    }\n  }\n\n  cleanup() {\n    this.unsubscribe();\n    this.removeLocationChangeEventListeners();\n    this.clearGroupStage();\n    this.clearCounterInterval();\n  }\n\n  async fetch(opts?: { filters?: QueryFilterParams; force?: boolean }) {\n    this.knock.log(\"[Guide] .fetch\");\n    this.knock.failIfNotAuthenticated();\n\n    const queryParams = this.buildQueryParams(opts?.filters);\n    const queryKey = this.formatQueryKey(queryParams);\n\n    // If already fetched before, then noop (unless forced).\n    const maybeQueryStatus = this.store.state.queries[queryKey];\n    if (maybeQueryStatus && !opts?.force) {\n      return maybeQueryStatus;\n    }\n\n    // Mark this query status as loading.\n    this.store.setState((state) => ({\n      ...state,\n      queries: { ...state.queries, [queryKey]: { status: \"loading\" } },\n    }));\n\n    let queryStatus: QueryStatus;\n    try {\n      this.knock.log(\"[Guide] Fetching all eligible guides\");\n      const data = await this.knock.user.getGuides<\n        GetGuidesQueryParams,\n        GetGuidesResponse\n      >(this.channelId, queryParams);\n      queryStatus = { status: \"ok\" };\n\n      const {\n        entries,\n        guide_groups: groups,\n        guide_group_display_logs,\n        ineligible_guides,\n      } = data;\n\n      // Clear group stage if one exists already before (re)setting the store\n      // state.\n      if (this.stage) {\n        this.clearGroupStage();\n      }\n\n      this.knock.log(\"[Guide] Loading fetched guides\");\n      this.store.setState((state) => ({\n        ...state,\n        guideGroups: groups?.length > 0 ? groups : [mockDefaultGroup(entries)],\n        guideGroupDisplayLogs: guide_group_display_logs || {},\n        guides: byKey(entries.map((g) => this.localCopy(g))),\n        ineligibleGuides: byKey(ineligible_guides || []),\n        queries: { ...state.queries, [queryKey]: queryStatus },\n      }));\n    } catch (e) {\n      queryStatus = { status: \"error\", error: e as Error };\n\n      this.store.setState((state) => ({\n        ...state,\n        queries: { ...state.queries, [queryKey]: queryStatus },\n      }));\n    }\n\n    return queryStatus;\n  }\n\n  subscribe() {\n    if (!this.socket) return;\n    this.knock.failIfNotAuthenticated();\n    this.knock.log(\"[Guide] Subscribing to real time updates\");\n\n    // Ensure a live socket connection if not yet connected.\n    if (!this.socket.isConnected()) {\n      this.socket.connect();\n    }\n\n    // If there's an existing connected channel, then disconnect.\n    if (this.socketChannel) {\n      this.unsubscribe();\n    }\n\n    // Join the channel topic and subscribe to supported events.\n    const debugState = this.store.state.debug;\n    const params = {\n      ...this.targetParams,\n      user_id: this.knock.userId,\n      force_all_guides:\n        debugState?.forcedGuideKey || debugState?.debugging ? true : undefined,\n      preview_session_id: debugState?.previewSessionId || undefined,\n    };\n\n    const newChannel = this.socket.channel(this.socketChannelTopic, params);\n\n    for (const eventType of this.socketEventTypes) {\n      newChannel.on(eventType, (payload) => this.handleSocketEvent(payload));\n    }\n\n    if ([\"closed\", \"errored\"].includes(newChannel.state)) {\n      // Reset retry count for new subscription attempt\n      this.subscribeRetryCount = 0;\n\n      newChannel\n        .join()\n        .receive(\"ok\", () => {\n          this.knock.log(\"[Guide] Successfully joined channel\");\n        })\n        .receive(\"error\", (resp) => {\n          this.knock.log(\n            `[Guide] Failed to join channel: ${JSON.stringify(resp)}`,\n          );\n          this.handleChannelJoinError();\n        })\n        .receive(\"timeout\", () => {\n          this.knock.log(\"[Guide] Channel join timed out\");\n          this.handleChannelJoinError();\n        });\n    }\n\n    // Track the joined channel.\n    this.socketChannel = newChannel;\n  }\n\n  private handleChannelJoinError() {\n    // Prevent phx channel from retrying forever in case of either network or\n    // other errors (e.g. auth error, invalid channel etc)\n    if (this.subscribeRetryCount >= SUBSCRIBE_RETRY_LIMIT) {\n      this.knock.log(\n        `[Guide] Channel join max retry limit reached: ${this.subscribeRetryCount}`,\n      );\n      this.unsubscribe();\n      return;\n    }\n\n    this.subscribeRetryCount++;\n  }\n\n  unsubscribe() {\n    if (!this.socketChannel) return;\n    this.knock.log(\"[Guide] Unsubscribing from real time updates\");\n\n    // Unsubscribe from the socket events and leave the channel.\n    for (const eventType of this.socketEventTypes) {\n      this.socketChannel.off(eventType);\n    }\n    this.socketChannel.leave();\n\n    // Unset the channel.\n    this.socketChannel = undefined;\n  }\n\n  private handleSocketEvent(payload: GuideSocketEvent) {\n    const { event, data } = payload;\n\n    // TODO(KNO-11489): Include an ineligible guide in the socket payload too\n    // and process it when handling socket events in real time.\n    switch (event) {\n      case \"guide.added\":\n        return this.addOrReplaceGuide(payload);\n\n      case \"guide.updated\":\n        return data.eligible\n          ? this.addOrReplaceGuide(payload)\n          : this.removeGuide(payload);\n\n      case \"guide.removed\":\n        return this.removeGuide(payload);\n\n      case \"guide_group.added\":\n      case \"guide_group.updated\":\n        return this.addOrReplaceGuideGroup(payload);\n\n      case \"guide.live_preview_updated\":\n        return this.updatePreviewGuide(payload);\n\n      default:\n        return;\n    }\n  }\n\n  setLocation(href: string, additionalParams: Partial<StoreState> = {}) {\n    this.knock.log(`[Guide] .setLocation (loc=${href})`);\n\n    // Make sure to clear out the stage.\n    this.clearGroupStage();\n\n    this.knock.log(\"[Guide] Updating the tracked location\");\n    this.store.setState((state) => {\n      // Clear preview guides if no longer in preview mode\n      const previewGuides = additionalParams?.debug?.previewSessionId\n        ? state.previewGuides\n        : {};\n\n      return {\n        ...state,\n        ...additionalParams,\n        previewGuides,\n        location: href,\n      };\n    });\n  }\n\n  exitDebugMode() {\n    this.knock.log(\"[Guide] Exiting debug mode\");\n\n    // Clear localStorage debug params\n    const win = checkForWindow();\n    if (win?.localStorage) {\n      try {\n        win.localStorage.removeItem(DEBUG_STORAGE_KEY);\n      } catch {\n        // Silently fail in privacy mode\n      }\n    }\n\n    // Clear debug state from store\n    this.store.setState((state) => ({\n      ...state,\n      debug: {\n        forcedGuideKey: null,\n        previewSessionId: null,\n        focusedGuideKeys: {},\n      },\n      previewGuides: {}, // Clear preview guides when exiting debug mode\n    }));\n\n    // Remove URL query params if present\n    // Only update the URL if params need to be cleared to avoid unnecessary navigations\n    if (win?.location) {\n      const url = new URL(win.location.href);\n      if (\n        url.searchParams.has(DEBUG_QUERY_PARAMS.GUIDE_KEY) ||\n        url.searchParams.has(DEBUG_QUERY_PARAMS.PREVIEW_SESSION_ID)\n      ) {\n        url.searchParams.delete(DEBUG_QUERY_PARAMS.GUIDE_KEY);\n        url.searchParams.delete(DEBUG_QUERY_PARAMS.PREVIEW_SESSION_ID);\n        win.location.href = url.toString();\n      }\n    }\n  }\n\n  setDebug(debugOpts?: Omit<DebugState, \"debugging\">) {\n    this.knock.log(\"[Guide] .setDebug()\");\n\n    if (!this.knock.isAuthenticated()) {\n      this.knock.log(\"[Guide] Not authenticated, cannot start debugging\");\n      return;\n    }\n\n    const shouldRefetch = !this.store.state.debug?.debugging;\n\n    // Clear the stage before updating the store state to let the next render\n    // cycle run with a fresh group stage.\n    this.clearGroupStage();\n\n    this.store.setState((state) => ({\n      ...state,\n      debug: {\n        skipEngagementTracking: true,\n        ignoreDisplayInterval: true,\n        focusedGuideKeys: {},\n        ...debugOpts,\n        debugging: true,\n      },\n    }));\n\n    if (shouldRefetch) {\n      this.knock.log(\n        `[Guide] Start debugging, refetching guides and resubscribing to the websocket channel`,\n      );\n      this.fetch({ force: true });\n      // Always subscribe while debugging.\n      this.subscribe();\n    }\n  }\n\n  unsetDebug(opts?: { listenForUpdates?: boolean }) {\n    this.knock.log(\"[Guide] .unsetDebug()\");\n    const shouldRefetch = this.store.state.debug?.debugging;\n\n    // Clear the stage before updating the store state to let the next render\n    // cycle run with a fresh group stage.\n    this.clearGroupStage();\n\n    this.store.setState((state) => ({ ...state, debug: undefined }));\n\n    if (!this.knock.isAuthenticated()) {\n      this.knock.log(\"[Guide] Not authenticated, will not refetch\");\n      return;\n    }\n\n    if (shouldRefetch) {\n      this.knock.log(\n        `[Guide] Stop debugging, refetching guides and resubscribing to the websocket channel`,\n      );\n      this.fetch({ force: true });\n      if (opts?.listenForUpdates) {\n        this.subscribe();\n      } else {\n        this.unsubscribe();\n      }\n    }\n  }\n\n  //\n  // Store selector\n  //\n\n  selectGuides<C = Any>(\n    state: StoreState,\n    filters: SelectFilterParams = {},\n    opts: SelectGuidesOpts = {},\n  ): KnockGuide<C>[] {\n    this.knock.log(\n      `[Guide] .selectGuides (filters: ${formatFilters(filters)}; state: ${formatState(state)})`,\n    );\n\n    // 1. First, call selectGuide() using the same filters to ensure we have a\n    // group stage open and respect throttling. This isn't the real query, but\n    // rather it's a shortcut ahead of handling the actual query result below.\n    const selectedGuide = this.selectGuide(state, filters, {\n      ...opts,\n      // Don't record this result, not the actual query result we need.\n      recordSelectQuery: false,\n    });\n\n    // 2. Now make the actual select query with the provided filters and opts,\n    // and record the result (as needed). By default, we only record the result\n    // while in debugging.\n    const { recordSelectQuery = !!state.debug?.debugging } = opts;\n    const metadata: SelectQueryMetadata = {\n      limit: \"all\",\n      opts: { ...opts, recordSelectQuery },\n    };\n    const result = select(state, filters, metadata);\n    this.maybeRecordSelectResult(result);\n\n    // 3. Stop if there is not at least one guide to return.\n    if (!selectedGuide && !opts.includeThrottled) {\n      return [];\n    }\n\n    // There should be at least one guide to return here now.\n    const guides = [...result.values()];\n\n    // 4. If throttled, filter out any throttled guides.\n    if (!opts.includeThrottled && checkStateIfThrottled(state)) {\n      const unthrottledGuides = guides.filter(\n        (g) => g.bypass_global_group_limit,\n      );\n      const throttledCount = guides.length - unthrottledGuides.length;\n      this.knock.log(\n        `[Guide] Throttling ${throttledCount} guides from selection, and returning ${unthrottledGuides.length} guides`,\n      );\n\n      return unthrottledGuides;\n    }\n\n    this.knock.log(`[Guide] Returning ${guides.length} guides from selection`);\n    return guides;\n  }\n\n  selectGuide<C = Any>(\n    state: StoreState,\n    filters: SelectFilterParams = {},\n    opts: SelectGuideOpts = {},\n  ): KnockGuide<C> | undefined {\n    this.knock.log(\n      `[Guide] .selectGuide (filters: ${formatFilters(filters)}; state: ${formatState(state)})`,\n    );\n    if (\n      Object.keys(state.guides).length === 0 &&\n      Object.keys(state.previewGuides).length === 0\n    ) {\n      this.knock.log(\"[Guide] Exiting selection (no guides)\");\n      return undefined;\n    }\n\n    // Starting here to the end of this method represents the core logic of how\n    // \"group stage\" works. It provides a mechanism for 1) figuring out which\n    // guide components are about to render on a page, 2) determining which\n    // among them ranks highest in the configured display sequence, and 3)\n    // returning only the prevailing guide to render at a time.\n    //\n    // Imagine N number of components that use the `useGuide()` hook which\n    // calls this `selectGuide()` method, and the logic works like this:\n    // * The first time this method is called, we don't have an \"open\" group\n    //   stage, so we open one (this occurs when a new page/route is rendering).\n    //   * While it is open, we record which guide was selected and its order\n    //     index from each call, but we do NOT return any guide to render yet.\n    //   * When a group stage opens, it schedules a timer to close itself. How\n    //     long this timer waits is configurable. Note, `setTimeout` with 0\n    //     delay seems to work well for React apps, where we \"yield\" to React\n    //     for one render cycle and close the group right after.\n    // * When a group stage closes, we evaluate which guides were selected and\n    //   recorded, then determine the winning guide (i.e. the one with the\n    //   lowest order index value).\n    //   * Then increment the internal counter to trigger a store state update,\n    //     which allows `useGuide()` and `selectGuide()` to re-run. This second\n    //     round of `selectGuide()` calls, occurring when the group stage is\n    //     closed, results in returning the prevailing guide.\n    // * Whenever a user navigates to a new page, we repeat the same process\n    //   above.\n    // * There's a third status called \"patch,\" which is for handling real-time\n    //   updates received from the API. It's similar to the \"open\" to \"closed\"\n    //   flow, except we keep the resolved guide in place while we recalculate.\n    //   This is done so that we don't cause flickers or CLS.\n    if (!this.stage) {\n      this.stage = this.openGroupStage(); // Assign here to make tsc happy\n    }\n\n    // Must come AFTER we ensure a group stage exists above, so we can record\n    // select queries. By default, we only record the result while in debugging.\n    const { recordSelectQuery = !!state.debug?.debugging } = opts;\n    const metadata: SelectQueryMetadata = {\n      limit: \"one\",\n      opts: { ...opts, recordSelectQuery },\n    };\n    const result = select(state, filters, metadata);\n    this.maybeRecordSelectResult(result);\n\n    if (result.size === 0) {\n      this.knock.log(\"[Guide] Selection found zero result\");\n      return undefined;\n    }\n\n    const [index, guide] = [...result][0]!;\n    this.knock.log(\n      `[Guide] Selection found: \\`${guide.key}\\` (total: ${result.size})`,\n    );\n\n    // If a guide ignores the group limit, then return immediately to render\n    // always.\n    if (guide.bypass_global_group_limit) {\n      this.knock.log(`[Guide] Returning the unthrottled guide: ${guide.key}`);\n      return guide;\n    }\n\n    // If focused while in debug mode, then we want to ignore the guide order\n    // and throttle settings and force render this guide.\n    const focusedInDebug = state.debug?.focusedGuideKeys?.[guide.key];\n\n    const throttled = !opts.includeThrottled && checkStateIfThrottled(state);\n\n    switch (this.stage.status) {\n      case \"open\": {\n        this.knock.log(`[Guide] Adding to the group stage: ${guide.key}`);\n        this.stage.ordered[index] = guide.key;\n        return undefined;\n      }\n\n      case \"patch\": {\n        this.knock.log(`[Guide] Patching the group stage: ${guide.key}`);\n        // Refresh the ordered queue in the group stage while continuing to\n        // render the currently resolved guide while in patch window, so that\n        // we can re-resolve when the group stage closes.\n        this.stage.ordered[index] = guide.key;\n\n        if (focusedInDebug) {\n          this.knock.log(\n            `[Guide] Focused to return \\`${guide.key}\\` (stage: ${formatGroupStage(this.stage)})`,\n          );\n          return guide;\n        }\n\n        if (throttled) {\n          this.knock.log(`[Guide] Throttling the selected guide: ${guide.key}`);\n          return undefined;\n        }\n\n        const ret = this.stage.resolved === guide.key ? guide : undefined;\n        this.knock.log(\n          `[Guide] Returning \\`${ret?.key}\\` (stage: ${formatGroupStage(this.stage)})`,\n        );\n        return ret;\n      }\n\n      case \"closed\": {\n        if (focusedInDebug) {\n          this.knock.log(\n            `[Guide] Focused to return \\`${guide.key}\\` (stage: ${formatGroupStage(this.stage)})`,\n          );\n          return guide;\n        }\n\n        if (throttled) {\n          this.knock.log(`[Guide] Throttling the selected guide: ${guide.key}`);\n          return undefined;\n        }\n\n        const ret = this.stage.resolved === guide.key ? guide : undefined;\n        this.knock.log(\n          `[Guide] Returning \\`${ret?.key}\\` (stage: ${formatGroupStage(this.stage)})`,\n        );\n        return ret;\n      }\n    }\n  }\n\n  // Record select query results by accumulating them by 1) key or type first,\n  // and then 2) \"one\" or \"all\".\n  private maybeRecordSelectResult(result: SelectionResult) {\n    if (!result.metadata) return;\n\n    const { opts, filters, limit } = result.metadata;\n    if (!opts.recordSelectQuery) return;\n    if (!filters.key && !filters.type) return;\n    if (!this.stage || this.stage.status === \"closed\") return;\n\n    // Deep merge to accumulate the results.\n    const queriedByKey = this.stage.results.key || {};\n    if (filters.key) {\n      queriedByKey[filters.key] = {\n        ...(queriedByKey[filters.key] || {}),\n        ...{ [limit]: result },\n      };\n    }\n    const queriedByType = this.stage.results.type || {};\n    if (filters.type) {\n      queriedByType[filters.type] = {\n        ...(queriedByType[filters.type] || {}),\n        ...{ [limit]: result },\n      };\n    }\n\n    this.stage = {\n      ...this.stage,\n      results: { key: queriedByKey, type: queriedByType },\n    };\n  }\n\n  getStage() {\n    return this.stage;\n  }\n\n  private openGroupStage() {\n    this.knock.log(\"[Guide] Opening a new group stage\");\n\n    const {\n      orderResolutionDuration: delay = DEFAULT_ORDER_RESOLUTION_DURATION,\n    } = this.options;\n\n    const timeoutId = setTimeout(() => {\n      this.closePendingGroupStage();\n      this.incrementCounter();\n    }, delay);\n\n    this.stage = {\n      status: \"open\",\n      ordered: [],\n      results: {},\n      timeoutId,\n    };\n\n    return this.stage;\n  }\n\n  // Close the current non-closed stage to resolve the prevailing guide up next\n  // for display amongst the ones that have been staged.\n  private closePendingGroupStage() {\n    this.knock.log(\"[Guide] .closePendingGroupStage\");\n    if (!this.stage || this.stage.status === \"closed\") return;\n\n    // Should have been cleared already since this method should be called as a\n    // callback to a setTimeout, but just to be safe.\n    this.ensureClearTimeout();\n\n    // Resolve to the first non-undefined guide in the stage.\n    const resolved = this.stage.ordered.find((x) => x !== undefined);\n\n    this.knock.log(\n      `[Guide] Closing the current group stage: resolved=${resolved}`,\n    );\n\n    this.stage = {\n      ...this.stage,\n      status: \"closed\",\n      resolved,\n      timeoutId: null,\n    };\n\n    return this.stage;\n  }\n\n  // Set the current closed stage status to \"patch\" to allow re-running\n  // selections and re-building a group stage with the latest/updated state,\n  // while keeping the currently resolved guide in place so that it stays\n  // rendered until we are ready to resolve the updated stage and re-render.\n  // Note, must be called ahead of updating the state store.\n  private patchClosedGroupStage() {\n    this.knock.log(\"[Guide] .patchClosedGroupStage\");\n    if (this.stage?.status !== \"closed\") return;\n\n    const { orderResolutionDuration: delay = 0 } = this.options;\n\n    const timeoutId = setTimeout(() => {\n      this.closePendingGroupStage();\n      this.incrementCounter();\n    }, delay);\n\n    // Just to be safe.\n    this.ensureClearTimeout();\n\n    this.knock.log(\"[Guide] Patching the current group stage\");\n\n    this.stage = {\n      ...this.stage,\n      status: \"patch\",\n      ordered: [],\n      timeoutId,\n    };\n\n    return this.stage;\n  }\n\n  private clearGroupStage() {\n    this.knock.log(\"[Guide] .clearGroupStage\");\n    if (!this.stage) return;\n\n    this.knock.log(\"[Guide] Clearing the current group stage\");\n    this.ensureClearTimeout();\n    this.stage = undefined;\n  }\n\n  private ensureClearTimeout() {\n    if (this.stage?.timeoutId) {\n      clearTimeout(this.stage.timeoutId);\n    }\n  }\n\n  // Test helpers to open and close the group stage to return the select result\n  // immediately.\n  private _selectGuide(\n    state: StoreState,\n    filters: SelectFilterParams = {},\n    opts: SelectGuideOpts = {},\n  ) {\n    this.openGroupStage();\n\n    this.selectGuide(state, filters, opts);\n    this.closePendingGroupStage();\n\n    return this.selectGuide(state, filters, opts);\n  }\n\n  private _selectGuides(\n    state: StoreState,\n    filters: SelectFilterParams = {},\n    opts: SelectGuidesOpts = {},\n  ) {\n    this.openGroupStage();\n\n    this.selectGuides(state, filters, opts);\n    this.closePendingGroupStage();\n\n    return this.selectGuides(state, filters, opts);\n  }\n\n  //\n  // Engagement event handlers\n  //\n  // Make an optimistic update on the client side first, then send an engagement\n  // event to the backend.\n  //\n\n  async markAsSeen(guide: GuideData, step: GuideStepData) {\n    if (step.message.seen_at) return;\n\n    this.knock.log(\n      `[Guide] Marking as seen (Guide key: ${guide.key}, Step ref:${step.ref})`,\n    );\n\n    const updatedStep = this.setStepMessageAttrs(guide.key, step.ref, {\n      seen_at: new Date().toISOString(),\n    });\n    if (!updatedStep) return;\n\n    if (this.shouldSkipEngagementApi()) {\n      this.knock.log(\n        \"[Guide] Skipping engagement API call for markAsSeen (debug mode)\",\n      );\n      return updatedStep;\n    }\n\n    const params = {\n      ...this.buildEngagementEventBaseParams(guide, updatedStep),\n      content: updatedStep.content,\n      data: this.targetParams.data,\n    };\n\n    this.knock.user.markGuideStepAs<MarkAsSeenParams, MarkGuideAsResponse>(\n      \"seen\",\n      params,\n    );\n\n    return updatedStep;\n  }\n\n  async markAsInteracted(\n    guide: GuideData,\n    step: GuideStepData,\n    metadata?: GenericData,\n  ) {\n    this.knock.log(\n      `[Guide] Marking as interacted (Guide key: ${guide.key}; Step ref:${step.ref})`,\n    );\n\n    const ts = new Date().toISOString();\n    const updatedStep = this.setStepMessageAttrs(guide.key, step.ref, {\n      read_at: ts,\n      interacted_at: ts,\n    });\n    if (!updatedStep) return;\n\n    if (this.shouldSkipEngagementApi()) {\n      this.knock.log(\n        \"[Guide] Skipping engagement API call for markAsInteracted (debug mode)\",\n      );\n      return updatedStep;\n    }\n\n    const params = {\n      ...this.buildEngagementEventBaseParams(guide, updatedStep),\n      metadata,\n    };\n\n    this.knock.user.markGuideStepAs<\n      MarkAsInteractedParams,\n      MarkGuideAsResponse\n    >(\"interacted\", params);\n\n    return updatedStep;\n  }\n\n  async markAsArchived(guide: GuideData, step: GuideStepData) {\n    if (step.message.archived_at) return;\n\n    this.knock.log(\n      `[Guide] Marking as archived (Guide key: ${guide.key}, Step ref:${step.ref})`,\n    );\n\n    const updatedStep = this.setStepMessageAttrs(guide.key, step.ref, {\n      archived_at: new Date().toISOString(),\n    });\n    if (!updatedStep) return;\n\n    if (this.shouldSkipEngagementApi()) {\n      this.knock.log(\n        \"[Guide] Skipping engagement API call for markAsArchived (debug mode)\",\n      );\n      return updatedStep;\n    }\n\n    const params = this.buildEngagementEventBaseParams(guide, updatedStep);\n\n    this.knock.user.markGuideStepAs<MarkAsArchivedParams, MarkGuideAsResponse>(\n      \"archived\",\n      {\n        ...params,\n        unthrottled: guide.bypass_global_group_limit,\n      },\n    );\n\n    return updatedStep;\n  }\n\n  async resetEngagement(guide: GuideData) {\n    const target = this.store.state.guides[guide.key];\n    if (!target || !target.hasEngagement()) return;\n\n    this.knock.log(`[Guide] Resetting engagement (Guide key: ${guide.key})`);\n\n    // Note: Bypass the skipEngagementTracking debug setting, so that the user\n    // can reset engagement from the toolbar while debugging.\n    const response = await this.knock.user.resetGuideEngagement({\n      guide_key: guide.key,\n      tenant: this.targetParams.tenant,\n    });\n\n    if (response.status !== \"ok\") return;\n\n    // Await the refetch so the store has fresh guide state (including\n    // ineligibleGuides) then re-cycle the group stage.\n    await this.fetch({ force: true });\n  }\n\n  private shouldSkipEngagementApi(): boolean {\n    return !!this.store.state.debug?.skipEngagementTracking;\n  }\n\n  //\n  // Helpers\n  //\n\n  private localCopy(remoteGuide: GuideData) {\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    const self = this;\n\n    // Build a local copy with helper methods added.\n    const localGuide = {\n      ...remoteGuide,\n      // Get the next unarchived step.\n      getStep() {\n        // If debugging this guide, return the first step regardless of archive status\n        if (\n          self.store.state.debug?.forcedGuideKey === this.key ||\n          self.store.state.debug?.focusedGuideKeys?.[this.key]\n        ) {\n          return this.steps[0];\n        }\n\n        return this.steps.find((s) => !s.message.archived_at);\n      },\n      // Check whether any of its steps have an engagement timestamp.\n      hasEngagement() {\n        return this.steps.some(\n          (step) =>\n            step.message.seen_at ||\n            step.message.read_at ||\n            step.message.interacted_at ||\n            step.message.archived_at ||\n            step.message.link_clicked_at,\n        );\n      },\n    } as KnockGuide;\n\n    localGuide.getStep = localGuide.getStep.bind(localGuide);\n    localGuide.hasEngagement = localGuide.hasEngagement.bind(localGuide);\n\n    localGuide.steps = remoteGuide.steps.map(({ message, ...rest }) => {\n      const localStep = {\n        ...rest,\n        message: { ...message },\n        markAsSeen() {\n          return self.markAsSeen(localGuide, this);\n        },\n        markAsInteracted({ metadata }: { metadata?: GenericData } = {}) {\n          return self.markAsInteracted(localGuide, this, metadata);\n        },\n        markAsArchived() {\n          return self.markAsArchived(localGuide, this);\n        },\n      };\n\n      // Bind all engagement action handler methods to the local step object so\n      // they can operate on itself.\n      localStep.markAsSeen = localStep.markAsSeen.bind(localStep);\n      localStep.markAsInteracted = localStep.markAsInteracted.bind(localStep);\n      localStep.markAsArchived = localStep.markAsArchived.bind(localStep);\n\n      return localStep;\n    });\n\n    localGuide.activation_url_patterns =\n      remoteGuide.activation_url_patterns.map((rule) => {\n        return {\n          ...rule,\n          pattern: new URLPattern({\n            pathname: rule.pathname ?? undefined,\n            search: rule.search ?? undefined,\n          }),\n        };\n      });\n\n    return localGuide;\n  }\n\n  private buildQueryParams(filterParams: QueryFilterParams = {}) {\n    // Combine the target params with the given filter params.\n    const combinedParams: GenericData = {\n      ...this.targetParams,\n      ...filterParams,\n    };\n\n    // Append debug params\n    const debugState = this.store.state.debug;\n    if (debugState?.forcedGuideKey || debugState?.debugging) {\n      combinedParams.force_all_guides = true;\n    }\n\n    // Prune out any keys that have an undefined or null value.\n    let params = Object.fromEntries(\n      Object.entries(combinedParams).filter(\n        ([_k, v]) => v !== undefined && v !== null,\n      ),\n    );\n\n    // Encode target data as a JSON string, if provided.\n    params = params.data\n      ? { ...params, data: JSON.stringify(params.data) }\n      : params;\n\n    return params as GetGuidesQueryParams;\n  }\n\n  private formatQueryKey(queryParams: GenericData) {\n    const sortedKeys = Object.keys(queryParams).sort();\n\n    const queryStr = sortedKeys\n      .map(\n        (key) =>\n          `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`,\n      )\n      .join(\"&\");\n\n    const basePath = guidesApiRootPath(this.knock.userId);\n    return queryStr ? `${basePath}?${queryStr}` : basePath;\n  }\n\n  private setStepMessageAttrs(\n    guideKey: string,\n    stepRef: string,\n    attrs: Partial<StepMessageState>,\n  ) {\n    let updatedStep: KnockGuideStep | undefined;\n\n    // If we are marking as archived, clear the group stage so we can render\n    // the next guide in the group.\n    if (attrs.archived_at) {\n      this.clearGroupStage();\n    }\n\n    this.store.setState((state) => {\n      let guide = state.guides[guideKey];\n      if (!guide) return state;\n\n      const steps = guide.steps.map((step) => {\n        if (step.ref !== stepRef) return step;\n\n        // Mutate in place and maintain the same obj ref so to make it easier\n        // to use in hook deps.\n        step.message = { ...step.message, ...attrs };\n        updatedStep = step;\n\n        return step;\n      });\n      // If updated, return the guide as a new object so useStore can trigger.\n      guide = updatedStep ? { ...guide, steps } : guide;\n\n      const guides = { ...state.guides, [guide.key]: guide };\n\n      // If the guide is subject to throttled settings and we are marking as\n      // archived, then update the display logs to start a new throttle window.\n      const guideGroupDisplayLogs =\n        attrs.archived_at && !guide.bypass_global_group_limit\n          ? {\n              ...state.guideGroupDisplayLogs,\n              [DEFAULT_GROUP_KEY]: attrs.archived_at,\n            }\n          : state.guideGroupDisplayLogs;\n\n      return { ...state, guides, guideGroupDisplayLogs };\n    });\n\n    return updatedStep;\n  }\n\n  private buildEngagementEventBaseParams(\n    guide: GuideData,\n    step: GuideStepData,\n  ) {\n    return {\n      channel_id: guide.channel_id,\n      guide_key: guide.key,\n      guide_id: guide.id,\n      guide_step_ref: step.ref,\n      // Can be used for scoping guide messages.\n      tenant: this.targetParams.tenant,\n    };\n  }\n\n  private addOrReplaceGuide({ data }: GuideAddedEvent | GuideUpdatedEvent) {\n    this.patchClosedGroupStage();\n\n    const guide = this.localCopy(data.guide);\n\n    this.store.setState((state) => {\n      const guides = { ...state.guides, [guide.key]: guide };\n\n      return { ...state, guides };\n    });\n  }\n\n  private removeGuide({ data }: GuideUpdatedEvent | GuideRemovedEvent) {\n    this.patchClosedGroupStage();\n\n    this.store.setState((state) => {\n      const { [data.guide.key]: _, ...rest } = state.guides;\n      return { ...state, guides: rest };\n    });\n  }\n\n  private addOrReplaceGuideGroup({\n    data,\n  }: GuideGroupAddedEvent | GuideGroupUpdatedEvent) {\n    this.patchClosedGroupStage();\n\n    this.store.setState((state) => {\n      // Currently we only support a single default global group, so we can just\n      // update the list with the added/updated group.\n      const guideGroups = [data.guide_group];\n\n      // A guide group event can include lists of unthrottled vs throttled guide\n      // keys which we can use to bulk update the guides in the store already.\n      const unthrottled = data.guide_group.display_sequence_unthrottled || [];\n      const throttled = data.guide_group.display_sequence_throttled || [];\n\n      let guides = state.guides;\n\n      guides = unthrottled.reduce((acc, key) => {\n        if (!acc[key]) return acc;\n        const guide = { ...acc[key], bypass_global_group_limit: true };\n        return { ...acc, [key]: guide };\n      }, guides);\n\n      guides = throttled.reduce((acc, key) => {\n        if (!acc[key]) return acc;\n        const guide = { ...acc[key], bypass_global_group_limit: false };\n        return { ...acc, [key]: guide };\n      }, guides);\n\n      return { ...state, guides, guideGroups };\n    });\n  }\n\n  private updatePreviewGuide({ data }: GuideLivePreviewUpdatedEvent) {\n    const guide = this.localCopy(data.guide);\n\n    this.store.setState((state) => {\n      const previewGuides = { ...state.previewGuides, [guide.key]: guide };\n      return { ...state, previewGuides };\n    });\n  }\n\n  // Define as an arrow func property to always bind this to the class instance.\n  private handleLocationChange = () => {\n    this.knock.log(`[Guide] .handleLocationChange`);\n    const win = checkForWindow();\n    if (!win?.location) return;\n\n    const href = win.location.href;\n    if (this.store.state.location === href) return;\n\n    this.knock.log(`[Guide] Detected a location change: ${href}`);\n\n    if (!this.options.trackDebugParams) {\n      this.setLocation(href);\n      return;\n    }\n\n    // TODO(KNO-11523): Remove below once we ship toolbar v2.\n\n    // If entering debug mode, fetch all guides.\n    const currentDebugParams = this.store.state.debug || {};\n    const newDebugParams = detectDebugParams();\n\n    this.setLocation(href, { debug: newDebugParams });\n\n    // If debug state has changed, refetch guides and resubscribe to the websocket channel\n    const debugStateChanged = this.checkDebugStateChanged(\n      currentDebugParams,\n      newDebugParams,\n    );\n\n    if (debugStateChanged) {\n      this.knock.log(\n        `[Guide] Debug state changed, refetching guides and resubscribing to the websocket channel`,\n      );\n      this.fetch();\n      this.subscribe();\n    }\n  };\n\n  // Returns whether debug params have changed. For guide key, we only check\n  // presence since the exact value has no impact on fetch/subscribe\n  private checkDebugStateChanged(a: DebugState, b: DebugState): boolean {\n    return (\n      Boolean(a.forcedGuideKey) !== Boolean(b.forcedGuideKey) ||\n      a.previewSessionId !== b.previewSessionId\n    );\n  }\n\n  private listenForLocationChangesFromWindow() {\n    const win = checkForWindow();\n    if (win?.history && win?.addEventListener) {\n      // 1. Listen for browser back/forward button clicks.\n      win.addEventListener(\"popstate\", this.handleLocationChange);\n\n      // 2. Listen for hash changes in case it's used for routing.\n      win.addEventListener(\"hashchange\", this.handleLocationChange);\n\n      // 3. Monkey-patch history methods to catch programmatic navigation.\n      const pushStateFn = win.history.pushState;\n      const replaceStateFn = win.history.replaceState;\n\n      // Use setTimeout to allow the browser state to potentially settle.\n      win.history.pushState = new Proxy(pushStateFn, {\n        apply: (target, history, args) => {\n          Reflect.apply(target, history, args);\n          setTimeout(() => {\n            this.handleLocationChange();\n          }, 0);\n        },\n      });\n      win.history.replaceState = new Proxy(replaceStateFn, {\n        apply: (target, history, args) => {\n          Reflect.apply(target, history, args);\n          setTimeout(() => {\n            this.handleLocationChange();\n          }, 0);\n        },\n      });\n\n      // 4. Keep refs to the original handlers so we can restore during cleanup.\n      this.pushStateFn = pushStateFn;\n      this.replaceStateFn = replaceStateFn;\n    } else {\n      this.knock.log(\n        \"[Guide] Unable to access the `window.history` object to detect location changes\",\n      );\n    }\n  }\n\n  removeLocationChangeEventListeners() {\n    const win = checkForWindow();\n    if (!win?.history || !win?.removeEventListener) return;\n\n    win.removeEventListener(\"popstate\", this.handleLocationChange);\n    win.removeEventListener(\"hashchange\", this.handleLocationChange);\n\n    if (this.pushStateFn) {\n      win.history.pushState = this.pushStateFn;\n      this.pushStateFn = undefined;\n    }\n    if (this.replaceStateFn) {\n      win.history.replaceState = this.replaceStateFn;\n      this.replaceStateFn = undefined;\n    }\n  }\n\n  static getToolbarRunConfigFromUrl() {\n    return getToolbarRunConfigFromUrl();\n  }\n}\n"],"names":["DEFAULT_ORDER_RESOLUTION_DURATION","DEFAULT_COUNTER_INCREMENT_INTERVAL","SUBSCRIBE_RETRY_LIMIT","DEBUG_QUERY_PARAMS","DEBUG_STORAGE_KEY","checkForWindow","guidesApiRootPath","userId","detectDebugParams","win","urlParams","urlGuideKey","urlPreviewSessionId","debugState","storedGuideKey","storedPreviewSessionId","storedDebugState","parsedDebugState","safeJsonParseDebugParams","value","parsed","select","state","filters","metadata","result","SelectionResult","defaultGroup","findDefaultGroup","displaySequence","location","index","guideKey","guide","predicate","ineligibleGuides","debug","s","checkActivatable","url","newUrl","urlRules","urlPatterns","predicateUrlRules","predicateUrlPatterns","KnockGuideClient","knock","channelId","targetParams","options","__publicField","href","currentDebugParams","newDebugParams","trackLocationFromWindow","trackDebugParams","throttleCheckInterval","_a","Store","maybeSocket","delay","opts","queryParams","queryKey","maybeQueryStatus","queryStatus","data","entries","groups","guide_group_display_logs","ineligible_guides","mockDefaultGroup","byKey","g","e","params","newChannel","eventType","payload","resp","event","additionalParams","previewGuides","debugOpts","shouldRefetch","formatFilters","formatState","selectedGuide","recordSelectQuery","guides","checkStateIfThrottled","unthrottledGuides","throttledCount","focusedInDebug","_c","_b","throttled","formatGroupStage","ret","limit","queriedByKey","queriedByType","timeoutId","resolved","x","step","updatedStep","ts","target","remoteGuide","self","localGuide","message","rest","localStep","rule","URLPattern","filterParams","combinedParams","_k","v","queryStr","key","basePath","stepRef","attrs","steps","guideGroupDisplayLogs","DEFAULT_GROUP_KEY","_","guideGroups","unthrottled","acc","a","b","pushStateFn","replaceStateFn","history","args","getToolbarRunConfigFromUrl"],"mappings":"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"}