@guidelytech/sdk-core 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capture-4EgpjK6Z.d.cts +100 -0
- package/dist/capture-C-4R56G0.d.ts +100 -0
- package/dist/capture.cjs +3 -1
- package/dist/capture.cjs.map +1 -1
- package/dist/capture.d.cts +3 -3
- package/dist/capture.d.ts +3 -3
- package/dist/capture.js +1 -1
- package/dist/chunk-2E2YUQAG.js +334 -0
- package/dist/chunk-2E2YUQAG.js.map +1 -0
- package/dist/chunk-XML74K2P.js +378 -0
- package/dist/chunk-XML74K2P.js.map +1 -0
- package/dist/headless.cjs +3 -1
- package/dist/headless.cjs.map +1 -1
- package/dist/headless.d.cts +5 -5
- package/dist/headless.d.ts +5 -5
- package/dist/headless.js +2 -2
- package/dist/health-DjZ2gwYa.d.cts +92 -0
- package/dist/health-DjZ2gwYa.d.ts +92 -0
- package/dist/http-BXys2d-j.d.ts +61 -0
- package/dist/http-zOI8d2c2.d.cts +61 -0
- package/dist/index.cjs +7 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts +1 -1
- package/dist/recorder.d.ts +1 -1
- package/dist/recorder.js +1 -1
- package/dist/types-Bkw8ErmO.d.cts +314 -0
- package/dist/types-Dy_uPu6S.d.ts +314 -0
- package/package.json +4 -4
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/agent-turns.ts","../src/health.ts","../src/http.ts","../src/storage.ts","../src/outbox.ts","../src/authoring.ts","../src/snapshot.ts","../src/tagging.ts","../src/autocapture.ts","../src/capture-token.ts","../src/load-capture.ts","../src/context.ts","../src/heatmap.ts","../src/errors.ts","../src/emitter.ts","../src/frequency.ts","../src/messenger-api.ts","../src/messenger-visitor.ts","../src/navigation.ts","../src/page-url.ts","../src/page-tracking.ts","../src/prototype-overlay.ts","../src/queue.ts","../src/load-recorder.ts"],"sourcesContent":["/**\n * @guidelytech/sdk-core — framework-independent Guidely browser SDK.\n *\n * SSR-safe to import: nothing touches `window` at module scope. Create a client in the browser\n * with {@link createGuidely} (or `Guidely.init` for script-tag installs).\n */\nimport { GuidelyClient, createGuidely, SDK_VERSION } from \"./client\";\n\nexport { GuidelyClient, createGuidely, SDK_NAME, SDK_VERSION, DEFAULT_API_URL } from \"./client\";\nexport type { GuidelyOptions, GuidelyEvents, GuidelyEventName, GuidelyUser, GuidelyAccount, GuidelyEnvironment, ConsentState, ChecklistProgressState, PersistedState, SessionState, GuideStepInfo } from \"./types\";\nexport { isFrequencyEligible, isExclusiveGuide, areMutuallyExclusive, isWithinSchedule, countsTowardThrottle, isThrottleEligible, pruneLaunches } from \"./frequency\";\nexport type { GuideLocalState } from \"./frequency\";\nexport { detectDevice, buildContext } from \"./context\";\nexport type { DeviceInfo, ContextInput } from \"./context\";\nexport { EventQueue } from \"./queue\";\nexport type { EventQueueOptions } from \"./queue\";\nexport { watchNavigation } from \"./navigation\";\nexport { normalizeAppUrl, isAppUrl } from \"./page-url\";\nexport { createStorage, KEYS } from \"./storage\";\nexport type { KeyValueStore, StorageKind } from \"./storage\";\nexport { AUTHORING_PARAM, HEARTBEAT_MS } from \"./authoring\";\nexport { captureSnapshot } from \"./snapshot\";\nexport type { AuthoringIncomingMessage, AuthoringOutgoingMessage } from \"./authoring\";\nexport { CAPTURE_PARAM } from \"./capture-token\";\nexport type { CaptureMarker } from \"./capture-token\";\nexport type { CaptureOutgoingMessage } from \"./capture\";\nexport type { AppSnapshot, PublishedGuide, SdkConfigResponse, SdkEvent, TargetingContext, GuideConfig, GuideStep, AutocaptureSettings, ExceptionProperties, StackFrame } from \"@guidelytech/shared\";\nexport type { ClickProperties } from \"./autocapture\";\nexport type { FlagsClient, FlagsClientOptions, FlagDetails, FlagsBootstrap, FlagsPayload, EvaluationResult, Attributes, JsonValue } from \"@guidelytech/flags\";\nexport type { PageLeaveInfo } from \"./page-tracking\";\nexport type { AgentTurnRedactor } from \"./agent-turns\";\nexport type { AgentTurnInput, AgentToolCallInput, AgentOutcome, AgentTurnRole, AgentEventsResponse } from \"@guidelytech/shared\";\nexport { matchPrototypeTestUrl, PROTOTYPE_CLOSE_MESSAGE } from \"./prototype-overlay\";\n\n/** Global-style API used by the script-tag embed: `Guidely.init(options)` / `Guidely.get()`. */\nexport const Guidely = {\n init: (options: Parameters<typeof GuidelyClient.init>[0]) => GuidelyClient.init(options),\n get: () => GuidelyClient.get(),\n createGuidely,\n version: SDK_VERSION,\n};\n\nexport default Guidely;\n","import { evaluateRules, localizeGuide, localizeResourceCenter, normalizeLocale, randomId, rolloutBucket, sanitizeProperties, supportsPlatform, visibleAnnouncements, visitorLocales, type ExceptionProperties } from \"@guidelytech/shared/runtime\";\nimport {\n type AutocaptureSettings,\n type ChecklistTask,\n type EventName,\n type IdentifyRequest,\n type IdentifyResponse,\n type PublishedGuide,\n type ResourceCenterArticle,\n type SdkConfigResponse,\n type SdkEvent,\n type TargetingContext,\n} from \"@guidelytech/shared\";\nimport {\n closestComposed,\n composedTarget,\n destroyHost,\n isChecklistComplete,\n renderChecklist,\n renderResourceCenter,\n renderSurvey,\n runGuide,\n urlMatches,\n waitForTarget,\n type ChecklistWidget,\n type GuideController,\n type ResourceCenterWidget,\n type SurveyWidget,\n} from \"@guidelytech/guide-runtime\";\nimport { createScope } from \"@guidelytech/guide-runtime\";\nimport { createFlagsClient, type Attributes, type EvaluationResult, type FlagDetails, type FlagValue, type FlagsClient, type JsonValue } from \"@guidelytech/flags\";\nimport type { MessengerTab, MessengerWidget } from \"@guidelytech/guide-runtime/messenger\";\nimport type { AgentTurnInput } from \"@guidelytech/shared/runtime\";\nimport { AgentTurns, prepareAgentTurn } from \"./agent-turns\";\nimport { AuthoringBridge } from \"./authoring\";\nimport type { CaptureBridge } from \"./capture\";\nimport { takeCaptureToken } from \"./capture-token\";\nimport { loadCapture } from \"./load-capture\";\nimport { DEFAULT_MASK_SELECTORS, describeClick, interactiveElement, isIgnoredElement, RageClickDetector, validSelectors } from \"./autocapture\";\nimport { buildContext, detectDevice } from \"./context\";\nimport { HeatmapBuffer, heatmapPoint, movementBin } from \"./heatmap\";\nimport { clickPropertyValues, elementSnapshot, featureAttributeOf, pagePropertyValues } from \"./tagging\";\nimport { errorEventToException, exceptionFromError, ExceptionThrottle, isGuidelyException, rejectionToException } from \"./errors\";\nimport { Emitter } from \"./emitter\";\nimport { areMutuallyExclusive, countsTowardThrottle, dismissedAfterMerge, isExclusiveGuide, isFrequencyEligible, isThrottleEligible, isWithinSchedule, pruneLaunches, type GuideLocalState } from \"./frequency\";\nimport { Api, postWithRetry } from \"./http\";\nimport { createMessengerTransport, forgetConversations } from \"./messenger-api\";\nimport { buildMessengerVisitor, plainText } from \"./messenger-visitor\";\nimport { watchNavigation } from \"./navigation\";\nimport { normalizeAppUrl } from \"./page-url\";\nimport { PageTracker } from \"./page-tracking\";\nimport { matchPrototypeTestUrl, openPrototypeOverlay } from \"./prototype-overlay\";\nimport { Outbox } from \"./outbox\";\nimport { EventQueue } from \"./queue\";\nimport { loadRecorder } from \"./load-recorder\";\nimport type { ReplayController, ReplayRecordingConfig } from \"./replay\";\nimport { createStorage, KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\nimport type { ChecklistProgressState, ConsentState, GuidelyAccount, GuidelyEvents, GuidelyOptions, GuidelyUser, PersistedState, SessionState } from \"./types\";\n\nexport const SDK_NAME = \"@guidelytech/sdk-core\";\nexport const SDK_VERSION = \"0.11.0\";\nexport const DEFAULT_API_URL = \"https://api.guidely.app\";\n\ntype EvalReason = \"ready\" | \"navigation\" | \"event\" | \"click\" | \"visible\" | \"identify\" | \"after_guide\" | \"timer\" | \"manual\";\ninterface EvalDetail {\n eventName?: string;\n target?: Element | null;\n guideId?: string;\n endedGuide?: PublishedGuide;\n newAudiences?: Set<string>;\n}\n\ninterface ActiveGuide {\n guide: PublishedGuide;\n controller?: GuideController;\n survey?: SurveyWidget;\n scope?: { destroy(): void };\n manual: boolean;\n startUrl: string;\n}\n\ninterface QueuedGuide {\n guide: PublishedGuide;\n url: string;\n pageScoped: boolean;\n}\n\nconst PAGE_SCOPED = new Set([\"page_load\", \"url_match\", \"element_click\", \"element_visible\", \"delay\"]);\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst MAX_SESSION_EXCEPTIONS = 100;\n/**\n * With a cached config, start from it when the server takes longer than this to answer (config or\n * identify): guides, the messenger and flags keep working through an outage, and the fresh answer\n * is applied when it arrives.\n */\nconst CACHED_START_MS = 1500;\n\n/** Resolves true when `promise` settles within `ms`, false otherwise (it keeps running either way). */\nfunction settlesWithin(promise: Promise<unknown>, ms: number): Promise<boolean> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), ms);\n const done = () => {\n clearTimeout(timer);\n resolve(true);\n };\n promise.then(done, done);\n });\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction emptyState(): PersistedState {\n return { guides: {}, checklists: {}, surveysSubmitted: [], audienceIds: [] };\n}\n\nfunction newSession(now = Date.now()): SessionState {\n return { id: `s_${randomId(16)}`, startedAt: new Date(now).toISOString(), shownGuides: [], events: [], lastActivityAt: now };\n}\n\n/**\n * Framework-independent Guidely client. Create one per page with {@link createGuidely} or\n * {@link GuidelyClient.init}; adapters (`@guidelytech/react`, `@guidelytech/svelte`) wrap it.\n */\nexport class GuidelyClient {\n readonly options: Readonly<Required<Pick<GuidelyOptions, \"projectId\" | \"environment\" | \"apiUrl\" | \"analytics\" | \"consent\" | \"storage\" | \"configRefreshMs\" | \"pollIntervalMs\" | \"debug\">>> & GuidelyOptions;\n private readonly api: Api;\n private readonly store: KeyValueStore;\n private readonly sessionStore: KeyValueStore;\n private readonly emitter: Emitter<GuidelyEvents>;\n private readonly queue: EventQueue;\n /** Survey answers and guide/checklist progress, kept until the server accepts them. */\n private readonly outbox: Outbox;\n /** Agent Analytics turns (agentConversation), in their own outbox. */\n private readonly agentTurns: AgentTurns;\n private config: SdkConfigResponse | null = null;\n private etag: string | null = null;\n private anonymousId: string;\n private user: GuidelyUser | null = null;\n private state: PersistedState;\n private session: SessionState;\n private consent: ConsentState;\n private readyPromise: Promise<void> | null = null;\n private resolveReady: (() => void) | null = null;\n private isReady = false;\n private destroyed = false;\n private active: ActiveGuide | null = null;\n private queued: QueuedGuide[] = [];\n private widgets = new Map<string, { destroy(): void; checklist?: ChecklistWidget; scope?: { destroy(): void }; controller?: GuideController; manual?: boolean }>();\n private resourceCenter: ResourceCenterWidget | null = null;\n private resourceCenterScope: { destroy(): void } | null = null;\n private messenger: MessengerWidget | null = null;\n private messengerScope: { destroy(): void } | null = null;\n private messengerLoading: Promise<MessengerWidget | null> | null = null;\n private cleanups: Array<() => void> = [];\n private timers = new Set<ReturnType<typeof setTimeout>>();\n private visibilityObservers = new Map<string, () => void>();\n private firedDelays = new Set<string>();\n private firstVisit: boolean;\n private lastUrl: string;\n private authoring: AuthoringBridge | null = null;\n private capture: CaptureBridge | null = null;\n /** A capture token was found and the (lazily loaded) capture bridge is starting. */\n private captureStarting = false;\n private lastAudiences = new Set<string>();\n /** Set once the app calls identify()/reset(); bootstrap then leaves identity alone instead of re-identifying. */\n private identitySettled = false;\n // Product analytics (autocapture, error tracking, session replay)\n /** Created once the recorder chunk has loaded (it carries the replay controller). */\n private replay: ReplayController | null = null;\n private replayLoading = false;\n private readonly pageTracker = new PageTracker();\n private readonly rage = new RageClickDetector();\n private readonly heatmap = new HeatmapBuffer();\n private readonly exceptionThrottle = new ExceptionThrottle();\n /** Exceptions seen before the config was loaded (reported once it is known whether the server accepts them). */\n private earlyExceptions: Array<[ExceptionProperties, Record<string, unknown> | undefined]> = [];\n private initialPageViewSent = false;\n private pageViewUrl: string | null = null;\n private pageLeft = false;\n /** Feature flags for this environment: `guidely.flags.isEnabled(\"new-checkout\")`. */\n readonly flags: FlagsClient;\n /** Experiments already reported this session (`experiment_viewed` is sent once per session). */\n private exposures = new Set<string>();\n /** Language set with `setLocale()`. */\n private locale: string | null = null;\n /** Language each shown guide was rendered in; added to its events as `locale`. */\n private guideLocales = new Map<string, string>();\n\n constructor(options: GuidelyOptions) {\n if (!isBrowser()) throw new Error(\"[Guidely] createGuidely() must be called in the browser. Create the client inside useEffect / onMount, or use the framework adapters.\");\n if (!options || !options.projectId) throw new Error(\"[Guidely] `projectId` (your environment public key, e.g. pk_dev_…) is required.\");\n this.options = {\n ...options,\n environment: options.environment ?? (options.projectId.startsWith(\"pk_prod\") ? \"production\" : options.projectId.startsWith(\"pk_stag\") ? \"staging\" : \"development\"),\n apiUrl: options.apiUrl ?? DEFAULT_API_URL,\n analytics: options.analytics ?? true,\n consent: options.consent ?? \"granted\",\n storage: options.storage ?? \"local\",\n configRefreshMs: options.configRefreshMs ?? 5 * 60 * 1000,\n pollIntervalMs: options.pollIntervalMs ?? 1000,\n debug: options.debug ?? false,\n };\n this.consent = this.options.consent;\n this.emitter = new Emitter<GuidelyEvents>((err) => this.reportError(err));\n this.api = new Api(this.options.apiUrl, this.options.projectId, options.fetch);\n this.store = createStorage(this.options.storage);\n this.sessionStore = this.options.storage === \"memory\" ? this.store : createStorage(\"session\");\n this.anonymousId = this.store.get(KEYS.anon) || \"\";\n if (!this.anonymousId) {\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n }\n this.firstVisit = !this.store.get(KEYS.seen);\n this.store.set(KEYS.seen, nowIso());\n this.state = { ...emptyState(), ...readJson<Partial<PersistedState>>(this.store, KEYS.state(this.options.projectId), {}) };\n this.user = readJson<GuidelyUser | null>(this.store, KEYS.user(this.options.projectId), null);\n const session = readJson<SessionState | null>(this.sessionStore, KEYS.session, null);\n this.session = session && session.id ? session : newSession();\n this.persistSession();\n this.lastUrl = this.pageHref();\n this.lastAudiences = new Set(this.state.audienceIds);\n this.queue = new EventQueue({\n store: this.store,\n storageKey: KEYS.queue(this.options.projectId),\n enabled: () => this.analyticsEnabled(),\n health: this.api.health,\n send: async (events) => {\n const res = await this.api.post<{ accepted: number }>(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }, { keepalive: true });\n return { ok: res.ok, retry: !(res.status >= 400 && res.status < 500 && res.status !== 429) };\n },\n beacon: (events) => this.api.beacon(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }),\n onError: (err) => this.reportError(err),\n });\n this.outbox = new Outbox({ api: this.api, store: this.store, storageKey: KEYS.outbox(this.options.projectId), health: this.api.health });\n this.agentTurns = new AgentTurns({ api: this.api, store: this.store, storageKey: KEYS.agentOutbox(this.options.projectId), health: this.api.health, sdk: { name: SDK_NAME, version: SDK_VERSION } });\n if (options.user) this.user = { ...options.user };\n this.flags = this.createFlags(options.flags);\n }\n\n private createFlags(opts: GuidelyOptions[\"flags\"]): FlagsClient {\n const base = { sdkKey: this.options.projectId, apiUrl: this.options.apiUrl, fetch: this.options.fetch, sdk: { name: SDK_NAME, version: SDK_VERSION } };\n // Disabled: a client that never fetches and serves fallbacks, so `guidely.flags` is always usable.\n if (opts === false) return createFlagsClient({ ...base, overrideBehaviour: \"localOnly\", offline: true, reportUsage: false, trackExposures: false, storage: false, logger: null });\n const o = opts ?? {};\n return createFlagsClient({\n ...base,\n storage: { getItem: (k) => this.store.get(k), setItem: (k, v) => this.store.set(k, v), removeItem: (k) => this.store.remove(k) },\n reportUsage: this.options.analytics,\n // Failures surface through onError (and `debug` logs); development warnings (unknown flag keys) reach the console.\n logger: { warn: (...a: unknown[]) => console.warn(\"[Guidely]\", ...a), error: (...a: unknown[]) => this.log(...a) },\n ...o,\n contextAttributes: this.flagContext(),\n // Exposures travel through the event pipeline (with the session) as `experiment_viewed`.\n trackExposures: false,\n onFlagEvaluated: (result) => {\n this.trackExposure(result);\n o.onFlagEvaluated?.(result);\n },\n onReady: () => {\n this.emitter.emit(\"flags:ready\");\n o.onReady?.();\n },\n onChange: (data) => {\n this.emitter.emit(\"flags:change\");\n o.onChange?.(data);\n },\n onError: (err) => {\n this.reportError(err);\n o.onError?.(err);\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /** Loads config (cache first, then network), wires listeners and evaluates triggers. Idempotent. */\n init(): Promise<void> {\n if (this.readyPromise) return this.readyPromise;\n this.readyPromise = new Promise<void>((resolve) => {\n this.resolveReady = resolve;\n });\n void this.bootstrap();\n return this.readyPromise;\n }\n\n /** Resolves once the client is ready (alias of `init()`). */\n ready(): Promise<void> {\n return this.init();\n }\n\n private async bootstrap(): Promise<void> {\n this.wireErrorListeners();\n try {\n const cached = readJson<SdkConfigResponse | null>(this.store, KEYS.config(this.options.projectId), null);\n this.etag = this.store.get(KEYS.etag(this.options.projectId));\n if (cached && cached.guides) this.config = webOnly(cached);\n const before = this.config?.configVersion;\n const fresh = this.fetchConfig();\n // With a cached config a slow or unreachable server doesn't hold guides back: start from the\n // cache and apply the fresh config when it lands. Without one there is nothing to show yet.\n if (!this.config) await fresh;\n else if (!(await settlesWithin(fresh, CACHED_START_MS))) void fresh.then(() => this.applyConfigChange(before));\n if (this.destroyed) return;\n this.wireListeners();\n if (!this.identitySettled) {\n // identify() re-evaluates guides when it completes, so a slow answer is applied later too.\n const known = this.options.user ?? (this.user?.id ? this.user : null);\n if (known) await settlesWithin(this.identify(known.id, known.traits, known.account), CACHED_START_MS);\n }\n if (this.destroyed) return;\n this.isReady = true;\n if (this.config) this.emitter.emit(\"ready\", this.config);\n this.resolveReady?.();\n // Capture is detected before anything renders, so guides and widgets never appear in its screenshots.\n const capturing = !this.options.disableAuthoring && this.maybeStartCapture();\n this.renderPersistentWidgets();\n this.resumeActiveGuide();\n this.evaluate(\"ready\");\n if (!this.options.disableAuthoring && !capturing) this.maybeStartAuthoring();\n this.pageTracker.start(this.pageHref());\n this.touchSession(); // a page load is activity: rotate an expired session before capture starts\n this.syncCapture();\n } catch (err) {\n this.reportError(err);\n this.isReady = true;\n this.resolveReady?.();\n }\n }\n\n private async fetchConfig(): Promise<boolean> {\n try {\n const res = await this.api.get<SdkConfigResponse>(\"/config\", { etag: this.etag, params: { platform: \"web\" } });\n if (res.status === 304) return true;\n if (res.ok && res.data && Array.isArray(res.data.guides)) {\n this.config = webOnly(res.data);\n this.etag = res.etag;\n writeJson(this.store, KEYS.config(this.options.projectId), res.data);\n if (res.etag) this.store.set(KEYS.etag(this.options.projectId), res.etag);\n else this.store.remove(KEYS.etag(this.options.projectId));\n this.emitter.emit(\"config\", res.data);\n this.log(\"config loaded\", res.data.configVersion, `${res.data.guides.length} guides`);\n return true;\n }\n this.reportError(new Error(`[Guidely] config request failed (${res.status})${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n } catch (err) {\n this.reportError(new Error(`[Guidely] config request failed: ${err instanceof Error ? err.message : String(err)}${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n }\n }\n\n private wireListeners(): void {\n const doc = document;\n const win = window;\n this.cleanups.push(watchNavigation((url) => this.handleNavigation(this.pageHref(url))));\n const onClick = (e: Event) => this.handleDocumentClick(e);\n doc.addEventListener(\"click\", onClick, true);\n this.cleanups.push(() => doc.removeEventListener(\"click\", onClick, true));\n const onVisibility = () => {\n const hidden = doc.visibilityState === \"hidden\";\n this.pageTracker.setHidden(hidden);\n if (!hidden) return;\n this.replay?.flushOnHide();\n this.queue.flushSync();\n };\n const onPageHide = () => {\n this.flushHeatmap();\n if (!this.pageLeft) this.leavePage(null);\n this.pageLeft = true;\n this.replay?.flushOnHide();\n this.queue.flushSync();\n };\n const onPageShow = (e: PageTransitionEvent) => {\n if (!e.persisted || !this.pageLeft) return;\n this.pageLeft = false;\n this.pageTracker.start(this.pageHref());\n };\n // Activity keeps the session alive (and rotates it after the inactivity timeout).\n let lastScroll = 0;\n const onScroll = () => {\n const now = Date.now();\n if (now - lastScroll < 250) return;\n lastScroll = now;\n this.pageTracker.measureScroll();\n this.touchSession();\n };\n const onKey = () => this.touchSession();\n // Mouse-movement heatmap: one sample (the latest position) per 200ms while the pointer moves; fine pointers only.\n let move: MouseEvent | null = null;\n let moveTimer: ReturnType<typeof setTimeout> | null = null;\n const onMove = (e: MouseEvent) => {\n move = e;\n moveTimer ??= setTimeout(() => {\n moveTimer = null;\n if (move) this.sampleMove(move);\n move = null;\n }, 200);\n };\n if (win.matchMedia?.(\"(pointer: fine)\").matches) {\n doc.addEventListener(\"mousemove\", onMove, { passive: true });\n this.cleanups.push(() => {\n doc.removeEventListener(\"mousemove\", onMove);\n if (moveTimer) clearTimeout(moveTimer);\n });\n }\n doc.addEventListener(\"visibilitychange\", onVisibility);\n win.addEventListener(\"pagehide\", onPageHide);\n win.addEventListener(\"pageshow\", onPageShow);\n win.addEventListener(\"scroll\", onScroll, { passive: true });\n doc.addEventListener(\"keydown\", onKey, true);\n this.cleanups.push(() => {\n doc.removeEventListener(\"visibilitychange\", onVisibility);\n win.removeEventListener(\"pagehide\", onPageHide);\n win.removeEventListener(\"pageshow\", onPageShow);\n win.removeEventListener(\"scroll\", onScroll);\n doc.removeEventListener(\"keydown\", onKey, true);\n });\n // Skipped while the API's circuit is open; the cached config keeps serving meanwhile.\n const refresh = setInterval(() => {\n if (this.api.health.canSend()) void this.refresh();\n }, this.options.configRefreshMs);\n // Back online: queued events, answers and recordings retry at once (see ServerHealth).\n const onOnline = () => this.api.health.online();\n win.addEventListener(\"online\", onOnline);\n this.cleanups.push(() => win.removeEventListener(\"online\", onOnline));\n this.cleanups.push(() => clearInterval(refresh));\n // Idle re-check: DOM can change without navigation (lazy content), so re-arm element-visibility\n // observers for eligible guides and drain the queue.\n const poll = setInterval(() => {\n if (!this.isReady || !this.config || this.editing() || doc.visibilityState === \"hidden\") return;\n const url = this.pageHref();\n const ctx = this.getContext();\n for (const guide of this.config.guides) {\n if (guide.config.trigger.type === \"element_visible\" && guide.config.trigger.value) this.armVisibility(guide, ctx, url);\n }\n this.drainQueue(url, ctx);\n }, Math.max(250, this.options.pollIntervalMs));\n this.cleanups.push(() => clearInterval(poll));\n const onMessage = (e: MessageEvent) => this.authoring?.handleMessage(e);\n win.addEventListener(\"message\", onMessage);\n this.cleanups.push(() => win.removeEventListener(\"message\", onMessage));\n }\n\n /** Uncaught errors + unhandled rejections; attached before the config loads so boot errors are kept. */\n private wireErrorListeners(): void {\n const win = window;\n const onError = (e: ErrorEvent) => this.captureGlobalException(errorEventToException(e));\n const onRejection = (e: PromiseRejectionEvent) => this.captureGlobalException(rejectionToException(e));\n win.addEventListener(\"error\", onError);\n win.addEventListener(\"unhandledrejection\", onRejection);\n this.cleanups.push(() => {\n win.removeEventListener(\"error\", onError);\n win.removeEventListener(\"unhandledrejection\", onRejection);\n });\n }\n\n /** Re-fetches the published config and re-evaluates triggers. */\n async refresh(): Promise<void> {\n if (this.destroyed) return;\n const before = this.config?.configVersion;\n await this.fetchConfig();\n this.applyConfigChange(before);\n }\n\n /** Re-renders after a config change (refresh, or a config that arrived after start). */\n private applyConfigChange(before: number | undefined): void {\n if (this.destroyed || !this.isReady) return;\n if (this.config && this.config.configVersion !== before) {\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n }\n this.syncCapture();\n }\n\n /** Tears everything down: guides, widgets, listeners, timers, host element. Re-init is allowed via a new client. */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.active?.controller?.destroy();\n this.active?.survey?.destroy();\n this.active?.scope?.destroy();\n this.active = null;\n this.queued = [];\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n this.resourceCenter?.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.destroyMessenger();\n this.visibilityObservers.forEach((stop) => stop());\n this.visibilityObservers.clear();\n this.timers.forEach((t) => clearTimeout(t));\n this.timers.clear();\n this.cleanups.splice(0).forEach((fn) => fn());\n this.authoring?.stop();\n this.authoring = null;\n this.capture?.destroy();\n this.capture = null;\n this.replay?.destroy();\n this.replay = null;\n this.queue.flushSync();\n this.queue.destroy();\n this.outbox.destroy();\n this.agentTurns.destroy();\n this.flags.destroy();\n this.emitter.clear();\n destroyHost();\n if (current === this) current = null;\n }\n\n // ---------------------------------------------------------------------------\n // Identity\n // ---------------------------------------------------------------------------\n\n /** Identifies the end user and loads server-held state (audiences, guide history, checklist progress). */\n async identify(userId: string, traits?: Record<string, unknown>, account?: GuidelyAccount): Promise<void> {\n if (this.destroyed) return;\n this.identitySettled = true;\n this.user = { id: String(userId), traits: { ...(this.user?.id === String(userId) ? this.user.traits : {}), ...(traits || {}) }, account: account ?? (this.user?.id === String(userId) ? this.user.account : undefined) };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n this.syncFlagAttributes();\n this.enqueue(\"identify\", { properties: { traits: sanitizeProperties(this.user.traits) } });\n await this.syncIdentify();\n this.emitter.emit(\"identify\", { userId: this.user.id, anonymousId: this.anonymousId });\n if (this.isReady) this.evaluate(\"identify\");\n }\n\n private async syncIdentify(): Promise<void> {\n const body: IdentifyRequest = { anonymousId: this.anonymousId, userId: this.user?.id ?? null, traits: this.user?.traits, account: this.user?.account ? { id: this.user.account.id, traits: this.user.account.traits } : null, sessionId: this.session.id, url: this.collectUrls() ? this.pageHref() : undefined };\n const res = await postWithRetry<IdentifyResponse>(this.api, \"/identify\", body, 2);\n if (res?.ok && res.data) this.mergeServerState(res.data);\n }\n\n private mergeServerState(data: IdentifyResponse): void {\n const guides = { ...this.state.guides };\n for (const [id, s] of Object.entries(data.guideState || {})) {\n const local = guides[id];\n guides[id] = {\n ...local,\n impressions: Math.max(local?.impressions ?? 0, s.impressions ?? 0),\n completedAt: local?.completedAt ?? s.completedAt ?? null,\n dismissedAt: local?.dismissedAt ?? s.dismissedAt ?? null,\n lastShownAt: local?.lastShownAt ?? s.lastShownAt ?? null,\n };\n }\n const checklists = { ...this.state.checklists };\n for (const [id, p] of Object.entries(data.checklistProgress || {})) {\n const local = checklists[id];\n checklists[id] = {\n completedTaskIds: Array.from(new Set([...(local?.completedTaskIds ?? []), ...(p.completedTaskIds ?? [])])),\n completedAt: local?.completedAt ?? p.completedAt ?? null,\n dismissedAt: dismissedAfterMerge(local, p),\n dismissResetAt: p.dismissResetAt ?? local?.dismissResetAt ?? null,\n };\n }\n this.state = {\n guides,\n checklists,\n surveysSubmitted: Array.from(new Set([...this.state.surveysSubmitted, ...(data.surveysSubmitted || [])])),\n audienceIds: data.audienceIds || [],\n firstSeenAt: this.state.firstSeenAt ?? data.firstSeenAt,\n // Device-local only (the server doesn't hold them).\n ...(this.state.throttle ? { throttle: this.state.throttle } : {}),\n ...(this.state.announcementsSeenAt ? { announcementsSeenAt: this.state.announcementsSeenAt } : {}),\n };\n if (data.firstSeenAt && Date.now() - Date.parse(data.firstSeenAt) > 60_000) this.firstVisit = false;\n this.persistState();\n this.syncFlagAttributes(); // audiences\n this.widgets.forEach((w, id) => {\n const g = this.findGuide(id);\n if (w.checklist && g) w.checklist.setProgress(this.getChecklistProgress(g.id));\n });\n // Name, audiences and progress may have changed.\n this.messenger?.refresh();\n }\n\n /** Sets or replaces the account (company/organisation) for the current user. */\n async setAccount(account: GuidelyAccount): Promise<void> {\n if (!this.user) {\n this.user = { id: \"\", account };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n this.syncFlagAttributes();\n return;\n }\n await this.identify(this.user.id, undefined, account);\n }\n\n /** Merges additional traits into the current user. */\n async updateTraits(traits: Record<string, unknown>): Promise<void> {\n if (!this.user?.id) {\n this.user = { id: \"\", traits: { ...(this.user?.traits || {}), ...traits } };\n this.syncFlagAttributes();\n return;\n }\n await this.identify(this.user.id, traits, this.user.account);\n }\n\n /** Forgets the user: new anonymous id, cleared local guide/checklist state, triggers re-evaluated. */\n reset(): void {\n this.identitySettled = true;\n this.stopGuide();\n this.user = null;\n this.store.remove(KEYS.user(this.options.projectId));\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n this.state = emptyState();\n this.persistState();\n this.session = newSession();\n this.persistSession();\n this.sessionStore.remove(KEYS.active);\n this.replay?.stop(); // the recording belongs to the previous user; restarted below when eligible\n this.syncCapture();\n this.lastAudiences = new Set();\n this.firedDelays.clear();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n // Conversations belong to the previous user: forget their tokens and rebuild the messenger.\n forgetConversations(this.store, this.options.projectId);\n this.destroyMessenger();\n this.exposures.clear();\n this.syncFlagAttributes();\n this.emitter.emit(\"identify\", { userId: null, anonymousId: this.anonymousId });\n if (this.isReady) {\n this.renderPersistentWidgets();\n this.evaluate(\"identify\");\n }\n }\n\n // ---------------------------------------------------------------------------\n // Events\n // ---------------------------------------------------------------------------\n\n /** Updates consent at runtime (`granted` flushes buffered events; `denied` drops them). */\n setConsent(consent: ConsentState): void {\n this.consent = consent;\n if (consent === \"denied\") this.queue.clear();\n else if (consent === \"granted\") void this.queue.flush();\n if (consent !== \"granted\") this.replay?.stop({ discard: true });\n if (consent !== \"pending\") this.agentTurns.consentChanged(consent === \"granted\");\n this.syncCapture();\n }\n\n private analyticsEnabled(): boolean {\n return this.options.analytics && this.consent === \"granted\" && (this.config?.settings?.analyticsEnabled ?? true);\n }\n\n private collectUrls(): boolean {\n return this.config?.settings?.collectUrls ?? true;\n }\n\n private enqueue(name: EventName, extra: Partial<SdkEvent> = {}): SdkEvent | null {\n if (this.consent === \"denied\" || !this.options.analytics) return null;\n if (name !== \"page_leave\" && name !== \"heatmap\") this.touchSession();\n const event: SdkEvent = {\n eventId: randomId(24),\n name,\n occurredAt: nowIso(),\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n accountId: this.user?.account?.id || null,\n sessionId: this.session.id,\n url: this.collectUrls() ? this.pageHref() : undefined,\n ...extra,\n };\n if (extra.properties) event.properties = sanitizeProperties(extra.properties);\n const locale = extra.guideId ? this.guideLocales.get(extra.guideId) : undefined;\n if (locale) event.properties = { ...(event.properties ?? {}), locale };\n this.queue.enqueue(event);\n this.replay?.addCustomEvent(\"guidely\", { name, customName: event.customName, guideId: event.guideId });\n this.emitter.emit(\"track\", event);\n return event;\n }\n\n /** Tracks a custom event. Events drive `event` triggers, `advanceOn: \"event\"` steps and checklist tasks. */\n track(name: string, properties?: Record<string, unknown>): void {\n if (this.destroyed || !name) return;\n if (!this.session.events.includes(name)) {\n this.session.events.push(name);\n this.persistSession();\n }\n this.enqueue(\"custom\", { customName: name.slice(0, 120), properties: properties ?? {} });\n this.customListeners.get(name)?.forEach((cb) => {\n try {\n cb();\n } catch (err) {\n this.reportError(err);\n }\n });\n this.completeChecklistTasksBy(\"event\", name);\n if (this.isReady) this.evaluate(\"event\", { eventName: name });\n }\n\n /**\n * Agent Analytics: records one or more turns of a conversation with your own AI agent or chatbot\n * (`{ conversationId, agentId, role, text, toolCalls?, latencyMs?, outcome?, … }`). The visitor's\n * anonymous id, user id, account id and session id are filled in, `agents.redact` from the init\n * options runs on each turn, and turns are retried until Guidely accepts them. Returns false when\n * nothing was queued (analytics off or consent denied, or every turn was invalid or dropped).\n */\n agentConversation(turns: AgentTurnInput | AgentTurnInput[]): boolean {\n if (this.destroyed || !this.options.analytics || this.consent === \"denied\" || this.config?.settings?.analyticsEnabled === false) return false;\n const identity = { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, sessionId: this.session.id };\n const prepared = (Array.isArray(turns) ? turns : [turns]).map((t) => prepareAgentTurn(t, identity, this.options.agents?.redact, (err) => this.reportError(err))).filter((t): t is AgentTurnInput => !!t);\n if (!prepared.length) return false;\n this.touchSession();\n this.agentTurns.add(prepared, this.consent === \"pending\");\n return true;\n }\n\n /** Alias of {@link agentConversation}. */\n trackAgentTurn(turns: AgentTurnInput | AgentTurnInput[]): boolean {\n return this.agentConversation(turns);\n }\n\n /** Records a page view and re-evaluates triggers. Called automatically on SPA navigation. */\n page(href?: string): void {\n if (this.destroyed) return;\n const url = this.pageHref(href);\n this.leavePage(url);\n this.trackPageView(url);\n this.handleNavigation(url, true);\n }\n\n private readonly customListeners = new Map<string, Set<() => void>>();\n private readonly eventBus = {\n on: (name: string, cb: () => void) => {\n let set = this.customListeners.get(name);\n if (!set) {\n set = new Set();\n this.customListeners.set(name, set);\n }\n set.add(cb);\n return () => {\n set?.delete(cb);\n };\n },\n };\n\n private handleNavigation(url: string, explicit = false): void {\n if (this.destroyed) return;\n const changed = url !== this.lastUrl;\n this.lastUrl = url;\n if (changed) this.syncFlagAttributes();\n if (!explicit && changed) {\n this.leavePage(url);\n this.trackPageView(url);\n }\n this.completeChecklistTasksBy(\"url_visited\", url);\n this.active?.controller?.resume();\n if (this.active?.controller) {\n const st = this.active.controller.getState();\n if (st.status === \"running\" && !this.active.manual) {\n const g = this.active.guide;\n if (g.config.urlPatterns.length && !g.config.urlPatterns.some((p) => urlMatches(p, url))) this.active.controller.destroy();\n }\n }\n // Banners and hotspots are page-scoped too: close the ones whose URL patterns no longer match.\n this.widgets.forEach((w, id) => {\n if (!w.controller || w.manual) return;\n const g = this.findGuide(id);\n if (g?.config.urlPatterns.length && !g.config.urlPatterns.some((p) => urlMatches(p, url))) w.controller.destroy();\n });\n this.firedDelays.clear();\n if (this.isReady) this.evaluate(\"navigation\");\n if (changed) this.messenger?.refresh();\n if (changed) void this.queue.flush();\n }\n\n private handleDocumentClick(e: Event): void {\n const target = composedTarget(e);\n if (!target || typeof target.closest !== \"function\") return;\n this.autocaptureClick(e as MouseEvent, target);\n this.completeChecklistTasksBy(\"click\", target);\n if (this.isReady) this.evaluate(\"click\", { target });\n }\n\n // ---------------------------------------------------------------------------\n // Product analytics: sessions, page views, clicks, errors, session replay\n // ---------------------------------------------------------------------------\n\n /** Records activity; starts a new session after `sessionTimeoutMinutes` of inactivity or 24h. */\n private touchSession(): void {\n const now = Date.now();\n const s = this.session;\n const timeout = Math.max(1, this.config?.settings?.sessionTimeoutMinutes ?? 30) * 60_000;\n const last = s.lastActivityAt ?? now;\n if (now - last > timeout || now - (Date.parse(s.startedAt) || now) > DAY_MS) return this.rotateSession(now);\n if (now - (s.lastActivityAt ?? 0) < 1000) return;\n s.lastActivityAt = now;\n this.persistSession();\n }\n\n private rotateSession(now: number): void {\n this.session = newSession(now);\n this.persistSession();\n this.log(\"session rotated\", this.session.id);\n if (this.replay?.activeSessionId) this.replay.stop();\n this.syncReplay();\n }\n\n /** Autocapture, error tracking and replay need analytics on, consent granted and no authoring or how-to capture session. */\n private captureAllowed(): boolean {\n return !this.destroyed && this.analyticsEnabled() && !this.editing();\n }\n\n /** Authoring or how-to capture is running: no guides, widgets, replay or autocapture. */\n private editing(): boolean {\n return !!this.authoring?.isActive() || this.captureStarting || !!this.capture?.isActive();\n }\n\n /** A capability is on when the project enables it (absent on old servers → off) and no option turns it off. */\n private autocaptureOn(key: keyof AutocaptureSettings): boolean {\n const o = this.options.autocapture;\n return !!this.config?.settings?.autocapture?.[key] && o !== false && !(typeof o === \"object\" && o[key] === false) && this.captureAllowed();\n }\n\n /** Page views on SPA navigation predate autocapture: only an explicit opt-out stops them. */\n private pageviewsOn(): boolean {\n const o = this.options.autocapture;\n return this.config?.settings?.autocapture?.pageviews !== false && o !== false && !(typeof o === \"object\" && o.pageviews === false) && !this.editing();\n }\n\n private trackPageView(url: string): void {\n if (url === this.pageViewUrl || !this.pageviewsOn()) return;\n this.pageViewUrl = url;\n this.touchSession();\n const collect = this.collectUrls();\n const device = detectDevice(navigator.userAgent, window.innerWidth);\n const props: Record<string, unknown> = { deviceType: device.type, browser: device.browser, os: device.os, screenWidth: window.screen?.width, viewportWidth: window.innerWidth };\n if (collect) {\n props.path = pathOf(url);\n props.title = (document.title || \"\").slice(0, 200);\n const ref = !this.session.pageViews ? externalReferrer() : undefined;\n if (ref) props.referrer = ref;\n }\n const ep = this.captureAllowed() ? pagePropertyValues(this.config?.tagging, url, { mask: this.maskSelector(), maskAll: this.maskAllText() }) : undefined;\n if (ep) props.ep = ep;\n this.session.pageViews = (this.session.pageViews ?? 0) + 1;\n this.persistSession();\n this.enqueue(\"page_view\", { url: collect ? url : undefined, properties: props });\n }\n\n /** Emits `page_leave` for the page being left and starts measuring `nextUrl` (null: page unload). */\n private leavePage(nextUrl: string | null): void {\n const t = this.pageTracker;\n if (!t.url || t.url === nextUrl) return;\n this.flushHeatmap();\n if (!this.pageLeft && this.autocaptureOn(\"pageLeave\")) {\n const info = t.leave();\n const collect = this.collectUrls();\n this.enqueue(\"page_leave\", { url: collect ? info.url : undefined, properties: { ...(collect ? { path: pathOf(info.url) } : {}), durationMs: info.durationMs, scrollDepth: info.scrollDepth } });\n }\n if (nextUrl !== null) {\n t.start(nextUrl);\n this.pageLeft = false;\n }\n }\n\n private autocaptureClick(e: MouseEvent, target: Element): void {\n const clicks = this.autocaptureOn(\"clicks\");\n const rage = this.autocaptureOn(\"rageClicks\");\n const heat = this.autocaptureOn(\"heatmaps\");\n if ((!clicks && !rage && !heat) || isIgnoredElement(target)) return;\n this.touchSession();\n // An element carrying the feature attribute (or inside one) counts as clicked even when not interactive.\n const featureAttribute = this.config?.tagging?.featureAttribute ?? null;\n const feature = featureAttributeOf(target, featureAttribute);\n const el = interactiveElement(target) ?? feature?.el ?? null;\n const opts = { mask: this.maskSelector(), maskAll: this.maskAllText(), collectUrls: this.collectUrls() };\n const clickProps = (on: Element) => {\n const p = describeClick(on, e, opts);\n const ep = clickPropertyValues(this.config?.tagging, on, p, opts);\n return { ...p, el: elementSnapshot(on, { ...opts, featureAttribute }), ...(feature ? { fa: feature.value } : {}), ...(ep ? { ep } : {}) };\n };\n if (clicks && el) this.enqueue(\"click\", { properties: clickProps(el) });\n const count = this.rage.add(e.pageX ?? 0, e.pageY ?? 0, Date.now());\n if (rage && count) this.enqueue(\"rage_click\", { properties: { ...clickProps(el ?? target), count } });\n if (!heat) return;\n const url = this.pageHref();\n if (this.heatmap.url !== url) this.flushHeatmap();\n if (this.heatmap.add(url, heatmapPoint(el ?? target, e, this.rage.burst > 0), this.rage.burst)) this.flushHeatmap();\n }\n\n /** Bins one pointer sample into the heatmap buffer. Not session activity. */\n private sampleMove(e: MouseEvent): void {\n const target = composedTarget(e);\n if (document.visibilityState === \"hidden\" || !target?.closest || !this.autocaptureOn(\"mouseMovement\") || isIgnoredElement(target)) return;\n const url = this.pageHref();\n if (this.heatmap.url !== url) this.flushHeatmap();\n if (this.heatmap.move(url, movementBin(interactiveElement(target) ?? target, e))) this.flushHeatmap();\n }\n\n /** Sends the buffered heatmap clicks as one `heatmap` event attributed to the page they happened on. */\n private flushHeatmap(): void {\n const batch = this.heatmap.take();\n if (!batch || !this.captureAllowed()) return;\n const collect = this.collectUrls();\n const de = document.documentElement;\n const properties = { path: collect ? pathOf(batch.url) : undefined, viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, pageHeight: Math.max(de.scrollHeight, document.body?.scrollHeight || 0), points: batch.points };\n if (!collect) delete properties.path;\n this.enqueue(\"heatmap\", { url: collect ? batch.url : undefined, properties });\n }\n\n private captureGlobalException(props: ExceptionProperties | null): void {\n if (!props || isGuidelyException(props) || this.options.captureErrors === false) return;\n if (!this.config) {\n if (this.earlyExceptions.length < 10) this.earlyExceptions.push([props, undefined]);\n return;\n }\n this.sendException(props);\n }\n\n /**\n * Reports a caught error as an `exception` event (`source: \"manual\"`, `handled: true`), grouped\n * into an issue on the Errors page. Extra properties are attached to the occurrence. Needs the\n * project's error tracking on (plus analytics + consent); `captureErrors: false` does not stop it.\n */\n captureException(error: unknown, properties?: Record<string, unknown>): void {\n if (this.destroyed) return;\n const props = exceptionFromError(error, \"manual\", true);\n if (!this.config) {\n if (this.earlyExceptions.length < 10) this.earlyExceptions.push([props, properties]);\n return;\n }\n this.sendException(props, properties);\n }\n\n private sendException(props: ExceptionProperties, extra?: Record<string, unknown>): void {\n // Error tracking off (or a server that predates it and would reject the event): nothing is sent.\n if (!this.config?.settings?.errorTracking?.enabled || !this.captureAllowed() || !this.exceptionThrottle.allow(props)) return;\n const count = this.session.exceptions ?? 0;\n if (count >= MAX_SESSION_EXCEPTIONS) return;\n const properties: Record<string, unknown> = { ...props };\n if (this.options.release) properties.release = String(this.options.release).slice(0, 100);\n for (const [k, v] of Object.entries(extra ?? {})) if (!(k in properties)) properties[k] = v;\n this.enqueue(\"exception\", { properties });\n this.session.exceptions = count + 1;\n this.persistSession();\n }\n\n private maskSelector(): string {\n return validSelectors([...DEFAULT_MASK_SELECTORS, ...(this.config?.settings?.maskSelectors || []), ...(this.options.maskSelectors || [])]).join(\",\");\n }\n\n private maskAllText(): boolean {\n const o = this.options.sessionReplay;\n return !!this.config?.settings?.replay?.maskAllText || (typeof o === \"object\" && !!o.maskAllText);\n }\n\n /** Replay settings for this installation, or null when the project (or an option) disables replay. */\n private replayConfig(): { sampleRate: number; config: ReplayRecordingConfig } | null {\n const r = this.config?.settings?.replay;\n const o = this.options.sessionReplay;\n if (!r?.enabled || o === false) return null;\n const opt = typeof o === \"object\" ? o : {};\n const extra = opt.blockSelectors || [];\n return {\n sampleRate: r.sampleRate ?? 100,\n config: {\n recordConsole: r.recordConsole !== false,\n maskTextSelector: this.maskAllText() ? \"*\" : this.maskSelector(),\n blockSelector: validSelectors([\"[data-guidely-block]\", ...(r.blockSelectors || []), ...extra]).join(\",\"),\n network: r.recordNetwork && opt.recordNetwork !== false ? { payloads: !!r.recordNetworkPayloads && opt.recordNetworkPayloads !== false, apiUrl: this.options.apiUrl, mask: opt.maskNetworkRequest } : null,\n },\n };\n }\n\n /** Reconciles capture with the current config / consent / authoring state. Idempotent. */\n private syncCapture(): void {\n if (!this.isReady || this.destroyed) return;\n if (this.config && !this.initialPageViewSent && this.config.settings?.autocapture) {\n this.initialPageViewSent = true;\n this.trackPageView(this.pageHref());\n }\n if (this.config) {\n for (const [props, extra] of this.earlyExceptions.splice(0)) {\n if (props.handled) this.sendException(props, extra);\n else this.captureGlobalException(props);\n }\n }\n this.syncReplay();\n }\n\n private syncReplay(): void {\n const cfg = this.isReady && this.captureAllowed() ? this.replayConfig() : null;\n if (cfg && this.session.replay === undefined) {\n this.session.replay = rolloutBucket(this.session.id, \"replay\") < cfg.sampleRate;\n this.persistSession();\n }\n if (!cfg || !this.session.replay) {\n if (this.replay?.activeSessionId) this.replay.stop({ discard: !this.analyticsEnabled() });\n return;\n }\n if (this.replay) return this.replay.start(this.session.id, cfg.config);\n if (this.replayLoading) return;\n this.replayLoading = true;\n loadRecorder().then(\n (api) => {\n this.replayLoading = false;\n if (this.destroyed || this.replay) return;\n this.replay = api.createReplay({\n url: (params) => this.api.url(\"/replay\", params),\n fetch: () => this.options.fetch ?? (typeof fetch === \"function\" ? fetch.bind(globalThis) : null),\n meta: () => {\n const device = detectDevice(navigator.userAgent, window.innerWidth);\n return {\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n url: this.collectUrls() ? this.pageHref() : undefined,\n device: { type: device.type, browser: device.browser, os: device.os },\n viewport: { width: window.innerWidth, height: window.innerHeight },\n sdk: { name: SDK_NAME, version: SDK_VERSION },\n };\n },\n onDisabled: (sessionId) => {\n if (sessionId !== this.session.id) return;\n this.session.replay = false;\n this.persistSession();\n this.replay?.stop({ discard: true });\n },\n onError: (err) => this.reportError(err),\n health: this.api.health,\n stash: this.sessionStore,\n });\n this.syncReplay(); // re-decide: consent, session or settings may have changed while loading\n },\n (err) => {\n this.replayLoading = false;\n this.reportError(err);\n },\n );\n }\n\n /**\n * Records this session even when it was not sampled, provided the project has session replay\n * enabled (and analytics + consent allow it). The decision sticks for the rest of the session.\n */\n startSessionRecording(): void {\n if (this.destroyed) return;\n this.session.replay = true;\n this.persistSession();\n this.syncReplay();\n }\n\n /** Stops recording for the rest of this session (what was recorded so far is uploaded). */\n stopSessionRecording(): void {\n this.session.replay = false;\n this.persistSession();\n this.replay?.stop();\n }\n\n /** True while the session is being recorded. */\n isRecording(): boolean {\n return !!this.replay?.isRecording();\n }\n\n /** The current analytics session id (rotates after inactivity; also the replay id). */\n getSessionId(): string {\n return this.session.id;\n }\n\n // ---------------------------------------------------------------------------\n // Targeting + triggers\n // ---------------------------------------------------------------------------\n\n /** The page URL Guidely works with: `options.pageUrl`, else app-relative for `file:` / custom protocols (`normalizeAppUrl`). */\n pageHref(href: string = location.href): string {\n try {\n return this.options.pageUrl ? this.options.pageUrl(href) || href : normalizeAppUrl(href);\n } catch {\n return href;\n }\n }\n\n /** Builds the targeting context for the current moment. */\n getContext(): TargetingContext {\n const guides = this.state.guides;\n const completedChecklists = Object.entries(this.state.checklists).filter(([, p]) => !!p.completedAt).map(([id]) => id);\n const keysOf = (ids: string[]) => ids.flatMap((id) => [id, this.findGuide(id)?.key ?? id]);\n return buildContext({\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n userAttributes: this.user?.traits ?? {},\n accountAttributes: this.user?.account?.traits ?? {},\n url: this.pageHref(),\n firstVisit: this.firstVisit,\n eventsSeen: this.session.events,\n completedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.completedAt)),\n dismissedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.dismissedAt)),\n seenGuides: keysOf(Object.keys(guides).filter((id) => (guides[id]?.impressions ?? 0) > 0)),\n completedChecklists: keysOf(completedChecklists),\n audienceIds: this.state.audienceIds,\n environment: this.options.environment,\n platform: \"web\",\n ...(this.options.appVersion ? { appVersion: this.options.appVersion } : {}),\n });\n }\n\n private isTargeted(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n const c = guide.config;\n if (c.urlPatterns.length && !c.urlPatterns.some((p) => urlMatches(p, url))) return false;\n if (c.trigger.urlPattern && !urlMatches(c.trigger.urlPattern, url)) return false;\n if (!isWithinSchedule(guide)) return false;\n if (guide.kind === \"survey\" && (this.state.surveysSubmitted.includes(guide.id) || this.state.surveysSubmitted.includes(guide.key))) return false;\n ctx.rolloutSalt = guide.id;\n return evaluateRules(c.targeting, ctx);\n }\n\n /** Guide throttling: may this guide launch automatically now? */\n private throttleAllows(guide: PublishedGuide): boolean {\n if (!countsTowardThrottle(guide)) return true;\n return isThrottleEligible(this.config?.settings.throttling, this.state.throttle ?? []);\n }\n\n private recordLaunch(guide: PublishedGuide, manual: boolean): void {\n if (manual || !countsTowardThrottle(guide) || !this.config?.settings.throttling?.enabled) return;\n this.state.throttle = pruneLaunches([...(this.state.throttle ?? []), nowIso()], this.config.settings.throttling);\n this.persistState();\n }\n\n /** Guides and A/B test control groups, which are evaluated the same way but never render. */\n private candidates(): PublishedGuide[] {\n const guides = this.config?.guides ?? [];\n const holdouts = this.config?.guideHoldouts ?? [];\n return holdouts.length ? [...guides, ...holdouts.map((h) => h.guide)] : guides;\n }\n\n private holdoutFor(guide: PublishedGuide) {\n return this.config?.guideHoldouts?.find((h) => h.guide.id === guide.id) ?? null;\n }\n\n /** The visitor's language candidates, most preferred first. */\n private locales(): string[] {\n const nav = typeof navigator !== \"undefined\" ? [...(navigator.languages ?? []), navigator.language] : [];\n return visitorLocales(this.locale ?? this.options.locale, this.user?.traits, nav);\n }\n\n private defaultLocale(): string {\n return this.config?.settings.localization?.defaultLocale || \"en\";\n }\n\n /** The guide in the visitor's language (remembered so its events carry `locale`). */\n private localize(guide: PublishedGuide): PublishedGuide {\n const localized = localizeGuide(guide, this.locales(), this.defaultLocale());\n this.guideLocales.set(guide.id, localized.locale);\n return localized;\n }\n\n /**\n * Sets the language for guides and the resource center (`null` = back to the traits / browser).\n * Guides already on screen keep their language; the resource center re-renders.\n */\n setLocale(locale: string | null): void {\n this.locale = locale ? normalizeLocale(locale) || null : null;\n if (this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.renderPersistentWidgets();\n }\n }\n\n private isEligible(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n if (!this.isTargeted(guide, ctx, url)) return false;\n const shownThisSession = this.session.shownGuides.includes(guide.id);\n if (guide.kind === \"checklist\") {\n const p = this.state.checklists[guide.id];\n return !p?.dismissedAt;\n }\n return isFrequencyEligible(guide.config.frequency, this.state.guides[guide.id], shownThisSession);\n }\n\n private triggerFires(guide: PublishedGuide, reason: EvalReason, detail: EvalDetail): boolean {\n const t = guide.config.trigger;\n switch (t.type) {\n case \"page_load\":\n // A delayed page_load re-evaluates from its own timer.\n if (t.delayMs > 0) return reason === \"timer\" && detail.guideId === guide.id;\n return reason === \"ready\" || reason === \"navigation\" || reason === \"identify\";\n case \"url_match\":\n return (reason === \"ready\" || reason === \"navigation\" || reason === \"identify\") && urlMatches(t.value, this.pageHref());\n case \"event\":\n return reason === \"event\" && !!t.value && detail.eventName === t.value;\n case \"element_click\":\n if (reason !== \"click\" || !t.value || !detail.target) return false;\n try {\n return !!closestComposed(detail.target, t.value);\n } catch {\n return false;\n }\n case \"element_visible\":\n return reason === \"visible\" && detail.guideId === guide.id;\n case \"delay\":\n return reason === \"timer\" && detail.guideId === guide.id;\n case \"after_guide\":\n return reason === \"after_guide\" && !!detail.endedGuide && (detail.endedGuide.id === t.value || detail.endedGuide.key === t.value);\n case \"segment_enter\":\n return reason === \"identify\" && !!t.value && !!detail.newAudiences?.has(t.value);\n case \"manual\":\n default:\n return false;\n }\n }\n\n private evaluate(reason: EvalReason, detail: EvalDetail = {}): void {\n if (!this.config || this.destroyed || this.editing()) return;\n const url = this.pageHref();\n const ctx = this.getContext();\n if (reason === \"identify\") {\n const current = new Set(this.state.audienceIds);\n detail.newAudiences = new Set(Array.from(current).filter((a) => !this.lastAudiences.has(a)));\n this.lastAudiences = current;\n }\n const candidates: PublishedGuide[] = [];\n for (const guide of this.candidates()) {\n const t = guide.config.trigger;\n if (detail.endedGuide && detail.endedGuide.id === guide.id) continue; // never re-show the guide that just ended\n // Arm element-visibility observers and delay timers on page-level evaluations.\n if (reason === \"ready\" || reason === \"navigation\") {\n if (t.type === \"element_visible\" && t.value) this.armVisibility(guide, ctx, url);\n if ((t.type === \"delay\" || (t.type === \"page_load\" && t.delayMs > 0)) && !this.firedDelays.has(guide.id)) {\n if (!this.isEligible(guide, ctx, url)) continue;\n this.firedDelays.add(guide.id);\n this.setTimer(() => this.evaluate(\"timer\", { guideId: guide.id }), t.delayMs);\n continue;\n }\n }\n if (t.type === \"page_load\" && t.delayMs > 0 && reason !== \"timer\") continue;\n if (t.type === \"page_load\" && t.delayMs > 0 && reason === \"timer\" && detail.guideId !== guide.id) continue;\n if (!this.triggerFires(guide, reason, detail)) continue;\n if (!this.isEligible(guide, ctx, url)) continue;\n if (!this.throttleAllows(guide)) {\n this.log(\"throttled\", guide.key);\n continue;\n }\n candidates.push(guide);\n }\n if (reason === \"after_guide\" || reason === \"navigation\") this.drainQueue(url, ctx);\n if (!candidates.length) return;\n candidates.sort((a, b) => a.config.frequency.priority - b.config.frequency.priority);\n for (const guide of candidates) {\n if (this.widgets.has(guide.id) || this.active?.guide.id === guide.id) continue;\n const delay = guide.config.trigger.type !== \"delay\" && guide.config.trigger.type !== \"page_load\" ? guide.config.trigger.delayMs : 0;\n if (delay > 0) {\n this.setTimer(() => this.tryShow(guide, url, false), delay);\n continue;\n }\n this.tryShow(guide, url, false);\n }\n }\n\n private armVisibility(guide: PublishedGuide, ctx: TargetingContext, url: string): void {\n const selector = guide.config.trigger.value;\n if (!selector || this.visibilityObservers.has(guide.id)) return;\n if (!this.isEligible(guide, ctx, url)) return;\n const ac = new AbortController();\n let io: IntersectionObserver | null = null;\n const stop = () => {\n ac.abort();\n io?.disconnect();\n this.visibilityObservers.delete(guide.id);\n };\n this.visibilityObservers.set(guide.id, stop);\n waitForTarget([{ kind: \"css\", value: selector }], { timeoutMs: 0, signal: ac.signal })\n .then((el) => {\n if (ac.signal.aborted) return;\n const fire = () => {\n stop();\n this.evaluate(\"visible\", { guideId: guide.id });\n };\n if (typeof IntersectionObserver === \"undefined\") return fire();\n io = new IntersectionObserver((entries) => {\n if (entries.some((e) => e.isIntersecting)) fire();\n });\n io.observe(el);\n })\n .catch(() => stop());\n }\n\n private setTimer(fn: () => void, ms: number): void {\n const t = setTimeout(() => {\n this.timers.delete(t);\n if (!this.destroyed) fn();\n }, ms);\n this.timers.add(t);\n }\n\n /** Decides whether a guide can show now, otherwise queues it. */\n private tryShow(guide: PublishedGuide, url: string, manual: boolean): boolean {\n if (this.destroyed) return false;\n // Another automatic guide may have launched since this one was picked (delays, queue).\n if (!manual && !this.throttleAllows(guide)) return false;\n const holdout = this.holdoutFor(guide);\n if (holdout) {\n // A/B test control group: count the exposure as if the guide had shown, render nothing.\n if (this.active && !manual) return false;\n this.recordImpression(guide, manual);\n return true;\n }\n if (!isExclusiveGuide(guide)) {\n if (this.widgets.has(guide.id)) return false;\n this.show(guide, manual);\n return true;\n }\n if (this.active) {\n if (this.active.guide.id === guide.id) return false;\n if (manual) this.stopGuide();\n else {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: PAGE_SCOPED.has(guide.config.trigger.type) });\n this.log(\"queued\", guide.key, \"behind\", this.active.guide.key);\n return false;\n }\n }\n const blocked = Array.from(this.widgets.keys()).map((id) => this.findGuide(id)).some((g) => g && areMutuallyExclusive(g, guide));\n if (blocked && !manual) {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: true });\n return false;\n }\n this.show(guide, manual);\n return true;\n }\n\n private drainQueue(url: string, ctx: TargetingContext): void {\n if (this.active) return;\n this.queued = this.queued.filter((q) => !(q.pageScoped && q.url !== url));\n while (this.queued.length) {\n const next = this.queued.shift() as QueuedGuide;\n if (!this.isEligible(next.guide, ctx, url)) continue;\n if (this.tryShow(next.guide, url, false)) return;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Showing guides\n // ---------------------------------------------------------------------------\n\n private findGuide(idOrKey: string): PublishedGuide | undefined {\n return this.config?.guides.find((g) => g.id === idOrKey || g.key === idOrKey);\n }\n\n private guideState(id: string): GuideLocalState {\n return this.state.guides[id] ?? (this.state.guides[id] = { impressions: 0 });\n }\n\n private recordImpression(guide: PublishedGuide, manual = false): void {\n const s = this.guideState(guide.id);\n s.impressions += 1;\n s.lastShownAt = nowIso();\n if (!this.session.shownGuides.includes(guide.id)) this.session.shownGuides.push(guide.id);\n this.recordLaunch(guide, manual);\n this.persistState();\n this.persistSession();\n const holdout = this.holdoutFor(guide);\n const experiment = holdout ? { id: holdout.experimentId, variantId: holdout.variantId } : guide.experiment;\n if (experiment) this.enqueue(\"experiment_viewed\", { properties: { guideExperimentId: experiment.id, variantId: experiment.variantId, ...(holdout ? {} : { guideId: guide.id }) } });\n // Control groups are local only: the server knows no guide by that id.\n if (!holdout) this.syncGuideState(guide.id, { impression: true });\n }\n\n private recordEnd(guide: PublishedGuide, reason: \"completed\" | \"dismissed\" | \"skipped\"): void {\n const s = this.guideState(guide.id);\n if (reason === \"completed\") s.completedAt = nowIso();\n else s.dismissedAt = nowIso();\n this.persistState();\n this.syncGuideState(guide.id, reason === \"completed\" ? { completed: true } : { dismissed: true });\n if (reason === \"completed\") this.completeChecklistTasksBy(\"guide_completed\", guide);\n }\n\n private syncGuideState(guideId: string, update: { impression?: boolean; completed?: boolean; dismissed?: boolean }): void {\n const body = { anonymousId: this.anonymousId, userId: this.user?.id || null, updates: [{ guideId, ...update }] };\n // Impressions are counters (a resend would count twice) and matter less; completions and\n // dismissals are kept until the server has them, so a guide doesn't come back on another device.\n if (update.impression) void postWithRetry(this.api, \"/guide-state\", body);\n else this.outbox.add(`guide:${guideId}:${update.completed ? \"completed\" : \"dismissed\"}:${this.anonymousId}`, \"/guide-state\", body);\n }\n\n private show(guide: PublishedGuide, manual: boolean, stepId?: string): void {\n try {\n if (guide.kind === \"checklist\" && guide.config.checklist) return this.showChecklist(guide);\n if (guide.kind === \"survey\" && guide.config.survey) return this.showSurvey(guide, manual);\n this.showFlow(guide, manual, stepId);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private showFlow(raw: PublishedGuide, manual: boolean, stepId?: string): void {\n if (this.editing()) return; // authoring mode renders previews only; capture renders nothing\n const guide = this.localize(raw);\n const exclusive = isExclusiveGuide(guide);\n const entry: ActiveGuide = { guide, manual, startUrl: this.pageHref() };\n const controller = runGuide(guide, {\n theme: this.theme(),\n // Code blocks only arrive when a workspace admin allowed them (the server strips them otherwise).\n runCode: true,\n ctx: () => this.getContext(),\n currentUrl: () => this.pageHref(),\n startAtStep: stepId,\n eventBus: this.eventBus,\n // Started from Help, Scout or startGuide(): steps on other pages offer to take the user there.\n promptForUrl: manual,\n // Also while a step waits for its page, so a link that loads that page resumes on it.\n onPosition: (id) => {\n if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: id, manual });\n },\n onError: (err) => this.reportError(err),\n onEvent: (e) => {\n const step = e.stepId ? guide.config.steps.find((s) => s.id === e.stepId) : undefined;\n this.enqueue(e.name, { guideId: guide.id, guideVersion: guide.version, stepId: e.stepId, stepIndex: e.stepIndex, properties: e.properties });\n if (e.name === \"guide_started\") {\n this.recordImpression(guide, manual);\n this.emitter.emit(\"guide:start\", guide);\n }\n if (e.name === \"step_viewed\" && step) {\n if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: step.id, manual });\n if (guide.kind === \"flow\" && guide.config.steps.length > 1) {\n this.guideState(guide.id).lastStepId = step.id;\n this.persistState();\n }\n this.emitter.emit(\"guide:step\", { guide, stepId: step.id, stepIndex: e.stepIndex ?? 0 });\n }\n if (e.name === \"guide_completed\") {\n this.recordEnd(guide, \"completed\");\n this.emitter.emit(\"guide:complete\", guide);\n }\n if (e.name === \"guide_dismissed\") {\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n if (e.name === \"guide_skipped\") {\n this.recordEnd(guide, \"skipped\");\n this.emitter.emit(\"guide:skip\", guide);\n }\n },\n onNavigate: (url, newTab) => this.navigate(url, newTab),\n onAction: (action, value) => {\n if (action === \"start_guide\" && value) this.setTimer(() => this.startGuide(value), 0);\n else if (action === \"event\" && value) this.track(value);\n else if (action === \"open_resource_center\") this.openResourceCenter();\n },\n onEnd: (reason) => {\n if (exclusive) {\n if (this.active?.controller === controller) this.active = null;\n this.sessionStore.remove(KEYS.active);\n } else this.widgets.delete(guide.id);\n if (reason !== \"destroyed\" && !this.destroyed) this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n },\n });\n entry.controller = controller;\n if (exclusive) this.active = entry;\n else this.widgets.set(guide.id, { destroy: () => controller.destroy(), controller, manual });\n controller.start();\n if (controller.getState().status === \"ended\") {\n if (exclusive && this.active === entry) this.active = null;\n this.widgets.delete(guide.id);\n }\n }\n\n private showChecklist(raw: PublishedGuide): void {\n if (this.editing()) return; // authoring mode renders previews only; capture renders nothing\n const guide = this.localize(raw);\n const config = guide.config.checklist;\n if (!config || this.widgets.has(guide.id)) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const progress = this.getChecklistProgress(guide.id);\n const first = !this.state.guides[guide.id]?.impressions;\n const widget = renderChecklist({\n scope: scope.el,\n config,\n progress,\n open: config.autoOpen && first && !progress.completedAt,\n onTaskClick: (task) => this.handleChecklistTaskClick(guide, task),\n onDismiss: () => this.dismissChecklist(guide),\n onOpen: () => this.enqueue(\"guide_viewed\", { guideId: guide.id, guideVersion: guide.version }),\n });\n this.widgets.set(guide.id, { destroy: () => { widget.destroy(); scope.destroy(); }, checklist: widget, scope });\n if (first) this.recordImpression(guide);\n }\n\n private showSurvey(raw: PublishedGuide, manual: boolean): void {\n if (this.editing()) return; // authoring mode renders previews only; capture renders nothing\n const guide = this.localize(raw);\n const config = guide.config.survey;\n if (!config) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const entry: ActiveGuide = { guide, manual, startUrl: this.pageHref(), scope };\n const finish = (reason: \"submitted\" | \"dismissed\") => {\n widget.destroy();\n scope.destroy();\n if (this.active === entry) this.active = null;\n if (reason === \"dismissed\") {\n this.enqueue(\"survey_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n };\n const widget = renderSurvey({\n scope: scope.el,\n config,\n title: guide.name,\n onDismiss: () => finish(this.state.surveysSubmitted.includes(guide.id) ? \"submitted\" : \"dismissed\"),\n onSubmit: (answers) => {\n const responseId = randomId(24);\n this.state.surveysSubmitted.push(guide.id);\n this.persistState();\n this.recordEnd(guide, \"completed\");\n this.enqueue(\"survey_submitted\", { guideId: guide.id, guideVersion: guide.version, properties: { responseId } });\n this.outbox.add(`survey:${responseId}`, `/surveys/${encodeURIComponent(guide.id)}/responses`, { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, guideVersion: guide.version, answers, responseId });\n this.emitter.emit(\"survey:submit\", { guide, answers, responseId });\n this.emitter.emit(\"guide:complete\", guide);\n widget.showThankYou();\n },\n });\n entry.survey = widget;\n this.active = entry;\n this.recordImpression(guide, manual);\n this.enqueue(\"survey_displayed\", { guideId: guide.id, guideVersion: guide.version });\n this.emitter.emit(\"guide:start\", guide);\n }\n\n private theme() {\n return { ...(this.config?.theme || {}), ...(this.options.theme || {}) };\n }\n\n private navigate(url: string, newTab?: boolean): void {\n try {\n if (this.openPrototypeTest(url)) return;\n if (newTab) window.open(url, \"_blank\", \"noopener\");\n else location.assign(url);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private renderPersistentWidgets(): void {\n if (!this.config || this.captureStarting || this.capture?.isActive()) return;\n const rc = this.config.resourceCenter;\n if (this.config.messenger?.enabled) {\n // One launcher: the messenger's Help tab replaces the resource center.\n if (this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n if (!this.messenger) void this.loadMessenger();\n return;\n }\n this.destroyMessenger();\n if (rc && rc.enabled && !this.resourceCenter) {\n const scope = createScope(this.theme());\n this.resourceCenterScope = scope;\n this.resourceCenter = renderResourceCenter({\n scope: scope.el,\n config: localizeResourceCenter(rc, this.locales(), this.defaultLocale()),\n evaluate: (rules) => evaluateRules(rules, this.getContext()),\n announcementsSeenAt: () => this.state.announcementsSeenAt ?? null,\n onAnnouncementsSeen: () => {\n this.state.announcementsSeenAt = nowIso();\n this.persistState();\n },\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n search: (q) => this.searchResourceCenter(q),\n audienceIds: () => this.state.audienceIds,\n loadArticle: (id) => this.loadArticle(id),\n onStartGuide: (id) => this.startGuide(id),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"resource_center_opened\");\n this.emitter.emit(\"resource-center:open\");\n },\n });\n } else if ((!rc || !rc.enabled) && this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n }\n\n private resumeActiveGuide(): void {\n const saved = readJson<{ guideId: string; stepId: string; manual?: boolean } | null>(this.sessionStore, KEYS.active, null);\n if (!saved) return;\n this.sessionStore.remove(KEYS.active);\n const guide = this.findGuide(saved.guideId);\n if (!guide || !guide.config.steps.some((s) => s.id === saved.stepId)) return;\n this.showFlow(guide, saved.manual ?? false, saved.stepId);\n }\n\n /** Loads the messenger widget on demand (it is a separate chunk) and renders it. */\n private loadMessenger(): Promise<MessengerWidget | null> {\n if (this.messenger) return Promise.resolve(this.messenger);\n if (this.messengerLoading) return this.messengerLoading;\n this.messengerLoading = import(\"@guidelytech/guide-runtime/messenger\")\n .then(({ renderMessenger }) => {\n const cfg = this.config?.messenger;\n if (this.destroyed || !this.config || !cfg?.enabled || this.messenger) return this.messenger;\n const scope = createScope(this.theme());\n this.messengerScope = scope;\n this.messenger = renderMessenger({\n scope: scope.el,\n config: cfg,\n api: createMessengerTransport({\n api: this.api,\n store: this.store,\n projectId: this.options.projectId,\n anonymousId: () => this.anonymousId,\n userId: () => this.user?.id || null,\n pageUrl: () => (this.collectUrls() ? this.pageHref() : undefined),\n locale: () => this.rcLocale(),\n }),\n visitor: () => this.messengerVisitor(),\n brand: { logoUrl: this.theme().logoUrl ?? null, name: this.theme().brandName ?? null },\n onResumeGuide: (guideId, stepId) => this.startGuide(guideId, { stepId }),\n onNewsSeen: (ids) => {\n const seen = readJson<string[]>(this.store, KEYS.newsSeen(this.options.projectId), []);\n writeJson(this.store, KEYS.newsSeen(this.options.projectId), Array.from(new Set([...ids, ...(Array.isArray(seen) ? seen : [])])).slice(0, 200));\n },\n resourceCenter: this.config.resourceCenter ? localizeResourceCenter(this.config.resourceCenter, this.locales(), this.defaultLocale()) : null,\n evaluate: (rules) => evaluateRules(rules, this.getContext()),\n audienceIds: () => this.state.audienceIds,\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n onStartGuide: (idOrKey) => this.startGuide(idOrKey),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"messenger_opened\");\n this.emitter.emit(\"messenger:open\");\n },\n onMessage: (message, conversation) => this.emitter.emit(\"conversation:message\", { message, conversation }),\n });\n return this.messenger;\n })\n .catch((err) => {\n this.reportError(err);\n return null;\n })\n .finally(() => {\n this.messengerLoading = null;\n });\n return this.messengerLoading;\n }\n\n /** What the messenger personalises from, computed fresh on every render. */\n private messengerVisitor() {\n const ctx = this.getContext();\n const url = this.pageHref();\n const seen = readJson<string[]>(this.store, KEYS.newsSeen(this.options.projectId), []);\n const visitor = buildMessengerVisitor({\n guides: this.config?.guides ?? [],\n state: this.state,\n traits: this.user?.traits,\n url,\n isTargeted: (g) => this.isTargeted(g, ctx, url),\n isAudienceTargeted: (g) => {\n if (!isWithinSchedule(g)) return false;\n ctx.rolloutSalt = g.id;\n return evaluateRules(g.config.targeting, ctx);\n },\n newsSeen: Array.isArray(seen) ? seen : [],\n });\n // The resource center's \"What's new\" joins the messenger's News (the messenger replaces the resource center).\n const rc = this.config?.resourceCenter;\n const rcNews = rc?.announcements?.length\n ? visibleAnnouncements(localizeResourceCenter(rc, this.locales(), this.defaultLocale()).announcements, this.state.audienceIds).map((a) => ({\n id: `rc_${a.id}`,\n key: a.guideId ?? \"\",\n title: a.title,\n body: plainText(a.body),\n imageUrl: null,\n publishedAt: a.publishedAt,\n unread: !(Array.isArray(seen) && seen.includes(`rc_${a.id}`)),\n articleId: a.articleId ?? null,\n url: a.url ?? null,\n }))\n : [];\n const news = rcNews.length ? [...visitor.news, ...rcNews].sort((a, b) => b.publishedAt.localeCompare(a.publishedAt)).slice(0, 10) : visitor.news;\n return { ...visitor, news, identified: !!this.user?.id };\n }\n\n private destroyMessenger(): void {\n this.messenger?.destroy();\n this.messengerScope?.destroy();\n this.messenger = null;\n this.messengerScope = null;\n }\n\n /** The resource center's language for this visitor, or null for the default language. */\n private rcLocale(): string | null {\n const rc = this.config?.resourceCenter;\n if (!rc) return null;\n const locale = localizeResourceCenter(rc, this.locales(), this.defaultLocale()).locale;\n return locale.toLowerCase() === this.defaultLocale().toLowerCase() ? null : locale;\n }\n\n private async loadArticle(id: string): Promise<ResourceCenterArticle | null> {\n try {\n const locale = this.rcLocale();\n const res = await this.api.get<{ article: ResourceCenterArticle }>(`/articles/${encodeURIComponent(id)}`, locale ? { params: { locale } } : undefined);\n return res.ok && res.data ? res.data.article : null;\n } catch {\n return null;\n }\n }\n\n private async searchResourceCenter(q: string): Promise<ResourceCenterArticle[]> {\n try {\n const res = await this.api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n } catch {\n return [];\n }\n }\n\n // ---------------------------------------------------------------------------\n // Checklists\n // ---------------------------------------------------------------------------\n\n /** Current progress for a checklist guide (by id or key). */\n getChecklistProgress(idOrKey: string): ChecklistProgressState {\n const guide = this.findGuide(idOrKey);\n const id = guide?.id ?? idOrKey;\n const p = this.state.checklists[id];\n return p ? { completedTaskIds: [...p.completedTaskIds], completedAt: p.completedAt ?? null, dismissedAt: p.dismissedAt ?? null } : { completedTaskIds: [], completedAt: null, dismissedAt: null };\n }\n\n /** Marks a checklist task complete (manual completion) and syncs progress. */\n completeChecklistTask(idOrKey: string, taskId: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n const task = guide.config.checklist.tasks.find((t) => t.id === taskId);\n if (task) this.markTaskDone(guide, task);\n }\n\n private markTaskDone(guide: PublishedGuide, task: ChecklistTask): void {\n const config = guide.config.checklist;\n if (!config) return;\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n if (progress.completedTaskIds.includes(task.id)) return;\n progress.completedTaskIds.push(task.id);\n this.enqueue(\"checklist_task_completed\", { guideId: guide.id, guideVersion: guide.version, properties: { taskId: task.id } });\n const complete = isChecklistComplete(config, progress) && !progress.completedAt;\n if (complete) {\n progress.completedAt = nowIso();\n this.enqueue(\"checklist_completed\", { guideId: guide.id, guideVersion: guide.version });\n }\n this.persistState();\n this.widgets.get(guide.id)?.checklist?.setProgress(this.getChecklistProgress(guide.id));\n this.outbox.add(`checklist:${guide.id}:progress:${this.anonymousId}`, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, completed: !!progress.completedAt });\n this.emitter.emit(\"checklist:task\", { guide, task, progress: this.getChecklistProgress(guide.id) });\n if (complete) {\n this.emitter.emit(\"checklist:complete\", guide);\n this.widgets.get(guide.id)?.checklist?.open();\n }\n }\n\n private completeChecklistTasksBy(kind: ChecklistTask[\"completion\"], value: string | Element | PublishedGuide): void {\n if (!this.config) return;\n for (const guide of this.config.guides) {\n const tasks = guide.config.checklist?.tasks;\n if (!tasks) continue;\n for (const task of tasks) {\n if (task.completion !== kind || !task.completionValue) continue;\n let hit = false;\n if (kind === \"event\") hit = value === task.completionValue;\n else if (kind === \"url_visited\") hit = urlMatches(task.completionValue, value as string);\n else if (kind === \"guide_completed\") hit = (value as PublishedGuide).id === task.completionValue || (value as PublishedGuide).key === task.completionValue;\n else if (kind === \"click\") {\n try {\n hit = !!closestComposed(value as Element, task.completionValue);\n } catch {\n hit = false;\n }\n }\n if (hit) this.markTaskDone(guide, task);\n }\n }\n }\n\n private handleChecklistTaskClick(guide: PublishedGuide, task: ChecklistTask): void {\n if (task.completion === \"manual\") this.markTaskDone(guide, task);\n if (task.action === \"start_guide\" && task.actionValue) this.startGuide(task.actionValue);\n else if (task.action === \"url\" && task.actionValue) this.navigate(task.actionValue);\n else if (task.action === \"event\" && task.actionValue) this.track(task.actionValue);\n }\n\n private dismissChecklist(guide: PublishedGuide): void {\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n progress.dismissedAt = nowIso();\n this.persistState();\n this.enqueue(\"checklist_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n this.outbox.add(`checklist:${guide.id}:dismissed:${this.anonymousId}`, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, dismissed: true });\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n }\n\n /** Opens (rendering if needed) the checklist panel. */\n openChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n if (!this.widgets.has(guide.id)) {\n const p = this.state.checklists[guide.id];\n if (p?.dismissedAt) {\n delete p.dismissedAt;\n this.persistState();\n }\n this.showChecklist(guide);\n }\n this.widgets.get(guide.id)?.checklist?.open();\n }\n\n closeChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (guide) this.widgets.get(guide.id)?.checklist?.close();\n }\n\n // ---------------------------------------------------------------------------\n // Public guide controls\n // ---------------------------------------------------------------------------\n\n /** Starts a guide by id or key, bypassing targeting and frequency rules. */\n startGuide(idOrKey: string, options: { stepId?: string } = {}): boolean {\n const guide = this.findGuide(idOrKey);\n if (!guide) {\n this.reportError(new Error(`[Guidely] startGuide: unknown guide \"${idOrKey}\"`));\n return false;\n }\n if (guide.kind === \"checklist\") {\n this.openChecklist(guide.id);\n return true;\n }\n if (this.active) this.stopGuide();\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n this.show(guide, true, options.stepId);\n return true;\n }\n\n /** Stops the active guide silently (no dismiss event). */\n stopGuide(): void {\n const a = this.active;\n if (!a) return;\n this.active = null;\n a.controller?.destroy();\n a.survey?.destroy();\n a.scope?.destroy();\n this.sessionStore.remove(KEYS.active);\n }\n\n /** Dismisses the active guide (records a dismissal). */\n dismissGuide(): void {\n const a = this.active;\n if (!a) return;\n if (a.controller) a.controller.dismiss();\n else {\n this.stopGuide();\n this.recordEnd(a.guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", a.guide);\n }\n }\n\n getActiveGuide(): PublishedGuide | null {\n return this.active?.guide ?? null;\n }\n\n /** Published guides for this environment (read-only). */\n getGuides(): ReadonlyArray<PublishedGuide> {\n return this.config?.guides ?? [];\n }\n\n isGuideCompleted(idOrKey: string): boolean {\n const guide = this.findGuide(idOrKey);\n return !!this.state.guides[guide?.id ?? idOrKey]?.completedAt;\n }\n\n openResourceCenter(): void {\n if (this.config?.messenger?.enabled) return this.openMessenger(\"help\");\n if (!this.resourceCenter) this.renderPersistentWidgets();\n this.resourceCenter?.open();\n }\n\n closeResourceCenter(): void {\n if (this.messenger) return this.closeMessenger();\n this.resourceCenter?.close();\n }\n\n /** Opens the Scout messenger (when enabled for the project), optionally on a tab. */\n openMessenger(tab?: MessengerTab): void {\n if (!this.config?.messenger?.enabled) return;\n void this.loadMessenger().then((m) => m?.open(tab));\n }\n\n closeMessenger(): void {\n this.messenger?.close();\n }\n\n /**\n * Opens a Guidely prototype test (its `/validate/<token>` URL on this SDK's API origin, or the bare\n * token) in a full-screen overlay, attributed to the current user. Returns false, doing nothing, for\n * any other URL. Guide buttons that open a test URL use this automatically.\n */\n openPrototypeTest(urlOrToken: string): boolean {\n if (typeof document === \"undefined\") return false;\n const url = matchPrototypeTestUrl(urlOrToken, this.options.apiUrl);\n if (!url) return false;\n openPrototypeOverlay(url, { key: this.options.projectId, anonymousId: this.anonymousId, userId: this.user?.id ?? null });\n return true;\n }\n\n /**\n * Opens the complaint form in the messenger, optionally with a category picked (its id from\n * Complaints → Categories). Does nothing when the project doesn't take complaints.\n */\n openComplaint(categoryId?: string): void {\n if (!this.config?.messenger?.enabled || !this.config.messenger.complaints?.categories.length) return;\n void this.loadMessenger().then((m) => m?.openComplaint(categoryId));\n }\n\n /**\n * Opens the Ideas tab in the messenger (feature requests and voting), or one idea by its id.\n * Does nothing when the project hasn't turned on Ideas.\n */\n openIdeas(requestId?: string): void {\n if (!this.config?.messenger?.enabled || !this.config.messenger.ideas) return;\n void this.loadMessenger().then((m) => m?.openIdeas(requestId));\n }\n\n /** Opens a new messenger conversation, optionally pre-filling the message. */\n showNewMessage(text?: string): void {\n if (!this.config?.messenger?.enabled) return;\n void this.loadMessenger().then((m) => m?.showNewMessage(text));\n }\n\n // ---------------------------------------------------------------------------\n // Feature flags\n // ---------------------------------------------------------------------------\n\n /** Boolean flag value for the current user; `fallback` (default `false`) until loaded or when missing. */\n isFeatureEnabled(key: string, fallback = false): boolean {\n return this.flags.isEnabled(key, fallback);\n }\n\n /** Flag value for the current user; `fallback` when missing or of a different type. */\n getFeatureValue<T extends JsonValue>(key: string, fallback: T): FlagValue<T> {\n return this.flags.getValue(key, fallback);\n }\n\n /** Flag value plus why it was served (reason, rule, variation, experiment). */\n getFeatureDetails<T extends JsonValue>(key: string, fallback: T): FlagDetails<FlagValue<T>> {\n return this.flags.getDetails(key, fallback);\n }\n\n /** Calls `cb` whenever flag values may have changed (new rules, identity, page, overrides). Returns an unsubscribe function. */\n onFlagsChange(cb: () => void): () => void {\n return this.flags.subscribe(cb);\n }\n\n /** Attributes flags are evaluated with: identity, traits, account, audiences, page and device. */\n private flagContext(): Attributes {\n const device = detectDevice(navigator.userAgent, window.innerWidth);\n const account = this.user?.account;\n return {\n url: this.pageHref(),\n path: pathOf(this.pageHref()),\n deviceType: device.type,\n browser: device.browser,\n os: device.os,\n locale: navigator.language || undefined,\n environment: this.options.environment,\n platform: \"web\",\n ...(this.options.appVersion ? { appVersion: this.options.appVersion } : {}),\n ...(this.user?.traits ?? {}),\n id: this.user?.id || this.anonymousId,\n anonymousId: this.anonymousId,\n account: account ? { ...(account.traits ?? {}), id: account.id } : undefined,\n $audiences: [...this.state.audienceIds],\n };\n }\n\n private syncFlagAttributes(): void {\n if (!this.destroyed) this.flags?.setContextAttributes(this.flagContext());\n }\n\n /** `experiment_viewed`, once per session and assignment, through the event queue (consent applies). */\n private trackExposure(result: EvaluationResult): void {\n const exp = result.inExperiment ? result.experiment : undefined;\n if (!exp || this.destroyed) return;\n const key = `${this.session.id}|${exp.key}|${exp.hashValue}|${exp.variationId}`;\n if (this.exposures.has(key)) return;\n if (this.exposures.size > 500) this.exposures.clear();\n this.exposures.add(key);\n this.enqueue(\"experiment_viewed\", { properties: { experimentKey: exp.key, variationId: exp.variationId, flagKey: result.key, hashAttribute: exp.hashAttribute, ...(exp.variationName ? { variationName: exp.variationName } : {}) } });\n }\n\n on<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): () => void {\n return this.emitter.on(event, cb);\n }\n\n off<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): void {\n this.emitter.off(event, cb);\n }\n\n /** Snapshot for debugging / devtools. */\n getState() {\n return {\n ready: this.isReady,\n destroyed: this.destroyed,\n anonymousId: this.anonymousId,\n user: this.user,\n consent: this.consent,\n configVersion: this.config?.configVersion ?? null,\n guides: this.getGuides().map((g) => ({ id: g.id, key: g.key, kind: g.kind })),\n activeGuide: this.active ? { id: this.active.guide.id, key: this.active.guide.key, ...(this.active.controller?.getState() ?? {}) } : null,\n queued: this.queued.map((q) => q.guide.key),\n widgets: Array.from(this.widgets.keys()),\n guideState: this.state.guides,\n checklists: this.state.checklists,\n audienceIds: this.state.audienceIds,\n session: this.session,\n pendingEvents: this.queue.size,\n authoring: !!this.authoring?.isActive(),\n capture: !!this.capture?.isActive(),\n flagsReady: this.flags.isReady(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Authoring\n // ---------------------------------------------------------------------------\n\n private maybeStartAuthoring(): void {\n try {\n const bridge = new AuthoringBridge({\n api: this.api,\n sessionStore: this.sessionStore,\n theme: () => this.theme(),\n ctx: () => this.getContext(),\n maskSelectors: [...(this.options.maskSelectors || []), ...(this.config?.settings?.maskSelectors || [])],\n onError: (err) => this.reportError(err),\n onActive: (active) => this.setEditing(\"authoring\", active),\n });\n if (bridge.detect()) this.authoring = bridge;\n } catch (err) {\n this.reportError(err);\n }\n }\n\n /** Authoring or capture started / ended: pause everything a visitor would see or be recorded by. */\n private setEditing(kind: \"authoring\" | \"capture\", active: boolean): void {\n this.emitter.emit(kind, { active });\n if (active) {\n this.replay?.stop({ discard: true });\n this.stopGuide();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n if (kind === \"capture\") this.hidePersistentWidgets();\n } else {\n this.syncCapture();\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n }\n }\n\n private hidePersistentWidgets(): void {\n this.resourceCenter?.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.resourceCenterScope = null;\n this.destroyMessenger();\n }\n\n // ---------------------------------------------------------------------------\n // How-to capture\n // ---------------------------------------------------------------------------\n\n /**\n * Starts how-to capture when the URL carries `guidely_capture` (or this tab is mid-recording).\n * The bridge, toolbar and screenshot code are a separate chunk loaded only then.\n */\n private maybeStartCapture(): boolean {\n let marker: ReturnType<typeof takeCaptureToken> = null;\n try {\n marker = takeCaptureToken(this.sessionStore);\n } catch (err) {\n this.reportError(err);\n }\n if (!marker) return false;\n const found = marker;\n this.captureStarting = true;\n this.replay?.stop({ discard: true });\n loadCapture()\n .then(async (capture) => {\n if (this.destroyed) return;\n const bridge = capture.createBridge({\n api: this.api,\n sessionStore: this.sessionStore,\n marker: found,\n maskSelector: this.maskSelector(),\n onError: (err) => this.reportError(err),\n onActive: (active) => {\n this.captureStarting = false;\n this.setEditing(\"capture\", active);\n },\n });\n this.capture = bridge;\n await bridge.start();\n })\n .catch((err) => this.reportError(err))\n .finally(() => {\n if (!this.captureStarting) return;\n // The session was rejected (or failed to load): carry on as a normal page.\n this.captureStarting = false;\n if (this.destroyed) return;\n this.syncCapture();\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n });\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------------------\n\n private persistState(): void {\n writeJson(this.store, KEYS.state(this.options.projectId), this.state);\n }\n\n private persistSession(): void {\n writeJson(this.sessionStore, KEYS.session, this.session);\n }\n\n private reportError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n this.log(\"error\", error.message);\n try {\n this.options.onError?.(error);\n } catch {\n /* ignore */\n }\n this.emitter.emit(\"error\", error);\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug && typeof console !== \"undefined\") console.debug(\"[Guidely]\", ...args);\n }\n\n // ---------------------------------------------------------------------------\n // Static helpers (used by the embed)\n // ---------------------------------------------------------------------------\n\n /** Creates (or returns the existing) client and starts initialisation. */\n static init(options: GuidelyOptions): GuidelyClient {\n if (current && !current.destroyed && current.options.projectId === options.projectId) return current;\n current?.destroy();\n current = new GuidelyClient(options);\n void current.init();\n return current;\n }\n\n /** The most recently created client, if any. */\n static get(): GuidelyClient | null {\n return current && !current.destroyed ? current : null;\n }\n}\n\nlet current: GuidelyClient | null = null;\n\n/** Mobile-only guides never run in the browser (older servers ignore `?platform=web`). */\nfunction webOnly(config: SdkConfigResponse): SdkConfigResponse {\n return config.guides.every((g) => supportsPlatform(g.config, \"web\")) ? config : { ...config, guides: config.guides.filter((g) => supportsPlatform(g.config, \"web\")) };\n}\n\nfunction pathOf(url: string): string {\n try {\n return new URL(url, \"http://localhost\").pathname;\n } catch {\n return url.replace(/[?#].*$/, \"\");\n }\n}\n\n/** `document.referrer` as origin + path, only when it is another site. */\nfunction externalReferrer(): string | undefined {\n try {\n if (!document.referrer) return undefined;\n const u = new URL(document.referrer);\n return u.origin === location.origin ? undefined : u.origin + u.pathname;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Creates a Guidely client and starts loading configuration. Throws a friendly error when called\n * during server-side rendering; framework adapters guard this for you.\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n const client = new GuidelyClient(options);\n current = client;\n void client.init();\n return client;\n}\n","import { AGENT_TOOL_CALLS_PER_TURN, AGENT_TURN_MAX_TEXT, AGENT_TURNS_PER_BATCH, randomId, type AgentToolCallInput, type AgentTurnInput } from \"@guidelytech/shared/runtime\";\nimport type { ServerHealth } from \"./health\";\nimport type { Api } from \"./http\";\nimport { Outbox } from \"./outbox\";\nimport type { KeyValueStore } from \"./storage\";\n\n/**\n * Agent Analytics in the browser: turns of conversations with the app's own AI agent, sent to\n * `POST /api/v1/sdk/agent-events`. Turns are filled in with the visitor's ids and session, passed through\n * the app's `agents.redact` callback, and kept in a persisted outbox until the server accepts them\n * (retried with backoff while it is unreachable; the server ignores turns it already has).\n */\n\n/** Last say over each turn before it leaves the browser: return a changed copy, or null to drop it. */\nexport type AgentTurnRedactor = (turn: AgentTurnInput) => AgentTurnInput | null | undefined;\n\nexport interface AgentTurnIdentity {\n anonymousId: string;\n userId: string | null;\n accountId: string | null;\n sessionId: string;\n}\n\nconst PENDING_MAX = 500;\n\nfunction toolCalls(calls: unknown): AgentToolCallInput[] | undefined {\n if (!Array.isArray(calls)) return undefined;\n // Only name, status and latency leave the browser: arguments and results are never sent.\n return calls\n .filter((c): c is AgentToolCallInput => !!c && typeof (c as AgentToolCallInput).name === \"string\" && !!(c as AgentToolCallInput).name)\n .slice(0, AGENT_TOOL_CALLS_PER_TURN)\n .map((c) => ({\n name: c.name.slice(0, 100),\n ...(c.status === \"ok\" || c.status === \"error\" ? { status: c.status } : {}),\n ...(typeof c.latencyMs === \"number\" && Number.isFinite(c.latencyMs) && c.latencyMs >= 0 ? { latencyMs: Math.round(c.latencyMs) } : {}),\n }));\n}\n\n/**\n * A turn ready to send: identity and session filled in where the app left them out, a turn id and time\n * when missing, the redactor applied, then text and tool calls trimmed to what the server accepts.\n * Returns null for a turn that is missing its ids or that the redactor dropped.\n */\nexport function prepareAgentTurn(turn: AgentTurnInput, identity: AgentTurnIdentity, redact?: AgentTurnRedactor, onError?: (err: unknown) => void): AgentTurnInput | null {\n if (!turn || typeof turn !== \"object\" || !turn.conversationId || !turn.agentId || !turn.role) return null;\n let out: AgentTurnInput = {\n ...turn,\n type: \"agent.conversation\",\n turnId: turn.turnId || `t_${randomId(20)}`,\n occurredAt: turn.occurredAt || new Date().toISOString(),\n anonymousId: turn.anonymousId ?? identity.anonymousId,\n userId: turn.userId !== undefined ? turn.userId : identity.userId,\n accountId: turn.accountId !== undefined ? turn.accountId : identity.accountId,\n sessionId: turn.sessionId ?? identity.sessionId,\n };\n if (redact) {\n try {\n const r = redact({ ...out, toolCalls: out.toolCalls ? out.toolCalls.map((c) => ({ ...c })) : undefined, metadata: out.metadata ? { ...out.metadata } : undefined });\n if (!r) return null;\n // The redactor may change content, not which conversation or turn this is.\n out = { ...r, type: \"agent.conversation\", conversationId: out.conversationId, agentId: out.agentId, turnId: out.turnId, role: out.role };\n } catch (err) {\n onError?.(err);\n return null; // when in doubt, send nothing\n }\n }\n if (typeof out.text === \"string\" && out.text.length > AGENT_TURN_MAX_TEXT) out.text = out.text.slice(0, AGENT_TURN_MAX_TEXT);\n if (out.text !== undefined && typeof out.text !== \"string\") out.text = String(out.text);\n const calls = toolCalls(out.toolCalls);\n if (calls) out.toolCalls = calls;\n else delete out.toolCalls;\n return out;\n}\n\nexport interface AgentTurnsOptions {\n api: Api;\n store: KeyValueStore;\n storageKey: string;\n health?: ServerHealth;\n sdk: { name: string; version: string };\n}\n\n/** Sends prepared turns in batches through their own outbox; holds them in memory while consent is pending. */\nexport class AgentTurns {\n private readonly outbox: Outbox;\n private pending: AgentTurnInput[] = [];\n\n constructor(private readonly opts: AgentTurnsOptions) {\n // Own outbox, kept small: turns can be long, and they must not crowd out survey answers.\n this.outbox = new Outbox({ api: opts.api, store: opts.store, storageKey: opts.storageKey, health: opts.health, maxItems: 20, maxAgeMs: 24 * 60 * 60 * 1000 });\n }\n\n get queued(): number {\n return this.outbox.size + this.pending.length;\n }\n\n /** Queues turns to send now, or (`hold`) until consent is granted. */\n add(turns: AgentTurnInput[], hold = false): void {\n if (!turns.length) return;\n if (hold) {\n this.pending.push(...turns);\n if (this.pending.length > PENDING_MAX) this.pending.splice(0, this.pending.length - PENDING_MAX);\n return;\n }\n for (let i = 0; i < turns.length; i += AGENT_TURNS_PER_BATCH) {\n const batch = turns.slice(i, i + AGENT_TURNS_PER_BATCH);\n this.outbox.add(`agent:${batch[0]!.turnId}`, \"/agent-events\", { turns: batch, sdk: this.opts.sdk });\n }\n }\n\n /** Consent changed: granted sends what was held, anything else drops it. */\n consentChanged(granted: boolean): void {\n const held = this.pending.splice(0);\n if (granted) this.add(held);\n }\n\n destroy(): void {\n this.pending = [];\n this.outbox.destroy();\n }\n}\n","/**\n * Whether the Guidely API is reachable right now: a circuit breaker shared by everything the SDK\n * sends in the background (event batches, replay uploads, config refreshes, queued survey answers).\n *\n * Every API answer is reported here. After `threshold` failures in a row (network errors, timeouts,\n * 429, 5xx) the circuit opens for a cooldown that doubles with each further failure (5 s up to\n * 5 min, ±20% jitter so tabs don't retry in step); a `Retry-After` answer sets the cooldown\n * directly. While it is open, background senders wait `waitMs()` instead of sending. Requests the\n * person makes (a messenger message) still go out, and any answer closes the circuit again. The\n * browser's `online` event ends the cooldown early.\n */\nexport interface ServerHealthOptions {\n threshold?: number;\n baseMs?: number;\n maxMs?: number;\n now?: () => number;\n random?: () => number;\n}\n\n/** Longest `Retry-After` honoured, so a bad header can't silence the SDK for days. */\nconst MAX_RETRY_AFTER_MS = 60 * 60 * 1000;\n/** How long background senders wait while the browser reports being offline (the `online` event usually comes first). */\nconst OFFLINE_WAIT_MS = 30_000;\n\nexport class ServerHealth {\n private failures = 0;\n private openUntil = 0;\n private lastOkAt = 0;\n private readonly listeners = new Set<() => void>();\n private readonly threshold: number;\n private readonly baseMs: number;\n private readonly maxMs: number;\n private readonly now: () => number;\n private readonly random: () => number;\n\n constructor(opts: ServerHealthOptions = {}) {\n this.threshold = opts.threshold ?? 3;\n this.baseMs = opts.baseMs ?? 5000;\n this.maxMs = opts.maxMs ?? 5 * 60 * 1000;\n this.now = opts.now ?? Date.now;\n this.random = opts.random ?? Math.random;\n }\n\n /** The server answered (2xx, 3xx, or a 4xx other than 429): it is up. */\n success(): void {\n const wasDown = this.failures > 0 || this.openUntil > 0;\n this.failures = 0;\n this.openUntil = 0;\n this.lastOkAt = this.now();\n if (wasDown) this.notify();\n }\n\n /** The request failed or the server is overloaded. `retryAfterMs` comes from a `Retry-After` header. */\n failure(retryAfterMs?: number | null): void {\n this.failures += 1;\n const now = this.now();\n if (retryAfterMs != null && retryAfterMs > 0) {\n this.openUntil = Math.max(this.openUntil, now + Math.min(retryAfterMs, MAX_RETRY_AFTER_MS));\n return;\n }\n if (this.failures < this.threshold) return;\n const cooldown = Math.min(this.maxMs, this.baseMs * 2 ** (this.failures - this.threshold));\n this.openUntil = Math.max(this.openUntil, now + cooldown * (0.8 + this.random() * 0.4));\n }\n\n /** Milliseconds background traffic should wait before trying again (0: send now). */\n waitMs(): number {\n if (typeof navigator !== \"undefined\" && navigator.onLine === false) return OFFLINE_WAIT_MS;\n return Math.max(0, this.openUntil - this.now());\n }\n\n canSend(): boolean {\n return this.waitMs() === 0;\n }\n\n /**\n * The last request got an answer. Unload beacons can't report back, so what they carry is only\n * forgotten while this holds; otherwise it stays queued and is sent again (the server drops duplicates).\n */\n get reachable(): boolean {\n return this.failures === 0 && this.lastOkAt > 0;\n }\n\n /** The browser came back online: end the cooldown and let queued traffic try straight away. */\n online(): void {\n this.openUntil = 0;\n this.notify();\n }\n\n /** Called when the server answers again after failures, or the browser comes back online. */\n onRecover(cb: () => void): () => void {\n this.listeners.add(cb);\n return () => this.listeners.delete(cb);\n }\n\n private notify(): void {\n for (const cb of Array.from(this.listeners)) {\n try {\n cb();\n } catch {\n /* a listener must not break the others */\n }\n }\n }\n}\n\n/** `Retry-After` as milliseconds: delta-seconds or an HTTP date. Null when absent or unparseable. */\nexport function parseRetryAfter(value: string | null | undefined, now = Date.now()): number | null {\n if (!value) return null;\n const trimmed = value.trim();\n if (/^\\d+$/.test(trimmed)) return Number(trimmed) * 1000;\n const at = Date.parse(trimmed);\n return Number.isNaN(at) ? null : Math.max(0, at - now);\n}\n\n/** Answers that mean the server is down or shedding load (retry later) rather than refusing the request. */\nexport function isServerFailure(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import { isServerFailure, parseRetryAfter, ServerHealth } from \"./health\";\n\nexport interface ApiResponse<T> {\n status: number;\n ok: boolean;\n data: T | null;\n etag: string | null;\n}\n\nexport type FetchLike = typeof fetch;\n\n/** Reply streams: the response must start within this long, and then never go quiet longer than the idle limit (the server sends a keepalive every 15 s). */\nexport const STREAM_RESPONSE_TIMEOUT_MS = 30_000;\nexport const STREAM_IDLE_TIMEOUT_MS = 60_000;\n\n/** Thin HTTP client for the public SDK API. Adds the public key as query + header. */\nexport class Api {\n /** Reachability of the API, fed by every answer (see {@link ServerHealth}). */\n readonly health: ServerHealth;\n\n constructor(\n private readonly baseUrl: string,\n private readonly key: string,\n private readonly fetchImpl?: FetchLike,\n health?: ServerHealth,\n ) {\n this.health = health ?? new ServerHealth();\n }\n\n /** Feeds an answer (or a failed request, `null`) into {@link health}. */\n private observe(res: Response | null): void {\n if (!res) this.health.failure();\n else if (isServerFailure(res.status)) this.health.failure(parseRetryAfter(res.headers?.get?.(\"retry-after\")));\n else this.health.success();\n }\n\n url(path: string, params: Record<string, string | undefined> = {}): string {\n // Built by hand rather than with URL/searchParams, which React Native does not implement.\n const query = Object.entries({ key: this.key, ...params })\n .filter((e): e is [string, string] => e[1] != null)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n return `${this.baseUrl.replace(/\\/$/, \"\")}/api/v1/sdk${path}?${query}`;\n }\n\n private get fetcher(): FetchLike | null {\n if (this.fetchImpl) return this.fetchImpl;\n return typeof fetch === \"function\" ? fetch.bind(globalThis) : null;\n }\n\n async request<T>(method: \"GET\" | \"POST\", path: string, options: { body?: unknown; etag?: string | null; params?: Record<string, string | undefined>; keepalive?: boolean; timeoutMs?: number; headers?: Record<string, string> } = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const headers: Record<string, string> = { ...options.headers, \"X-Guidely-Key\": this.key, Accept: \"application/json\" };\n // Multipart bodies set their own Content-Type (with the boundary).\n const form = typeof FormData !== \"undefined\" && options.body instanceof FormData;\n if (options.body !== undefined && !form) headers[\"Content-Type\"] = \"application/json\";\n if (options.etag) headers[\"If-None-Match\"] = options.etag;\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timer = ac ? setTimeout(() => ac.abort(), options.timeoutMs ?? 10000) : null;\n try {\n let res: Response;\n try {\n res = await f(this.url(path, options.params), {\n method,\n headers,\n body: options.body === undefined ? undefined : form ? (options.body as FormData) : JSON.stringify(options.body),\n keepalive: options.keepalive,\n signal: ac?.signal,\n credentials: \"omit\",\n mode: \"cors\",\n });\n } catch (err) {\n this.observe(null);\n throw err;\n }\n this.observe(res);\n let data: T | null = null;\n if (res.status !== 304 && res.status !== 204) {\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n }\n return { status: res.status, ok: res.ok, data, etag: res.headers?.get?.(\"etag\") ?? null };\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n get<T>(path: string, options?: { etag?: string | null; params?: Record<string, string | undefined>; headers?: Record<string, string> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"GET\", path, options);\n }\n\n post<T>(path: string, body: unknown, options?: { params?: Record<string, string | undefined>; keepalive?: boolean; headers?: Record<string, string> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"POST\", path, { body, ...options });\n }\n\n /** Multipart POST (file uploads). No Content-Type header: the browser adds it with the boundary. */\n postForm<T>(path: string, form: FormData, options?: { params?: Record<string, string | undefined>; timeoutMs?: number }): Promise<ApiResponse<T>> {\n return this.request<T>(\"POST\", path, { body: form, ...options });\n }\n\n /**\n * POST that may answer with server-sent events. Each event is passed to `onEvent`; a JSON answer is\n * returned instead. Scout replies can take a while, so there is no overall timeout: the response\n * must start within 30 s and then never go quiet for more than 60 s (the server sends keepalives),\n * otherwise the request is aborted and rejects.\n */\n async stream<T>(path: string, body: unknown, onEvent: (event: string, data: unknown) => void, headers: Record<string, string> = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const arm = (ms: number) => {\n if (!ac) return;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => ac.abort(), ms);\n };\n arm(STREAM_RESPONSE_TIMEOUT_MS);\n try {\n let res: Response;\n try {\n res = await f(this.url(path), {\n method: \"POST\",\n headers: { ...headers, \"X-Guidely-Key\": this.key, Accept: \"text/event-stream, application/json\", \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: ac?.signal,\n credentials: \"omit\",\n mode: \"cors\",\n });\n } catch (err) {\n this.observe(null);\n throw err;\n }\n this.observe(res);\n const type = res.headers?.get?.(\"content-type\") ?? \"\";\n if (!type.includes(\"text/event-stream\") || !res.body) {\n let data: T | null = null;\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n return { status: res.status, ok: res.ok, data, etag: null };\n }\n arm(STREAM_IDLE_TIMEOUT_MS);\n await readEventStream(res.body, onEvent, () => arm(STREAM_IDLE_TIMEOUT_MS));\n return { status: res.status, ok: res.ok, data: null, etag: null };\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /** `navigator.sendBeacon` when available (page unload); returns false when it could not be queued. */\n beacon(path: string, body: unknown): boolean {\n try {\n if (typeof navigator === \"undefined\" || typeof navigator.sendBeacon !== \"function\") return false;\n // text/plain is a CORS-safelisted type: cross-origin beacons need no preflight (which\n // browsers drop during unload). The API parses the body regardless of content type.\n const blob = new Blob([JSON.stringify(body)], { type: \"text/plain;charset=UTF-8\" });\n return navigator.sendBeacon(this.url(path), blob);\n } catch {\n return false;\n }\n }\n}\n\nexport const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\n/** Exponential backoff helper: 1s → 2s → 4s … capped. */\nexport function backoffMs(attempt: number, baseMs = 1000, maxMs = 30000): number {\n return Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt));\n}\n\n/**\n * Sends with bounded retries: network errors, 429 and 5xx are retried with backoff; success and\n * other 4xx answers are returned as they are. Null when every attempt failed.\n */\nexport async function withRetry<T>(send: () => Promise<ApiResponse<T>>, attempts = 3, baseMs = 500): Promise<ApiResponse<T> | null> {\n for (let i = 0; i < attempts; i++) {\n try {\n const res = await send();\n if (res.ok || (res.status >= 400 && res.status < 500 && res.status !== 429)) return res;\n } catch {\n /* network error → retry */\n }\n if (i < attempts - 1) await sleep(backoffMs(i, baseMs, 8000));\n }\n return null;\n}\n\n/** Fire-and-forget POST with bounded retries (used for state sync; never blocks UI). */\nexport function postWithRetry<T>(api: Api, path: string, body: unknown, attempts = 3, baseMs = 500): Promise<ApiResponse<T> | null> {\n return withRetry(() => api.post<T>(path, body), attempts, baseMs);\n}\n\n/** Parses a `text/event-stream` body (`event:` + single-line JSON `data:`; comment lines ignored). `onChunk` runs whenever bytes arrive. */\nexport async function readEventStream(body: ReadableStream<Uint8Array>, onEvent: (event: string, data: unknown) => void, onChunk?: () => void): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const dispatch = (raw: string) => {\n let event = \"message\";\n const data: string[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) continue;\n const i = line.indexOf(\":\");\n const field = i < 0 ? line : line.slice(0, i);\n const value = i < 0 ? \"\" : line.slice(i + 1).replace(/^ /, \"\");\n if (field === \"event\") event = value;\n else if (field === \"data\") data.push(value);\n }\n if (!data.length) return;\n try {\n onEvent(event, JSON.parse(data.join(\"\\n\")));\n } catch {\n /* ignore malformed events */\n }\n };\n for (;;) {\n const { done, value } = await reader.read();\n if (value) onChunk?.();\n if (value) buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n?/g, \"\\n\");\n let sep: number;\n while ((sep = buffer.indexOf(\"\\n\\n\")) >= 0) {\n dispatch(buffer.slice(0, sep));\n buffer = buffer.slice(sep + 2);\n }\n if (done) break;\n }\n if (buffer.trim()) dispatch(buffer);\n}\n","export type StorageKind = \"local\" | \"session\" | \"memory\";\n\n/** Minimal synchronous key/value store; never throws (private mode, quota, SSR). */\nexport interface KeyValueStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\nexport function memoryStore(): KeyValueStore {\n const map = new Map<string, string>();\n return { get: (k) => map.get(k) ?? null, set: (k, v) => void map.set(k, v), remove: (k) => void map.delete(k) };\n}\n\nfunction webStore(area: \"localStorage\" | \"sessionStorage\"): KeyValueStore | null {\n try {\n if (typeof window === \"undefined\") return null;\n const s = window[area];\n if (!s) return null;\n const probe = \"__guidely_probe__\";\n s.setItem(probe, \"1\");\n s.removeItem(probe);\n return {\n get: (k) => {\n try {\n return s.getItem(k);\n } catch {\n return null;\n }\n },\n set: (k, v) => {\n try {\n s.setItem(k, v);\n } catch {\n /* quota / private mode */\n }\n },\n remove: (k) => {\n try {\n s.removeItem(k);\n } catch {\n /* ignore */\n }\n },\n };\n } catch {\n return null;\n }\n}\n\n/** Creates a store of the requested kind, degrading to memory when unavailable. */\nexport function createStorage(kind: StorageKind = \"local\"): KeyValueStore {\n if (kind === \"memory\") return memoryStore();\n return webStore(kind === \"local\" ? \"localStorage\" : \"sessionStorage\") ?? memoryStore();\n}\n\nexport function readJson<T>(store: KeyValueStore, key: string, fallback: T): T {\n const raw = store.get(key);\n if (raw == null) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\nexport function writeJson(store: KeyValueStore, key: string, value: unknown): void {\n try {\n store.set(key, JSON.stringify(value));\n } catch {\n /* ignore */\n }\n}\n\n/** Storage keys used by the SDK (documented for integrators). */\nexport const KEYS = {\n anon: \"guidely:anon\",\n seen: \"guidely:seen\",\n config: (key: string) => `guidely:config:${key}`,\n etag: (key: string) => `guidely:etag:${key}`,\n state: (key: string) => `guidely:state:${key}`,\n user: (key: string) => `guidely:user:${key}`,\n queue: (key: string) => `guidely:queue:${key}`,\n /** Survey answers and guide/checklist progress not yet accepted by the server. */\n outbox: (key: string) => `guidely:outbox:${key}`,\n /** Agent Analytics turns not yet accepted by the server. */\n agentOutbox: (key: string) => `guidely:agents:${key}`,\n session: \"guidely:session\",\n active: \"guidely:active\",\n authoring: \"guidely:authoring\",\n /** How-to capture session marker ({ token, … }) and its not-yet-uploaded steps. */\n capture: \"guidely:capture\",\n capturePending: \"guidely:capture:pending\",\n /** Messenger conversations this browser can read: [{ id, token }]. */\n conversations: (key: string) => `guidely:conversations:${key}`,\n /** Announcement ids opened in the messenger's News tab. */\n newsSeen: (key: string) => `guidely:news:${key}`,\n} as const;\n","import type { ServerHealth } from \"./health\";\nimport { backoffMs, type Api } from \"./http\";\nimport { readJson, writeJson, type KeyValueStore } from \"./storage\";\n\n/** One request waiting to reach the server. */\ninterface OutboxItem {\n /** Same key → the newer request replaces the older one (e.g. a checklist's latest progress). */\n key: string;\n path: string;\n body: unknown;\n createdAt: number;\n}\n\nexport interface OutboxOptions {\n api: Api;\n store: KeyValueStore;\n storageKey: string;\n health?: ServerHealth;\n maxItems?: number;\n maxAgeMs?: number;\n onError?: (err: unknown) => void;\n}\n\n/**\n * Persisted queue for writes that must not be lost when the API is down: survey answers, guide\n * completions and checklist progress. Each request is kept (also across page loads) until the\n * server answers it; 5xx, 429 and network errors are retried with backoff, waiting while the API's\n * circuit is open. Every request is idempotent on the server (survey answers dedupe by\n * `responseId`, progress merges), so sending one twice is harmless. Bounded to 50 requests and 7 days.\n */\nexport class Outbox {\n private items: OutboxItem[];\n private sending = false;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private destroyed = false;\n private readonly offRecover: (() => void) | null;\n private readonly maxItems: number;\n private readonly maxAgeMs: number;\n\n constructor(private readonly opts: OutboxOptions) {\n this.maxItems = opts.maxItems ?? 50;\n this.maxAgeMs = opts.maxAgeMs ?? 7 * 24 * 60 * 60 * 1000;\n const stored = readJson<OutboxItem[]>(opts.store, opts.storageKey, []);\n const cutoff = Date.now() - this.maxAgeMs;\n this.items = Array.isArray(stored) ? stored.filter((i) => i && typeof i.path === \"string\" && typeof i.key === \"string\" && i.createdAt > cutoff).slice(-this.maxItems) : [];\n this.offRecover = opts.health?.onRecover(() => {\n this.attempt = 0;\n this.retryIn(0);\n }) ?? null;\n if (this.items.length) this.retryIn(0);\n }\n\n get size(): number {\n return this.items.length;\n }\n\n /** Queues `POST path` and sends it now (or as soon as the API is reachable). */\n add(key: string, path: string, body: unknown): void {\n if (this.destroyed) return;\n this.items = this.items.filter((i) => i.key !== key);\n this.items.push({ key, path, body, createdAt: Date.now() });\n if (this.items.length > this.maxItems) this.items.splice(0, this.items.length - this.maxItems);\n this.persist();\n void this.flush();\n }\n\n private persist(): void {\n writeJson(this.opts.store, this.opts.storageKey, this.items);\n }\n\n private retryIn(ms: number): void {\n if (this.destroyed) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, ms);\n }\n\n /** Sends queued requests in order, one at a time. */\n async flush(): Promise<void> {\n if (this.destroyed || this.sending || !this.items.length) return;\n const wait = this.opts.health?.waitMs() ?? 0;\n if (wait > 0) return this.retryIn(wait);\n this.sending = true;\n try {\n while (this.items.length && !this.destroyed) {\n const item = this.items[0] as OutboxItem;\n let retry = false;\n try {\n const res = await this.opts.api.post(item.path, item.body);\n retry = !res.ok && (res.status === 429 || res.status >= 500);\n } catch (err) {\n retry = true;\n this.opts.onError?.(err);\n }\n if (retry) {\n this.attempt += 1;\n this.retryIn(Math.max(backoffMs(this.attempt - 1, 1000, 60_000), this.opts.health?.waitMs() ?? 0));\n return;\n }\n // Answered (or refused for good, e.g. the survey was deleted): done with it. A newer request\n // under the same key may have replaced it while this one was in flight; keep that one.\n this.attempt = 0;\n this.items = this.items.filter((i) => i !== item);\n this.persist();\n }\n } finally {\n this.sending = false;\n }\n }\n\n destroy(): void {\n this.destroyed = true;\n this.offRecover?.();\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n }\n}\n","import { type AppSnapshot, type AuthoringPick, type AuthoringSessionInfo, type ProjectTheme, type SelectorStrategy, type TargetingContext } from \"@guidelytech/shared\";\nimport { closestComposed, highlightSelectors, previewStep, runGuide, startAuthoring, type AuthoringSession, type GuideController, type PreviewHandle, type RunnableGuide } from \"@guidelytech/guide-runtime\";\nimport type { Api } from \"./http\";\nimport { captureSnapshot } from \"./snapshot\";\nimport { elementSnapshot } from \"./tagging\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\n/** Schemas are only needed in authoring mode; load them lazily so the normal runtime stays zod-free. */\nasync function loadSchemas() {\n const m = await import(\"@guidelytech/shared\");\n return { StepSchema: m.StepSchema, GuideConfigSchema: m.GuideConfigSchema };\n}\n\nexport const AUTHORING_PARAM = \"guidely_authoring\";\nexport const HEARTBEAT_MS = 15000;\n/** Quiet period after DOM changes / navigation before a new page snapshot is sent. */\nexport const SNAPSHOT_DEBOUNCE_MS = 800;\n/** Upper bound on how long continuous DOM churn can delay a snapshot. */\nexport const SNAPSHOT_MAX_WAIT_MS = 4000;\n\n/** Messages the SDK posts to the dashboard window (`window.opener`). */\nexport type AuthoringOutgoingMessage =\n | { type: \"guidely:authoring-ready\"; sessionId: string; url: string }\n | { type: \"guidely:pick\"; sessionId: string; pick: AuthoringPick }\n | { type: \"guidely:highlight-result\"; sessionId: string; counts: number[]; resolved: boolean }\n | { type: \"guidely:preview-ended\"; sessionId: string; reason: string }\n | { type: \"guidely:exit\"; sessionId: string }\n | { type: \"guidely:pong\"; sessionId: string; url: string }\n | { type: \"guidely:snapshot\"; sessionId: string; snapshot: AppSnapshot };\n\n/** Messages the dashboard may post to the app window (origin-checked against `dashboardOrigin`). */\nexport type AuthoringIncomingMessage =\n | { type: \"guidely:preview-step\"; step: unknown; theme?: Partial<ProjectTheme> | null; appearance?: unknown }\n | { type: \"guidely:preview-guide\"; guide: { id?: string; key?: string; name?: string; kind?: string; version?: number; config: unknown } }\n | { type: \"guidely:highlight\"; selectors: SelectorStrategy[] }\n | { type: \"guidely:stop-preview\" }\n | { type: \"guidely:ping\" }\n | { type: \"guidely:request-snapshot\" }\n | { type: \"guidely:exit\" };\n\nexport interface AuthoringBridgeOptions {\n api: Api;\n sessionStore: KeyValueStore;\n theme: () => Partial<ProjectTheme>;\n ctx: () => TargetingContext;\n maskSelectors: string[];\n onError: (err: unknown) => void;\n onActive: (active: boolean) => void;\n}\n\n/**\n * Detects `?guidely_authoring=<token>`, verifies the session with the public API, runs the\n * runtime's element picker and bridges picks/previews with the dashboard via `postMessage`.\n */\nexport class AuthoringBridge {\n private token: string | null = null;\n private info: AuthoringSessionInfo | null = null;\n private session: AuthoringSession | null = null;\n private heartbeat: ReturnType<typeof setInterval> | null = null;\n private preview: PreviewHandle | null = null;\n private previewGuide: GuideController | null = null;\n private active = false;\n private observer: MutationObserver | null = null;\n private snapshotTimer: ReturnType<typeof setTimeout> | null = null;\n private snapshotDue = 0;\n private lastSnapshot = \"\";\n\n constructor(private readonly opts: AuthoringBridgeOptions) {}\n\n isActive(): boolean {\n return this.active;\n }\n\n /** Returns true when a token was found (in the URL or the session marker) and verification started. */\n detect(): boolean {\n if (typeof window === \"undefined\") return false;\n let token: string | null = null;\n try {\n const url = new URL(window.location.href);\n token = url.searchParams.get(AUTHORING_PARAM);\n if (token) {\n url.searchParams.delete(AUTHORING_PARAM);\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n } catch {\n token = null;\n }\n if (!token) {\n const marker = readJson<{ token?: string } | null>(this.opts.sessionStore, KEYS.authoring, null);\n token = marker?.token ?? null;\n }\n if (!token) return false;\n this.token = token;\n writeJson(this.opts.sessionStore, KEYS.authoring, { token });\n void this.start();\n return true;\n }\n\n private async start(): Promise<void> {\n if (!this.token) return;\n try {\n const res = await this.opts.api.get<AuthoringSessionInfo>(\"/authoring/session\", { params: { token: this.token } });\n if (!res.ok || !res.data) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(`[Guidely] authoring session invalid or expired (${res.status})`));\n return;\n }\n this.info = res.data;\n if (Date.parse(this.info.expiresAt) < Date.now()) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(\"[Guidely] authoring session expired\"));\n return;\n }\n this.active = true;\n this.opts.onActive(true);\n this.session = startAuthoring({\n dashboardOrigin: this.info.dashboardOrigin,\n // Tag mode (Pages & Features): picks become feature rules; the page itself is tagged from the dashboard.\n message: this.info.purpose === \"tag\" ? \"Guidely tagging — click an element to tag it as a feature · tag the page from the dashboard · Esc to finish\" : undefined,\n onPick: (pick) => this.sendPick(pick),\n onExit: () => this.stop(),\n });\n this.heartbeat = setInterval(() => {\n void this.opts.api.post(\"/authoring/session/heartbeat\", {}, { params: { token: this.token ?? undefined } }).catch(() => {});\n }, HEARTBEAT_MS);\n this.post({ type: \"guidely:authoring-ready\", sessionId: this.info.id, url: window.location.href });\n this.watchPage();\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private masked(el: Element): boolean {\n return this.opts.maskSelectors.some((sel) => {\n try {\n return !!closestComposed(el, sel);\n } catch {\n return false;\n }\n });\n }\n\n private sendPick(raw: AuthoringPick & { element: Element }): void {\n if (!this.info || !this.token) return;\n const { element, ...rest } = raw;\n const pick: AuthoringPick = this.masked(element) ? { ...rest, textSnapshot: \"\", selectors: rest.selectors.filter((s) => s.kind !== \"text\") } : rest;\n pick.url = window.location.href;\n // Tag mode: a compact description of the element, so the dashboard can propose CSS rules for it.\n if (this.info.purpose === \"tag\") pick.elementSnapshot = elementSnapshot(element, { mask: this.opts.maskSelectors.join(\",\"), maskAll: false, featureAttribute: null }) as unknown as Record<string, unknown>;\n this.post({ type: \"guidely:pick\", sessionId: this.info.id, pick });\n void this.opts.api.post(\"/authoring/session/picks\", pick, { params: { token: this.token } }).catch((err) => this.opts.onError(err));\n }\n\n /** Sends a snapshot now and again whenever the page settles after DOM changes or navigation. */\n private watchPage(): void {\n this.scheduleSnapshot();\n if (typeof MutationObserver === \"undefined\") return;\n this.observer = new MutationObserver(() => this.scheduleSnapshot());\n this.observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true, characterData: true });\n }\n\n private scheduleSnapshot(): void {\n const now = Date.now();\n if (!this.snapshotTimer) this.snapshotDue = now + SNAPSHOT_MAX_WAIT_MS;\n else clearTimeout(this.snapshotTimer);\n this.snapshotTimer = setTimeout(() => this.sendSnapshot(), Math.max(0, Math.min(SNAPSHOT_DEBOUNCE_MS, this.snapshotDue - now)));\n }\n\n private sendSnapshot(): void {\n if (this.snapshotTimer) clearTimeout(this.snapshotTimer);\n this.snapshotTimer = null;\n if (!this.info || !this.active) return;\n try {\n const snapshot = captureSnapshot(document, this.opts.maskSelectors);\n if (!snapshot || snapshot.html === this.lastSnapshot) return;\n this.lastSnapshot = snapshot.html;\n this.post({ type: \"guidely:snapshot\", sessionId: this.info.id, snapshot });\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private post(message: AuthoringOutgoingMessage): void {\n if (!this.info) return;\n try {\n window.opener?.postMessage(message, this.info.dashboardOrigin);\n } catch {\n /* opener may be gone */\n }\n }\n\n private stopPreview(): void {\n this.preview?.destroy();\n this.preview = null;\n this.previewGuide?.destroy();\n this.previewGuide = null;\n this.session?.setPicking(true);\n }\n\n /** Handles `message` events; ignores anything not from `dashboardOrigin`. */\n async handleMessage(e: MessageEvent): Promise<void> {\n if (!this.active || !this.info) return;\n if (e.origin !== this.info.dashboardOrigin) return;\n const msg = e.data as AuthoringIncomingMessage | null;\n if (!msg || typeof msg !== \"object\" || typeof msg.type !== \"string\") return;\n try {\n switch (msg.type) {\n case \"guidely:preview-step\": {\n this.stopPreview();\n const { StepSchema, GuideConfigSchema } = await loadSchemas();\n const step = StepSchema.parse(msg.step);\n const appearance = msg.appearance ? GuideConfigSchema.shape.appearance.parse(msg.appearance) : undefined;\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing step “${step.title || step.id}” — close it to continue picking`);\n this.preview = previewStep(step, { ...this.opts.theme(), ...(msg.theme || {}) }, {\n appearance,\n onEnd: () => {\n this.preview = null;\n this.session?.setPicking(true);\n this.session?.setStatus(\"Guidely authoring — hover an element and click to select · Esc to cancel\");\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason: \"step\" });\n },\n });\n break;\n }\n case \"guidely:preview-guide\": {\n this.stopPreview();\n const g = msg.guide;\n const guide: RunnableGuide = { id: g.id || \"preview\", key: g.key || \"preview\", name: g.name || \"Preview\", kind: g.kind || \"flow\", version: g.version ?? 0, config: (await loadSchemas()).GuideConfigSchema.parse(g.config) };\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing “${guide.name}”`);\n this.previewGuide = runGuide(guide, {\n theme: this.opts.theme(),\n ctx: this.opts.ctx,\n onNavigate: (url, newTab) => (newTab ? window.open(url, \"_blank\", \"noopener\") : window.location.assign(url)),\n onEnd: (reason) => {\n this.previewGuide = null;\n this.session?.setPicking(true);\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason });\n },\n });\n this.previewGuide.start();\n break;\n }\n case \"guidely:highlight\": {\n const result = highlightSelectors(Array.isArray(msg.selectors) ? msg.selectors : [], { durationMs: 3000 });\n this.post({ type: \"guidely:highlight-result\", sessionId: this.info.id, counts: result.counts, resolved: !!result.resolved });\n break;\n }\n case \"guidely:stop-preview\":\n this.stopPreview();\n break;\n case \"guidely:request-snapshot\":\n this.lastSnapshot = \"\";\n this.sendSnapshot();\n break;\n case \"guidely:ping\":\n this.post({ type: \"guidely:pong\", sessionId: this.info.id, url: window.location.href });\n break;\n case \"guidely:exit\":\n this.stop();\n break;\n default:\n break;\n }\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n /** Leaves authoring mode and clears the session marker. */\n stop(): void {\n if (!this.active) return;\n this.active = false;\n this.stopPreview();\n this.observer?.disconnect();\n this.observer = null;\n if (this.snapshotTimer) clearTimeout(this.snapshotTimer);\n this.snapshotTimer = null;\n if (this.heartbeat) clearInterval(this.heartbeat);\n this.heartbeat = null;\n this.session?.stop();\n this.session = null;\n this.opts.sessionStore.remove(KEYS.authoring);\n if (this.info) this.post({ type: \"guidely:exit\", sessionId: this.info.id });\n this.opts.onActive(false);\n }\n}\n","import type { AppSnapshot } from \"@guidelytech/shared\";\n\n/** Snapshots larger than this are not sent (postMessage copies the string). */\nexport const MAX_SNAPSHOT_BYTES = 6 * 1024 * 1024;\n\nconst STRIP = \"script, noscript, template, #guidely-root, [data-guidely], meta[http-equiv], link[rel~='preload'], link[rel~='modulepreload'], link[rel~='prefetch'], link[rel~='manifest'], link[rel~='serviceworker']\";\n\n/** Text of a stylesheet built through the CSSOM (CSS-in-JS often leaves `<style>` empty). */\nfunction rulesText(sheet: CSSStyleSheet | null | undefined): string | null {\n if (!sheet) return null;\n try {\n return Array.from(sheet.cssRules, (r) => r.cssText).join(\"\\n\");\n } catch {\n return null; // cross-origin sheet\n }\n}\n\n/** Replaces text inside masked elements with bullets of the same length, keeping the layout. */\nfunction maskText(root: Element): void {\n const walker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n for (let n = walker.nextNode(); n; n = walker.nextNode()) {\n n.textContent = (n.textContent ?? \"\").replace(/\\S/g, \"•\");\n }\n}\n\n/**\n * Serializes the current page into a static HTML document for the dashboard's editor canvas.\n * Scripts, event handlers, Guidely's own UI and form values are dropped; `maskSelectors` text is\n * replaced with bullets. Same-origin CSSOM rules are inlined; everything else resolves through a\n * `<base href>` so stylesheets and images load from the app.\n */\nexport function captureSnapshot(doc: Document, maskSelectors: string[], maxBytes = MAX_SNAPSHOT_BYTES): AppSnapshot | null {\n const win = doc.defaultView;\n if (!win || !doc.documentElement) return null;\n const clone = doc.documentElement.cloneNode(true) as HTMLElement;\n\n // Elements whose state lives outside their markup are matched to the clone by document order,\n // so do this before anything is removed from the clone.\n const origStyles = doc.documentElement.querySelectorAll(\"style\");\n clone.querySelectorAll(\"style\").forEach((el, i) => {\n const css = rulesText(origStyles[i]?.sheet as CSSStyleSheet | null);\n if (css !== null && css.length > (el.textContent ?? \"\").length) el.textContent = css;\n });\n const origFrames = doc.documentElement.querySelectorAll(\"iframe, canvas, video, embed, object\");\n clone.querySelectorAll(\"iframe, canvas, video, embed, object\").forEach((el, i) => {\n const r = origFrames[i]?.getBoundingClientRect();\n const box = doc.createElement(\"div\");\n box.setAttribute(\"style\", `${el.getAttribute(\"style\") ?? \"\"};width:${r?.width ?? 0}px;height:${r?.height ?? 0}px;background:#e2e8f0;border-radius:4px`);\n if (el.getAttribute(\"class\")) box.setAttribute(\"class\", el.getAttribute(\"class\")!);\n el.replaceWith(box);\n });\n\n clone.querySelectorAll(STRIP).forEach((el) => el.remove());\n for (const sel of maskSelectors) {\n try {\n clone.querySelectorAll(sel).forEach(maskText);\n } catch {\n /* invalid selector */\n }\n }\n clone.querySelectorAll(\"*\").forEach((el) => {\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith(\"on\") || ((name === \"href\" || name === \"src\" || name === \"action\") && /^\\s*javascript:/i.test(attr.value))) el.removeAttribute(attr.name);\n }\n if (el instanceof HTMLInputElement) {\n el.removeAttribute(\"value\");\n el.removeAttribute(\"checked\");\n } else if (el instanceof HTMLTextAreaElement) {\n el.textContent = \"\";\n }\n el.removeAttribute(\"autofocus\");\n });\n\n const adopted = Array.from((doc as Document & { adoptedStyleSheets?: CSSStyleSheet[] }).adoptedStyleSheets ?? [])\n .map(rulesText)\n .filter(Boolean)\n .join(\"\\n\");\n let head = clone.querySelector(\"head\");\n if (!head) {\n head = doc.createElement(\"head\");\n clone.prepend(head);\n }\n if (adopted) {\n const style = doc.createElement(\"style\");\n style.textContent = adopted;\n head.append(style);\n }\n clone.querySelectorAll(\"base\").forEach((el) => el.remove());\n const base = doc.createElement(\"base\");\n base.setAttribute(\"href\", doc.baseURI || win.location.href);\n base.setAttribute(\"target\", \"_blank\");\n head.prepend(base);\n\n const html = `<!DOCTYPE html>\\n${clone.outerHTML}`;\n if (html.length > maxBytes) return null;\n return { html, url: win.location.href, title: doc.title, width: win.innerWidth, height: win.innerHeight, capturedAt: new Date().toISOString() };\n}\n","import { NOISY_DATA_ATTR, SNAPSHOT_LIMITS, TAG_PROPERTY_LIMITS, featureRuleMatchesClick, pageRuleMatches, pageRulesMatch, type ElementNode, type ElementSnapshot, type TaggingSdkConfig } from \"@guidelytech/shared/runtime\";\nimport { closestComposed, isStableClass, isStableId, querySelectorStrategy } from \"@guidelytech/guide-runtime\";\nimport type { ClickProperties } from \"./autocapture\";\nimport { elementText } from \"./autocapture\";\n\n/**\n * Tagged pages and features in the browser: the compact element snapshot attached to clicks (so CSS\n * selector rules written later still match them), the feature attribute, and the DOM properties a\n * project asked to read on matching clicks and page views.\n */\n\n/** Text-like attributes dropped from masked elements. */\nconst TEXT_ATTRS = new Set([\"aria-label\", \"title\", \"alt\"]);\nconst SAFE_ATTRS = [\"role\", \"name\", \"type\", \"aria-label\", \"title\", \"alt\", \"for\"];\n/** Classes that only describe a passing state; they would split one element into many. */\nconst STATE_CLASS = /^(is-|has-)?(active|hover|hovered|focus|focused|focus-visible|selected|open|opened|closed|disabled|visible|hidden|show|shown|collapsed|expanded|checked|pressed|loading|current)$/i;\n\nfunction nthOfType(el: Element): number | undefined {\n const parent = el.parentElement;\n if (!parent) return undefined;\n let n = 0;\n for (const c of Array.from(parent.children)) {\n if (c.tagName === el.tagName) n++;\n if (c === el) return n;\n }\n return undefined;\n}\n\nfunction nodeOf(el: Element, masked: boolean, featureAttribute: string | null): ElementNode {\n const node: ElementNode = { t: el.tagName.toLowerCase().slice(0, SNAPSHOT_LIMITS.tag) };\n if (el.id && isStableId(el.id) && el.id.length <= SNAPSHOT_LIMITS.id) node.id = el.id;\n const classes = Array.from(el.classList).filter((c) => isStableClass(c) && !STATE_CLASS.test(c) && c.length <= SNAPSHOT_LIMITS.className);\n if (classes.length) node.c = classes.slice(0, SNAPSHOT_LIMITS.classes);\n const a: Record<string, string> = {};\n const put = (name: string, value: string | null) => {\n if (value === null || Object.keys(a).length >= SNAPSHOT_LIMITS.attrs || name in a) return;\n if (masked && TEXT_ATTRS.has(name)) return;\n a[name] = value.slice(0, SNAPSHOT_LIMITS.attrValue);\n };\n // The feature attribute first: auto-tagged features are matched on it.\n if (featureAttribute && el.hasAttribute(featureAttribute)) put(featureAttribute, el.getAttribute(featureAttribute));\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"data-\") && !NOISY_DATA_ATTR.test(attr.name) && attr.value.length <= SNAPSHOT_LIMITS.attrValue) put(attr.name, attr.value);\n }\n for (const name of SAFE_ATTRS) if (el.hasAttribute(name)) put(name, el.getAttribute(name));\n if (Object.keys(a).length) node.a = a;\n const n = nthOfType(el);\n if (n) node.n = n;\n return node;\n}\n\n/**\n * Compact snapshot of an element: itself, up to 5 ancestors in its own tree and up to 3 shadow\n * hosts. Never values of form fields; text-like attributes are left out under masking.\n */\nexport function elementSnapshot(el: Element, opts: { mask: string; maskAll: boolean; featureAttribute: string | null }): ElementSnapshot {\n const masked = opts.maskAll || isMasked(el, opts.mask);\n const snap: ElementSnapshot = nodeOf(el, masked, opts.featureAttribute);\n const p: ElementNode[] = [];\n for (let cur = el.parentElement; cur && p.length < SNAPSHOT_LIMITS.ancestors; cur = cur.parentElement) {\n if (cur.tagName === \"BODY\" || cur.tagName === \"HTML\") break;\n p.push(nodeOf(cur, masked, opts.featureAttribute));\n }\n if (p.length) snap.p = p;\n const h: ElementNode[] = [];\n let root = el.getRootNode?.() as (Node & { host?: Element }) | undefined;\n while (root && root.nodeType === 11 && root.host && h.length < SNAPSHOT_LIMITS.hosts) {\n h.push(nodeOf(root.host, masked, opts.featureAttribute));\n root = root.host.getRootNode?.() as (Node & { host?: Element }) | undefined;\n }\n if (h.length) snap.h = h;\n return snap;\n}\n\nfunction isMasked(el: Element, mask: string): boolean {\n if (!mask) return false;\n try {\n return !!closestComposed(el, mask);\n } catch {\n return false;\n }\n}\n\n/** The element carrying the feature attribute at or above the click target, and its value. */\nexport function featureAttributeOf(target: Element, attribute: string | null): { el: Element; value: string } | null {\n if (!attribute) return null;\n try {\n const el = closestComposed(target, `[${attribute}]`);\n const value = el?.getAttribute(attribute)?.replace(/\\s+/g, \" \").trim();\n return el && value ? { el, value: value.slice(0, 100) } : null;\n } catch {\n return null;\n }\n}\n\nfunction readProperty(def: { selector?: string; source: \"text\" | \"attribute\"; attribute?: string }, base: Element | null, opts: { mask: string; maskAll: boolean }): string | undefined {\n let el: Element | null = base;\n if (def.selector) {\n try {\n el = querySelectorStrategy({ kind: \"css\", value: def.selector }, document)[0] ?? null;\n } catch {\n el = null;\n }\n }\n if (!el) return undefined;\n if (def.source === \"attribute\") {\n const name = (def.attribute ?? \"\").toLowerCase();\n if (!name || name === \"value\" || name.startsWith(\"on\")) return undefined;\n if (opts.maskAll || isMasked(el, opts.mask)) return undefined;\n const v = el.getAttribute(name);\n return v ? v.replace(/\\s+/g, \" \").trim().slice(0, TAG_PROPERTY_LIMITS.value) || undefined : undefined;\n }\n return elementText(el, opts.mask, opts.maskAll);\n}\n\n/** DOM properties for a click on `el` (features whose rules match it), keyed by property id. */\nexport function clickPropertyValues(config: TaggingSdkConfig | undefined, el: Element, click: ClickProperties, opts: { mask: string; maskAll: boolean }): Record<string, string> | undefined {\n if (!config?.properties.length) return undefined;\n const out: Record<string, string> = {};\n const css = (selector: string) => {\n try {\n return !!closestComposed(el, selector);\n } catch {\n return false;\n }\n };\n const here = { url: location.href, path: location.pathname, title: document.title };\n for (const tag of config.properties) {\n if (tag.kind !== \"feature\" || !tag.featureRules) continue;\n const rules = tag.featureRules;\n const matches = (r: (typeof rules)[number]) => featureRuleMatchesClick(r, click, css) && (!r.page?.pattern || pageRuleMatches({ type: \"url\", value: r.page.pattern }, here));\n if (!rules.some((r) => !r.exclude && matches(r)) || rules.some((r) => r.exclude && matches(r))) continue;\n for (const def of tag.properties) {\n const v = readProperty(def, el, opts);\n if (v) out[def.id] = v;\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n\n/** DOM properties for a page view of `url` (pages whose rules match it), keyed by property id. */\nexport function pagePropertyValues(config: TaggingSdkConfig | undefined, url: string, opts: { mask: string; maskAll: boolean }): Record<string, string> | undefined {\n if (!config?.properties.length) return undefined;\n const out: Record<string, string> = {};\n let path = \"/\";\n try {\n path = new URL(url, location.href).pathname;\n } catch {\n /* keep / */\n }\n const ctx = { url, path, title: document.title };\n for (const tag of config.properties) {\n if (tag.kind !== \"page\" || !tag.pageRules || !pageRulesMatch(tag.pageRules, ctx)) continue;\n for (const def of tag.properties) {\n if (!def.selector) continue;\n const v = readProperty(def, null, opts);\n if (v) out[def.id] = v;\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n","import { closestComposed, isGuidelyElement, isStableId, SHADOW_SEPARATOR, shadowHostChain } from \"@guidelytech/guide-runtime\";\n\n/** Elements whose clicks are autocaptured (the click may land on a descendant). */\nexport const INTERACTIVE_SELECTOR =\n \"a,button,input[type=button],input[type=submit],input[type=reset],input[type=checkbox],input[type=radio],select,summary,label,[role=button],[role=link],[role=tab],[role=menuitem],[role=checkbox],[role=switch],[role=option],[onclick],[data-guidely-track]\";\n\n/** Always-on mask selectors (text never captured, masked in replays). */\nexport const DEFAULT_MASK_SELECTORS = [\"[data-guidely-mask]\", \".guidely-mask\"];\n\n/** `click` / `rage_click` event properties. */\nexport interface ClickProperties {\n tag: string;\n text?: string;\n selector: string;\n href?: string;\n x: number;\n y: number;\n count?: number;\n}\n\nconst PREFERRED_ATTRS = [\"data-testid\", \"data-test-id\", \"data-test\", \"data-cy\", \"data-qa\", \"data-guidely-track\", \"data-tour\"];\nconst NOISY_DATA_ATTR = /^data-(state|v-|react|radix|headlessui|svelte|orientation|highlighted|focus|key|index|side|align|disabled|selected|active|open|guidely-(mask|ignore|block))/i;\n\n/** Drops empty and syntactically invalid CSS selectors. */\nexport function validSelectors(list: Array<string | null | undefined>): string[] {\n const out: string[] = [];\n const probe = typeof document !== \"undefined\" ? document.createDocumentFragment() : null;\n for (const raw of list) {\n const s = (raw || \"\").trim();\n if (!s || out.includes(s)) continue;\n try {\n probe?.querySelector(s);\n out.push(s);\n } catch {\n /* invalid selector */\n }\n }\n return out;\n}\n\n/** True for clicks Guidely must never capture: its own UI and anything under `[data-guidely-ignore]`. */\nexport function isIgnoredElement(el: Element): boolean {\n return isGuidelyElement(el) || !!closestComposed(el, \"[data-guidely-ignore]\");\n}\n\n/** The interactive element a click landed on (or inside), if any. */\nexport function interactiveElement(target: Element): Element | null {\n try {\n return closestComposed(target, INTERACTIVE_SELECTOR);\n } catch {\n return null;\n }\n}\n\nfunction esc(value: string): string {\n const g = globalThis as { CSS?: { escape?: (v: string) => string } };\n return g.CSS?.escape ? g.CSS.escape(value) : value.replace(/[^\\w-]/g, (c) => `\\\\${c}`);\n}\n\nconst attr = (tag: string, name: string, value: string) => (value ? `${tag}[${name}=\"${value.replace(/[\"\\\\]/g, \"\\\\$&\")}\"]` : `${tag}[${name}]`);\n\n/**\n * Stable selector: id → test/tracking data attributes → other data-* → aria-label → short CSS path.\n * Inside a shadow root it is prefixed with the host chain (`c-app >>> button.save`).\n */\nexport function elementSelector(el: Element): string {\n const own = ownSelector(el);\n const chain = shadowHostChain(el);\n return (chain ? chain + SHADOW_SEPARATOR + own : own).slice(0, 300);\n}\n\nfunction ownSelector(el: Element): string {\n const tag = el.tagName.toLowerCase();\n if (el.id && isStableId(el.id)) return `#${esc(el.id)}`;\n for (const name of PREFERRED_ATTRS) if (el.hasAttribute(name)) return attr(tag, name, el.getAttribute(name) || \"\");\n for (const a of Array.from(el.attributes)) {\n if (a.name.startsWith(\"data-\") && !NOISY_DATA_ATTR.test(a.name) && a.value && a.value.length <= 60) return attr(tag, a.name, a.value);\n }\n const label = el.getAttribute(\"aria-label\");\n if (label && label.length <= 80) return attr(tag, \"aria-label\", label);\n const parts: string[] = [];\n let cur: Element | null = el;\n while (cur && parts.length < 4) {\n const t = cur.tagName.toLowerCase();\n if (t === \"html\" || t === \"body\") break;\n if (cur !== el && cur.id && isStableId(cur.id)) {\n parts.unshift(`#${esc(cur.id)}`);\n break;\n }\n const parent: Element | null = cur.parentElement;\n const node: Element = cur;\n const same = parent ? Array.from(parent.children).filter((c) => c.tagName === node.tagName) : [];\n parts.unshift(same.length > 1 ? `${t}:nth-of-type(${same.indexOf(node) + 1})` : t);\n cur = parent;\n }\n return parts.join(\" > \") || tag;\n}\n\nfunction matches(el: Element, selector: string, deep: boolean): boolean {\n if (!selector) return false;\n try {\n return !!closestComposed(el, selector) || (deep && !!el.querySelector(selector));\n } catch {\n return false;\n }\n}\n\n/**\n * Visible text of a clicked element (≤100 chars, whitespace collapsed). Never the value of a form\n * field (only button-like inputs), and nothing when the element is (or contains) masked content.\n */\nexport function elementText(el: Element, mask: string, maskAll: boolean): string | undefined {\n if (maskAll || matches(el, mask, true)) return undefined;\n const tag = el.tagName.toLowerCase();\n let text = \"\";\n if (tag === \"input\") {\n if (!/^(button|submit|reset)$/i.test((el as HTMLInputElement).type || \"\")) return undefined;\n text = (el as HTMLInputElement).value;\n } else if (tag === \"select\" || tag === \"textarea\") return undefined;\n else text = (el as HTMLElement).innerText ?? el.textContent ?? \"\";\n text = (text || el.getAttribute(\"aria-label\") || el.getAttribute(\"title\") || \"\").replace(/\\s+/g, \" \").trim();\n return text ? text.slice(0, 100) : undefined;\n}\n\n/** Link target for analytics: the path for same-origin links, only the origin otherwise. */\nexport function linkHref(el: Element): string | undefined {\n const a = closestComposed(el, \"a[href]\");\n if (!a) return undefined;\n try {\n const u = new URL(a.getAttribute(\"href\") || \"\", location.href);\n if (!/^https?:$/.test(u.protocol)) return undefined;\n return u.origin === location.origin ? u.pathname : u.origin;\n } catch {\n return undefined;\n }\n}\n\n/** Builds `click` properties for an element. */\nexport function describeClick(el: Element, e: MouseEvent, opts: { mask: string; maskAll: boolean; collectUrls: boolean }): ClickProperties {\n const props: ClickProperties = { tag: el.tagName.toLowerCase(), selector: elementSelector(el), x: Math.round(e.pageX ?? 0) || 0, y: Math.round(e.pageY ?? 0) || 0 };\n const text = elementText(el, opts.mask, opts.maskAll);\n if (text) props.text = text;\n const href = opts.collectUrls ? linkHref(el) : undefined;\n if (href) props.href = href;\n return props;\n}\n\n/** Detects rage clicks: 3+ clicks within 1s and 30px of each other, reported once per burst. */\nexport class RageClickDetector {\n private clicks: Array<{ x: number; y: number; t: number }> = [];\n private fired = false;\n\n constructor(\n private readonly threshold = 3,\n private readonly windowMs = 1000,\n private readonly radius = 30,\n ) {}\n\n /** Clicks in the current burst once it has fired (rage), otherwise 0. */\n get burst(): number {\n return this.fired ? this.clicks.length : 0;\n }\n\n /** Records a click; returns the click count when it completes a burst, otherwise 0. */\n add(x: number, y: number, t: number): number {\n const first = this.clicks[0];\n const last = this.clicks[this.clicks.length - 1];\n if (!first || !last || t - last.t > this.windowMs || Math.hypot(x - first.x, y - first.y) > this.radius) {\n this.clicks = [];\n this.fired = false;\n }\n this.clicks = this.clicks.filter((c) => t - c.t <= this.windowMs);\n this.clicks.push({ x, y, t });\n if (this.fired || this.clicks.length < this.threshold) return 0;\n this.fired = true;\n return this.clicks.length;\n }\n}\n","import { CAPTURE_PARAM } from \"@guidelytech/shared/runtime\";\nimport { AUTHORING_PARAM } from \"./authoring\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\nexport { CAPTURE_PARAM };\n\n/** What the SDK remembers about a capture session in this tab (`guidely:capture` in sessionStorage). */\nexport interface CaptureMarker {\n token: string;\n /** Recording has started (a page load continues it instead of showing \"Start recording\"). */\n started?: boolean;\n /** The user chose to take screenshots. */\n screenshots?: boolean;\n /** Epoch ms and action of the last recorded step. */\n lastStepAt?: number;\n lastAction?: string;\n}\n\n/**\n * Finds a capture token in the URL (and strips it) or in this tab's session marker. A capture\n * param wins over an authoring param; a leftover marker does not win over a fresh authoring link.\n */\nexport function takeCaptureToken(sessionStore: KeyValueStore): CaptureMarker | null {\n if (typeof window === \"undefined\") return null;\n let token: string | null = null;\n let authoringLink = false;\n try {\n const url = new URL(window.location.href);\n token = url.searchParams.get(CAPTURE_PARAM);\n authoringLink = url.searchParams.has(AUTHORING_PARAM);\n if (token) {\n url.searchParams.delete(CAPTURE_PARAM);\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n } catch {\n token = null;\n }\n const saved = readJson<CaptureMarker | null>(sessionStore, KEYS.capture, null);\n let marker: CaptureMarker | null = null;\n if (token) marker = saved?.token === token ? saved : { token };\n else if (saved?.token && !authoringLink) marker = saved;\n if (!marker) {\n if (saved) {\n sessionStore.remove(KEYS.capture);\n sessionStore.remove(KEYS.capturePending);\n }\n return null;\n }\n if (token && saved?.token !== token) sessionStore.remove(KEYS.capturePending);\n writeJson(sessionStore, KEYS.capture, marker);\n sessionStore.remove(KEYS.authoring);\n return marker;\n}\n","import type { CaptureApi } from \"./capture\";\n\n/**\n * Loads the how-to capture chunk on demand (only in a capture session). Like the replay recorder,\n * the import is rewritten per build: `./capture.js` (npm; consumers' bundlers code-split it) or, in\n * the script-tag build, a loader that injects `guidely-capture.js` and resolves `window.__guidelyCapture`.\n */\nexport const loadCapture = async (): Promise<CaptureApi> => (await import(\"./capture\")).capture;\n","import type { TargetingContext } from \"@guidelytech/shared\";\n\nexport interface DeviceInfo {\n type: \"desktop\" | \"tablet\" | \"mobile\";\n browser?: string;\n os?: string;\n}\n\n/** Lightweight UA sniffing (good enough for targeting; not for feature detection). */\nexport function detectDevice(ua: string, width: number): DeviceInfo {\n const u = ua || \"\";\n let type: DeviceInfo[\"type\"] = \"desktop\";\n if (/iPad|Tablet|PlayBook|Silk/i.test(u) || (/Android/i.test(u) && !/Mobile/i.test(u))) type = \"tablet\";\n else if (/Mobi|iPhone|iPod|Android.*Mobile|Windows Phone/i.test(u)) type = \"mobile\";\n else if (width > 0 && width < 768) type = \"mobile\";\n else if (width > 0 && width < 1024) type = \"tablet\";\n let browser: string | undefined;\n if (/Electron\\//i.test(u)) browser = \"electron\";\n else if (/Edg\\//i.test(u)) browser = \"edge\";\n else if (/OPR\\/|Opera/i.test(u)) browser = \"opera\";\n else if (/SamsungBrowser/i.test(u)) browser = \"samsung\";\n else if (/Chrome\\/|CriOS/i.test(u)) browser = \"chrome\";\n else if (/Firefox\\/|FxiOS/i.test(u)) browser = \"firefox\";\n else if (/Safari\\//i.test(u) && /Version\\//i.test(u)) browser = \"safari\";\n else if (/MSIE|Trident/i.test(u)) browser = \"ie\";\n let os: string | undefined;\n if (/Windows/i.test(u)) os = \"windows\";\n else if (/iPhone|iPad|iPod/i.test(u)) os = \"ios\";\n else if (/Mac OS X|Macintosh/i.test(u)) os = \"macos\";\n else if (/Android/i.test(u)) os = \"android\";\n else if (/CrOS/i.test(u)) os = \"chromeos\";\n else if (/Linux/i.test(u)) os = \"linux\";\n return { type, browser, os };\n}\n\nexport interface ContextInput {\n anonymousId: string;\n userId?: string | null;\n userAttributes: Record<string, unknown>;\n accountAttributes: Record<string, unknown>;\n url: string;\n firstVisit: boolean;\n eventsSeen: Iterable<string>;\n completedGuides: Iterable<string>;\n dismissedGuides: Iterable<string>;\n seenGuides: Iterable<string>;\n completedChecklists: Iterable<string>;\n audienceIds: Iterable<string>;\n environment: string;\n locale?: string;\n device?: DeviceInfo;\n now?: Date;\n platform?: string;\n screen?: string;\n appVersion?: string;\n}\n\n/** Builds the `TargetingContext` consumed by `evaluateRules`. */\nexport function buildContext(input: ContextInput): TargetingContext {\n let path = \"\";\n const query: Record<string, string> = {};\n try {\n const u = new URL(input.url, \"http://localhost\");\n path = u.pathname;\n u.searchParams.forEach((v, k) => {\n query[k] = v;\n });\n } catch {\n path = input.url;\n }\n const device = input.device ?? (typeof navigator !== \"undefined\" ? detectDevice(navigator.userAgent, typeof window !== \"undefined\" ? window.innerWidth : 0) : { type: \"desktop\" });\n return {\n anonymousId: input.anonymousId,\n userId: input.userId ?? null,\n userAttributes: input.userAttributes,\n accountAttributes: input.accountAttributes,\n url: input.url,\n path,\n query,\n device,\n firstVisit: input.firstVisit,\n eventsSeen: new Set(input.eventsSeen),\n completedGuides: new Set(input.completedGuides),\n dismissedGuides: new Set(input.dismissedGuides),\n seenGuides: new Set(input.seenGuides),\n completedChecklists: new Set(input.completedChecklists),\n audienceIds: new Set(input.audienceIds),\n now: input.now ?? new Date(),\n environment: input.environment,\n locale: input.locale ?? (typeof navigator !== \"undefined\" ? navigator.language : undefined),\n platform: input.platform ?? \"web\",\n ...(input.screen !== undefined ? { screen: input.screen } : {}),\n ...(input.appVersion !== undefined ? { appVersion: input.appVersion } : {}),\n };\n}\n","import type { HeatmapPoint } from \"@guidelytech/shared\";\nimport { elementSelector } from \"./autocapture\";\n\n/** Points per `heatmap` event, and the JSON size at which a batch is sent early (properties cap at 8KB). */\nexport const HEATMAP_MAX_POINTS = 40;\nexport const HEATMAP_MAX_BYTES = 6000;\n/** Movement bins per batch before it is sent. */\nexport const HEATMAP_MAX_BINS = 60;\n\nconst r2 = (n: number) => Math.round(Math.min(1, Math.max(0, n)) * 100) / 100;\n\n/** One heatmap point: page coordinates, a stable selector and the position inside the element (0–1). */\nexport function heatmapPoint(el: Element, e: MouseEvent, rage: boolean): HeatmapPoint {\n const p: HeatmapPoint = { k: rage ? \"r\" : \"c\", x: Math.round(e.pageX ?? 0) || 0, y: Math.round(e.pageY ?? 0) || 0 };\n const s = elementSelector(el).slice(0, 120);\n if (s) p.s = s;\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n p.rx = r2((e.clientX - rect.left) / rect.width);\n p.ry = r2((e.clientY - rect.top) / rect.height);\n }\n return p;\n}\n\nconst selectors = new WeakMap<Element, string>();\nconst r1 = (n: number) => Math.round(Math.min(1, Math.max(0, n)) * 10) / 10;\n\n/**\n * Movement bin for a pointer sample: per element at 0.1 of the element box (selectors cached per\n * element), or a 16px page-grid cell for `html`/`body` and elements without a box or selector.\n */\nexport function movementBin(el: Element, e: MouseEvent): [string, HeatmapPoint] {\n const p: HeatmapPoint = { k: \"m\", x: Math.round(e.pageX ?? 0) || 0, y: Math.round(e.pageY ?? 0) || 0 };\n let s = /^(HTML|BODY)$/.test(el.tagName) ? \"\" : selectors.get(el);\n if (s === undefined) selectors.set(el, (s = elementSelector(el).slice(0, 120)));\n const rect = s ? el.getBoundingClientRect() : null;\n if (!rect || !(rect.width > 0 && rect.height > 0)) return [`${p.x >> 4},${p.y >> 4}`, p];\n p.s = s;\n p.rx = r1((e.clientX - rect.left) / rect.width);\n p.ry = r1((e.clientY - rect.top) / rect.height);\n return [`${s} ${p.rx},${p.ry}`, p];\n}\n\n/** Click positions and movement bins on the current page, sent as one `heatmap` event per batch. */\nexport class HeatmapBuffer {\n /** The page the buffered points belong to. */\n url = \"\";\n points: HeatmapPoint[] = [];\n private bins = new Map<string, HeatmapPoint>();\n private bytes = 0;\n\n /** Adds a click (`burst` > 0 marks it and the burst's previous clicks as rage); true when the batch is full. */\n add(url: string, point: HeatmapPoint, burst: number): boolean {\n this.url = url;\n for (let i = Math.max(0, this.points.length - burst + 1); i < this.points.length; i++) (this.points[i] as HeatmapPoint).k = \"r\";\n this.points.push(point);\n this.bytes += JSON.stringify(point).length + 1;\n return this.full();\n }\n\n /** Adds a movement sample to its bin (weight +1); true when the batch is full. */\n move(url: string, [key, point]: [string, HeatmapPoint]): boolean {\n this.url = url;\n const bin = this.bins.get(key);\n if (bin) bin.w = (bin.w ?? 1) + 1;\n else {\n this.bins.set(key, point);\n this.bytes += JSON.stringify(point).length + 8; // + room for \"w\"\n }\n return this.full();\n }\n\n private full(): boolean {\n return this.points.length >= HEATMAP_MAX_POINTS || this.bins.size > HEATMAP_MAX_BINS || this.bytes >= HEATMAP_MAX_BYTES;\n }\n\n /** Empties the buffer, returning what was in it (clicks first, then movement bins). */\n take(): { url: string; points: HeatmapPoint[] } | null {\n const points = [...this.points, ...this.bins.values()];\n this.points = [];\n this.bins = new Map();\n this.bytes = 0;\n return points.length ? { url: this.url, points } : null;\n }\n}\n","import { parseStack, type ExceptionProperties, type StackFrame } from \"@guidelytech/shared/runtime\";\n\n/** Byte budget for the `frames` property (the event's properties are capped at 8KB). */\nconst MAX_FRAMES_BYTES = 6000;\n\nfunction fitFrames(frames: StackFrame[]): StackFrame[] {\n const out = frames.slice(0, 30);\n while (out.length > 1 && JSON.stringify(out).length > MAX_FRAMES_BYTES) out.pop();\n return out;\n}\n\nfunction describe(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** Converts anything thrown into `exception` properties. */\nexport function exceptionFromError(error: unknown, source: string, handled: boolean, fallbackType = \"Error\"): ExceptionProperties {\n const isError = error instanceof Error || (!!error && typeof error === \"object\" && typeof (error as Error).message === \"string\" && typeof (error as Error).stack === \"string\");\n const e = error as Error;\n return {\n type: (isError && e.name) || fallbackType,\n message: (isError ? e.message : describe(error)).slice(0, 1000),\n frames: isError ? fitFrames(parseStack(e.stack)) : [],\n source,\n handled,\n };\n}\n\n/** `window` `error` event → exception; `null` for resource-load errors and opaque \"Script error.\" reports. */\nexport function errorEventToException(e: ErrorEvent): ExceptionProperties | null {\n const target = e.target as unknown;\n if (target && typeof Element !== \"undefined\" && target instanceof Element) return null;\n if (e.error != null) return exceptionFromError(e.error, \"onerror\", false);\n const message = e.message || \"\";\n if (!message || /^script error\\.?$/i.test(message.trim())) return null;\n const m = /^(?:Uncaught )?([A-Z]\\w*(?:Error|Exception)):\\s*([\\s\\S]*)$/.exec(message);\n return {\n type: m?.[1] ?? \"Error\",\n message: (m?.[2] ?? message).slice(0, 1000),\n frames: e.filename ? [{ file: e.filename.slice(0, 500), line: e.lineno || undefined, col: e.colno || undefined }] : [],\n source: \"onerror\",\n handled: false,\n };\n}\n\n/** `unhandledrejection` → exception (`UnhandledRejection` for non-Error reasons). */\nexport function rejectionToException(e: PromiseRejectionEvent): ExceptionProperties {\n return exceptionFromError(e.reason, \"unhandledrejection\", false, \"UnhandledRejection\");\n}\n\nconst GUIDELY_SCRIPT = /\\/guidely(-recorder)?(\\.min)?\\.js$/i;\n\n/** Errors raised by Guidely itself (\"[Guidely] …\" messages, or thrown from the script-tag bundle). */\nexport function isGuidelyException(props: ExceptionProperties): boolean {\n if (props.message.startsWith(\"[Guidely]\")) return true;\n const file = props.frames[0]?.file;\n if (!file) return false;\n try {\n return GUIDELY_SCRIPT.test(new URL(file).pathname);\n } catch {\n return GUIDELY_SCRIPT.test(file.replace(/[?#].*$/, \"\"));\n }\n}\n\n/** Per-page-load throttle: the same exception (type + message + top frame) at most `max` times. */\nexport class ExceptionThrottle {\n private seen = new Map<string, number>();\n\n constructor(private readonly max = 5) {}\n\n allow(props: ExceptionProperties): boolean {\n const top = props.frames[0];\n const key = `${props.type}|${props.message}|${top ? `${top.file}:${top.line}:${top.col}` : \"\"}`;\n const n = this.seen.get(key) ?? 0;\n if (n >= this.max) return false;\n if (this.seen.size > 500) this.seen.clear();\n this.seen.set(key, n + 1);\n return true;\n }\n}\n","type AnyFn = (...args: any[]) => void;\n\n/** Tiny typed event emitter. Listener errors are reported, never thrown into the caller. */\nexport class Emitter<Events extends { [K in keyof Events]: AnyFn }> {\n private listeners = new Map<keyof Events, Set<AnyFn>>();\n constructor(private readonly onError?: (err: unknown) => void) {}\n\n on<K extends keyof Events>(event: K, cb: Events[K]): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(cb);\n return () => this.off(event, cb);\n }\n\n off<K extends keyof Events>(event: K, cb: Events[K]): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const cb of Array.from(set)) {\n try {\n cb(...args);\n } catch (err) {\n this.onError?.(err);\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { FrequencyConfig, GuideThrottlingSettings, PublishedGuide } from \"@guidelytech/shared\";\n\n/** Per-guide state kept locally and merged with the server's `IdentifyResponse.guideState`. */\nexport interface GuideLocalState {\n impressions: number;\n completedAt?: string | null;\n dismissedAt?: string | null;\n lastShownAt?: string | null;\n /** Last step reached in a multi-step flow (local only), so the messenger can offer to resume it. */\n lastStepId?: string | null;\n}\n\nconst HOUR = 3600 * 1000;\n\n/**\n * Pure frequency evaluation. `shownThisSession` comes from session storage.\n * - `once`: a single impression ever (unless `reshowAfterDismiss` and it was only dismissed).\n * - `once_per_session`: at most once per browser session.\n * - `every_time`: on every trigger (still blocked by completion/dismissal rules below).\n * - `interval`: at most once every `intervalHours`.\n * `maxImpressions` caps total impressions; dismissal blocks re-showing unless `reshowAfterDismiss`\n * (then `cooldownHours` must have elapsed); completion blocks unless mode is `every_time`.\n */\nexport function isFrequencyEligible(freq: FrequencyConfig, state: GuideLocalState | undefined, shownThisSession: boolean, now: number = Date.now()): boolean {\n const s = state ?? { impressions: 0 };\n if (freq.maxImpressions != null && s.impressions >= freq.maxImpressions) return false;\n if (s.completedAt && freq.mode !== \"every_time\") return false;\n if (s.dismissedAt) {\n if (!freq.reshowAfterDismiss) return false;\n if (freq.cooldownHours > 0 && now - Date.parse(s.dismissedAt) < freq.cooldownHours * HOUR) return false;\n }\n switch (freq.mode) {\n case \"once\":\n return s.impressions === 0 || (!!s.dismissedAt && freq.reshowAfterDismiss);\n case \"once_per_session\":\n return !shownThisSession;\n case \"interval\": {\n if (!s.lastShownAt) return true;\n const hours = freq.intervalHours ?? 24;\n return now - Date.parse(s.lastShownAt) >= hours * HOUR;\n }\n case \"every_time\":\n default:\n return true;\n }\n}\n\n/**\n * Exclusive guides (flows, modals, tooltips, announcements, surveys) run one at a time.\n * Banners, checklists and hotspot-only tooltips can coexist with an active flow.\n */\nexport function isExclusiveGuide(guide: PublishedGuide): boolean {\n if (guide.kind === \"banner\" || guide.kind === \"checklist\") return false;\n const steps = guide.config.steps;\n if (steps.length > 0 && steps.every((s) => s.type === \"hotspot\" || s.type === \"banner\")) return false;\n return true;\n}\n\n/** Is `a` mutually exclusive with `b` (by id or key, in either direction)? */\nexport function areMutuallyExclusive(a: PublishedGuide, b: PublishedGuide): boolean {\n const la = a.config.frequency.mutuallyExclusiveWith;\n const lb = b.config.frequency.mutuallyExclusiveWith;\n return la.includes(b.id) || la.includes(b.key) || lb.includes(a.id) || lb.includes(a.key);\n}\n\n/**\n * Scheduling window: the guide's `schedule` (any kind) and, for surveys, `survey.startAt` / `endAt`.\n * Unparsable dates are ignored.\n */\nexport function isWithinSchedule(guide: Pick<PublishedGuide, \"config\">, now: number = Date.now()): boolean {\n for (const w of [guide.config.schedule, guide.config.survey]) {\n if (!w) continue;\n if (w.startAt && now < Date.parse(w.startAt)) return false;\n if (w.endAt && now > Date.parse(w.endAt)) return false;\n }\n return true;\n}\n\nconst MINUTE = 60 * 1000;\n\n/**\n * Does showing this guide automatically count toward (and get limited by) the project's guide\n * throttling? Only exclusive guides (flows, modals, tooltips, announcements, surveys) interrupt;\n * banners, checklists and hotspot-only guides never count, nor does a guide set to ignore throttling.\n * Guides started by the visitor or the app (`startGuide`, buttons, Help) are never throttled.\n */\nexport function countsTowardThrottle(guide: PublishedGuide): boolean {\n return isExclusiveGuide(guide) && !guide.config.frequency.ignoreThrottling;\n}\n\n/**\n * Pure throttling check. `launches` = ISO times of this visitor's earlier automatic launches of\n * counted guides (any order). Disabled or missing settings never throttle.\n */\nexport function isThrottleEligible(settings: GuideThrottlingSettings | null | undefined, launches: readonly string[], now: number = Date.now()): boolean {\n if (!settings || !settings.enabled) return true;\n const times = launches.map((l) => Date.parse(l)).filter((t) => !Number.isNaN(t));\n const windowMs = Math.max(1, settings.windowHours) * HOUR;\n if (times.filter((t) => now - t < windowMs).length >= Math.max(1, settings.maxGuides)) return false;\n if (settings.minGapMinutes > 0 && times.some((t) => now - t < settings.minGapMinutes * MINUTE)) return false;\n return true;\n}\n\n/** Launch times worth keeping: those still inside the window or the minimum gap (at most 100). */\nexport function pruneLaunches(launches: readonly string[], settings: GuideThrottlingSettings | null | undefined, now: number = Date.now()): string[] {\n const keepMs = Math.max(settings?.windowHours ?? 24, 1) * HOUR + (settings?.minGapMinutes ?? 0) * MINUTE;\n return launches.filter((l) => { const t = Date.parse(l); return !Number.isNaN(t) && now - t < keepMs; }).slice(-100);\n}\n\n/**\n * A checklist's dismissal after merging server state. A local dismissal normally wins (it may not have\n * synced yet), but when the server reports a reset this device hasn't applied, the server's value wins:\n * null, or a dismissal made on another device after the reset. Compared as tokens, not times, so a\n * skewed device clock can't keep a reset dismissal.\n */\nexport function dismissedAfterMerge(local: { dismissedAt?: string | null; dismissResetAt?: string | null } | undefined, server: { dismissedAt?: string | null; dismissResetAt?: string | null }): string | null {\n if (server.dismissResetAt && server.dismissResetAt !== local?.dismissResetAt) return server.dismissedAt ?? null;\n return local?.dismissedAt ?? server.dismissedAt ?? null;\n}\n","import type {\n ConversationLookupResponse,\n FeedbackUpdatesResponse,\n FileComplaintResponse,\n PublicFeedbackList,\n PublicFeedbackRequest,\n PublicFeedbackRequestDetail,\n ConversationMessagesResponse,\n MessengerConversation,\n MessengerPageContent,\n MessengerMessage,\n ResourceCenterArticle,\n SdkArticlesResponse,\n SdkHowTo,\n SdkHowTosResponse,\n StartConversationResponse,\n} from \"@guidelytech/shared\";\nimport type { MessengerApi, MessengerStreamHandlers } from \"@guidelytech/guide-runtime/messenger\";\nimport type { Api } from \"./http\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\ninterface StoredConversation {\n id: string;\n token: string;\n}\n\nconst MAX_STORED = 50;\nconst TOKEN_HEADER = \"X-Guidely-Conversation\";\n\nexport interface MessengerTransportOptions {\n api: Api;\n store: KeyValueStore;\n projectId: string;\n anonymousId: () => string;\n userId: () => string | null;\n /** Page URL to attach to messages (omitted when URL collection is off). */\n pageUrl: () => string | undefined;\n /** The visitor's resource-center language when it isn't the default (articles are fetched in it). */\n locale?: () => string | null;\n}\n\n/** The path of a page URL (plus a `#/` route), without origin or query: all how-to matching needs. */\nexport function pagePath(url: string | undefined): string | undefined {\n if (!url) return undefined;\n try {\n const u = new URL(url);\n return (u.pathname + (/^#!?\\//.test(u.hash) ? u.hash.split(\"?\")[0] : \"\")).slice(0, 2000);\n } catch {\n return undefined;\n }\n}\n\n/** Conversation tokens this browser holds (the only way to read a conversation). */\nexport function storedConversations(store: KeyValueStore, projectId: string): StoredConversation[] {\n const list = readJson<StoredConversation[]>(store, KEYS.conversations(projectId), []);\n return Array.isArray(list) ? list.filter((c) => c && typeof c.id === \"string\" && typeof c.token === \"string\") : [];\n}\n\nexport function forgetConversations(store: KeyValueStore, projectId: string) {\n store.remove(KEYS.conversations(projectId));\n}\n\nclass HttpError extends Error {\n constructor(\n readonly status: number,\n message?: string,\n ) {\n super(message || `Request failed (${status})`);\n }\n}\n\n/** The server's message for a failed request (`{ error: { message } }`), when it sent one. */\nfunction serverMessage(data: unknown): string | undefined {\n const m = (data as { error?: { message?: unknown } } | null)?.error?.message;\n return typeof m === \"string\" && m !== \"Request validation failed\" ? m : undefined;\n}\n\n/** The messenger's server access over the public SDK API. */\nexport function createMessengerTransport(opts: MessengerTransportOptions): MessengerApi {\n const { api, store, projectId } = opts;\n const tokenFor = (id: string) => storedConversations(store, projectId).find((c) => c.id === id)?.token ?? \"\";\n const remember = (id: string, token: string) => {\n const rest = storedConversations(store, projectId).filter((c) => c.id !== id);\n writeJson(store, KEYS.conversations(projectId), [{ id, token }, ...rest].slice(0, MAX_STORED));\n };\n const forget = (id: string) => writeJson(store, KEYS.conversations(projectId), storedConversations(store, projectId).filter((c) => c.id !== id));\n\n /** Dispatches either SSE events or a JSON answer to the stream handlers. */\n async function exchange(path: string, body: unknown, headers: Record<string, string>, h: MessengerStreamHandlers, onStarted?: (r: StartConversationResponse) => void) {\n let finished = false;\n const res = await api.stream<StartConversationResponse | ConversationMessagesResponse>(\n path,\n body,\n (event, data) => {\n if (event === \"conversation\") {\n const d = data as StartConversationResponse;\n onStarted?.(d);\n h.onConversation?.(d.conversation);\n d.messages.forEach((m) => h.onMessage(m));\n } else if (event === \"message\") h.onMessage(data as MessengerMessage);\n else if (event === \"delta\") {\n const d = data as { messageId: string; text: string };\n h.onDelta(d.messageId, d.text);\n } else if (event === \"done\") {\n const d = data as { message: MessengerMessage | null; conversation: MessengerConversation };\n finished = true;\n h.onDone(d.message, d.conversation);\n } else if (event === \"error\") h.onError((data as { message?: string })?.message ?? \"Something went wrong\");\n },\n headers,\n );\n if (!res.ok) throw new HttpError(res.status);\n if (res.data) {\n // JSON answer (no Scout reply): the stored messages and the conversation.\n const d = res.data;\n if (\"token\" in d) {\n onStarted?.(d);\n h.onConversation?.(d.conversation);\n }\n d.messages.forEach((m) => h.onMessage(m));\n h.onDone(d.messages.at(-1) ?? null, d.conversation);\n } else if (!finished) h.onError(\"The reply was interrupted\");\n }\n\n /** A feedback (Ideas) call: the visitor goes in the body; failures carry the server's message. */\n async function feedback<T>(path: string, body: object, fallback: string): Promise<T> {\n const res = await api.post<T>(`/feedback${path}`, { ...body, anonymousId: opts.anonymousId(), userId: opts.userId() });\n if (!res.ok || !res.data) {\n if (res.status === 429) throw new HttpError(429, \"You're doing that a lot. Please try again in a minute.\");\n throw new HttpError(res.status, serverMessage(res.data) ?? fallback);\n }\n return res.data;\n }\n\n return {\n async listConversations() {\n const tokens = storedConversations(store, projectId).map((c) => c.token);\n if (!tokens.length) return [];\n const res = await api.post<ConversationLookupResponse>(\"/conversations/lookup\", { tokens });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n // Drop tokens the server no longer knows (deleted by retention).\n const known = new Set(res.data.conversations.map((c) => c.id));\n for (const c of storedConversations(store, projectId)) if (!known.has(c.id)) forget(c.id);\n return res.data.conversations.map(({ token: _token, ...c }) => c);\n },\n async loadMessages(id, since) {\n const res = await api.get<ConversationMessagesResponse>(`/conversations/${encodeURIComponent(id)}/messages`, { params: { since: since ?? undefined }, headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n start(text, h) {\n return exchange(\"/conversations\", { anonymousId: opts.anonymousId(), userId: opts.userId(), message: text, pageUrl: opts.pageUrl() }, {}, h, (r) => remember(r.conversation.id, r.token));\n },\n send(id, text, h) {\n return exchange(`/conversations/${encodeURIComponent(id)}/messages`, { message: text, pageUrl: opts.pageUrl() }, { [TOKEN_HEADER]: tokenFor(id) }, h);\n },\n async handoff(id) {\n const res = await api.post<ConversationMessagesResponse>(`/conversations/${encodeURIComponent(id)}/handoff`, {}, { headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async rate(id, rating) {\n const res = await api.post(`/conversations/${encodeURIComponent(id)}/rating`, { rating }, { headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok) throw new HttpError(res.status);\n },\n async listArticles() {\n const res = await api.get<SdkArticlesResponse>(\"/articles\");\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async getArticle(id) {\n const locale = opts.locale?.();\n const res = await api.get<{ article: ResourceCenterArticle }>(`/articles/${encodeURIComponent(id)}`, locale ? { params: { locale } } : undefined);\n return res.ok && res.data ? res.data.article : null;\n },\n async fileComplaint(input) {\n const headers: Record<string, string> = input.conversationId ? { [TOKEN_HEADER]: tokenFor(input.conversationId) } : {};\n const res = await api.post<FileComplaintResponse>(\"/complaints\", { ...input, anonymousId: opts.anonymousId(), userId: opts.userId(), pageUrl: opts.pageUrl() }, { headers });\n if (!res.ok || !res.data || !(\"complaint\" in res.data)) {\n if (res.status === 429) throw new HttpError(429, \"You've filed several complaints just now. Please try again later.\");\n throw new HttpError(res.status, serverMessage(res.data) ?? \"Your complaint couldn't be sent. Please try again.\");\n }\n // A conversation started for the complaint: keep its token so the person can read the replies.\n if (res.data.token) remember(res.data.conversation.id, res.data.token);\n return res.data;\n },\n async pageContent(path) {\n // Only the path is sent (never the query or fragment) and nothing is stored: it picks what to suggest.\n const res = await api.post<MessengerPageContent>(\"/messenger/page\", { anonymousId: opts.anonymousId(), userId: opts.userId(), path: path.split(/[?#]/)[0] || \"/\" });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async searchArticles(q) {\n const res = await api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n },\n async listHowTos() {\n const res = await api.get<SdkHowTosResponse>(\"/how-tos\", { params: { url: pagePath(opts.pageUrl()) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async getHowTo(id) {\n const res = await api.get<{ howTo: SdkHowTo }>(`/how-tos/${encodeURIComponent(id)}`);\n return res.ok && res.data ? res.data.howTo : null;\n },\n\n // Ideas (feature requests). The visitor's ids go in every body; the server decides what they may do.\n listIdeas: (query) => feedback<PublicFeedbackList>(\"/requests/query\", query, \"Ideas couldn't be loaded.\"),\n getIdea: (id) => feedback<PublicFeedbackRequestDetail>(`/requests/${encodeURIComponent(id)}/view`, {}, \"This idea couldn't be loaded.\"),\n submitIdea: (input) => feedback<PublicFeedbackRequestDetail>(\"/requests\", { ...input, pageUrl: opts.pageUrl() }, \"Your idea couldn't be sent. Please try again.\"),\n voteIdea: (id, vote) => feedback<PublicFeedbackRequest>(`/requests/${encodeURIComponent(id)}/vote`, vote, \"Your vote couldn't be saved.\"),\n unvoteIdea: (id) => feedback<PublicFeedbackRequest>(`/requests/${encodeURIComponent(id)}/unvote`, {}, \"Your vote couldn't be removed.\"),\n followIdea: (id, follow) => feedback<PublicFeedbackRequest>(`/requests/${encodeURIComponent(id)}/follow`, { follow }, \"That didn't work. Please try again.\"),\n commentIdea: (id, body) => feedback<PublicFeedbackRequestDetail>(`/requests/${encodeURIComponent(id)}/comments`, { body }, \"Your comment couldn't be posted.\"),\n similarIdeas: async (title) => (await feedback<{ requests: PublicFeedbackRequest[] }>(\"/similar\", { title }, \"Similar ideas couldn't be loaded.\")).requests ?? [],\n ideaUpdates: () => feedback<FeedbackUpdatesResponse>(\"/updates\", {}, \"Updates couldn't be loaded.\"),\n markIdeaUpdatesRead: (ids) => feedback<FeedbackUpdatesResponse>(\"/updates/read\", ids ? { ids } : {}, \"Updates couldn't be marked read.\"),\n ideaPortalLink: async () => (await feedback<{ url: string }>(\"/portal-link\", {}, \"The feedback portal couldn't be opened.\")).url,\n };\n}\n","import type { PublishedGuide } from \"@guidelytech/shared\";\nimport { firstNameFromTraits } from \"@guidelytech/shared/runtime\";\nimport { urlMatches } from \"@guidelytech/guide-runtime\";\nimport type { MessengerChecklistProgress, MessengerNewsItem, MessengerResumeGuide, MessengerVisitor } from \"@guidelytech/guide-runtime/messenger\";\nimport { isWithinSchedule } from \"./frequency\";\nimport type { PersistedState } from \"./types\";\n\n/** Guide kinds the messenger offers to start for a page (announcements go to News instead). */\nconst PAGE_GUIDE_KINDS = new Set([\"flow\", \"tooltip\", \"modal\"]);\n/** URL patterns that match every page say nothing about a page. */\nconst CATCH_ALL = new Set([\"\", \"*\", \"**\", \"/*\", \"/**\", \"/\"]);\nconst RESUME_WITHIN_MS = 14 * 86_400_000;\nconst NEWS_WITHIN_MS = 90 * 86_400_000;\nconst MAX_NEWS = 10;\n\nexport interface VisitorInput {\n guides: PublishedGuide[];\n state: PersistedState;\n traits: Record<string, unknown> | undefined;\n /** `location.href`. */\n url: string;\n /** Full targeting for the current page (URL patterns, schedule, rules). */\n isTargeted: (guide: PublishedGuide) => boolean;\n /** Schedule and rules only: for content that isn't tied to the current page (news, progress). */\n isAudienceTargeted: (guide: PublishedGuide) => boolean;\n /** Announcement ids already seen in the News tab. */\n newsSeen: readonly string[];\n now?: number;\n}\n\nfunction pathOf(url: string): string | null {\n try {\n return new URL(url, \"http://x.invalid\").pathname || \"/\";\n } catch {\n return null;\n }\n}\n\n/** True when the guide names this page explicitly (URL patterns, a URL trigger, or its first step's page). */\nexport function targetsPage(guide: PublishedGuide, url: string): boolean {\n const c = guide.config;\n const checks: string[] = [...c.urlPatterns, ...(c.trigger.urlPattern ? [c.trigger.urlPattern] : []), ...(c.trigger.type === \"url_match\" && c.trigger.value ? [c.trigger.value] : []), ...(c.steps[0]?.url ? [c.steps[0].url] : [])];\n const specific = checks.filter((p) => !CATCH_ALL.has(p.trim()));\n // Every page reference must match (they are all requirements), and at least one must be specific.\n return specific.length > 0 && checks.every((p) => urlMatches(p, url));\n}\n\n/** Rich text from a guide step as plain text for a news card. */\nexport function plainText(html: string, max = 280): string {\n const text = html\n .replace(/<(br|\\/p|\\/div|\\/li|\\/h[1-6])\\s*\\/?>/gi, \" \")\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\")\n .replace(/\\s+/g, \" \")\n .trim();\n return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;\n}\n\n/** Everything the messenger personalises from: name, page guides, progress and announcements. */\nexport function buildMessengerVisitor(input: VisitorInput): MessengerVisitor {\n const now = input.now ?? Date.now();\n const { guides, state } = input;\n const done = (g: PublishedGuide) => !!state.guides[g.id]?.completedAt;\n\n const pageGuides = guides\n .filter((g) => PAGE_GUIDE_KINDS.has(g.kind) && g.config.steps.length > 0 && !done(g) && targetsPage(g, input.url) && input.isTargeted(g))\n .slice(0, 3)\n .map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind }));\n\n let resumeGuide: MessengerResumeGuide | null = null;\n let resumeAt = 0;\n for (const g of guides) {\n const s = state.guides[g.id];\n if (g.kind !== \"flow\" || !s?.lastStepId || s.completedAt || g.config.steps.length < 2) continue;\n const at = Date.parse(s.lastShownAt ?? \"\");\n if (!Number.isFinite(at) || now - at > RESUME_WITHIN_MS || at <= resumeAt) continue;\n const stepIndex = g.config.steps.findIndex((st) => st.id === s.lastStepId);\n // Only once they got past the first step; the step must still exist in the live version. Auto-show\n // targeting (\"first visit\") doesn't apply: they already started it, and resuming starts it by hand.\n if (stepIndex < 1 || !isWithinSchedule(g)) continue;\n resumeGuide = { id: g.id, name: g.name, stepId: s.lastStepId, stepIndex, stepCount: g.config.steps.length };\n resumeAt = at;\n }\n\n let checklist: MessengerChecklistProgress | null = null;\n for (const g of guides) {\n const tasks = g.config.checklist?.tasks;\n if (g.kind !== \"checklist\" || !tasks?.length) continue;\n const p = state.checklists[g.id];\n if (p?.completedAt || p?.dismissedAt || !input.isAudienceTargeted(g)) continue;\n const completed = new Set(p?.completedTaskIds ?? []);\n const doneCount = tasks.filter((t) => completed.has(t.id)).length;\n if (doneCount >= tasks.length) continue;\n checklist = { id: g.id, name: g.name, done: doneCount, total: tasks.length, nextTask: tasks.find((t) => !completed.has(t.id))?.title ?? null };\n break;\n }\n\n const seen = new Set(input.newsSeen);\n const news: MessengerNewsItem[] = guides\n .filter((g) => g.kind === \"announcement\" && g.config.steps.length > 0 && now - Date.parse(g.publishedAt) <= NEWS_WITHIN_MS && input.isAudienceTargeted(g))\n .sort((a, b) => b.publishedAt.localeCompare(a.publishedAt))\n .slice(0, MAX_NEWS)\n .map((g) => {\n const step = g.config.steps[0]!;\n return {\n id: g.id,\n key: g.key,\n title: step.title || g.name,\n body: plainText(step.body ?? \"\"),\n imageUrl: step.imageUrl || null,\n publishedAt: g.publishedAt,\n // Read once opened in the News tab, or once the announcement itself was shown.\n unread: !seen.has(g.id) && !(state.guides[g.id]?.impressions ?? 0),\n };\n });\n\n return { firstName: firstNameFromTraits(input.traits), path: pathOf(input.url), pageGuides, resumeGuide, checklist, news };\n}\n","type Listener = (url: string) => void;\n\ninterface PatchedHistory extends History {\n __guidelyPatched?: { count: number; pushState: History[\"pushState\"]; replaceState: History[\"replaceState\"] };\n}\n\n/**\n * Detects SPA navigation: patches `history.pushState`/`replaceState` (reference counted, restored\n * on the last unwatch), listens to `popstate` and `hashchange`, and debounces into one callback.\n */\nexport function watchNavigation(listener: Listener, debounceMs = 50): () => void {\n if (typeof window === \"undefined\") return () => {};\n const win = window;\n const hist = win.history as PatchedHistory;\n let last = win.location.href;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const check = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const href = win.location.href;\n if (href !== last) {\n last = href;\n listener(href);\n }\n }, debounceMs);\n };\n if (!hist.__guidelyPatched) {\n const pushState = hist.pushState;\n const replaceState = hist.replaceState;\n hist.__guidelyPatched = { count: 0, pushState, replaceState };\n hist.pushState = function (this: History, ...args: Parameters<History[\"pushState\"]>) {\n const r = pushState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n hist.replaceState = function (this: History, ...args: Parameters<History[\"replaceState\"]>) {\n const r = replaceState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n }\n hist.__guidelyPatched.count += 1;\n win.addEventListener(\"guidely:navigate\", check);\n win.addEventListener(\"popstate\", check);\n win.addEventListener(\"hashchange\", check);\n return () => {\n if (timer) clearTimeout(timer);\n win.removeEventListener(\"guidely:navigate\", check);\n win.removeEventListener(\"popstate\", check);\n win.removeEventListener(\"hashchange\", check);\n const p = hist.__guidelyPatched;\n if (p) {\n p.count -= 1;\n if (p.count <= 0) {\n hist.pushState = p.pushState;\n hist.replaceState = p.replaceState;\n delete hist.__guidelyPatched;\n }\n }\n };\n}\n","/**\n * Page URLs for apps that are not served over http(s): Electron and other desktop shells load\n * `file:///…/index.html#/settings` or a custom protocol such as `app://bundle/index.html`. Raw, those\n * URLs make useless page paths (`/Users/ada/Applications/Acme.app/Contents/Resources/app.asar/index.html`)\n * that differ per machine, so guide URL patterns and page analytics could never match them.\n *\n * `normalizeAppUrl` maps them to stable app-relative URLs: `<scheme>://<host or \"app\"><route>` where the\n * route is the hash route when the app uses hash routing (`#/settings` → `/settings`), otherwise the\n * page file relative to the app (`index.html` → `/`, `settings.html` → `/settings`, a custom\n * protocol's own path otherwise). Query strings are kept. http(s) and unparseable URLs are unchanged.\n *\n * file:///C:/Acme/resources/app.asar/dist/index.html#/deals/42?tab=notes → file://app/deals/42?tab=notes\n * file:///Users/ada/Acme.app/Contents/Resources/app/settings.html → file://app/settings\n * app://bundle/index.html#!/inbox → app://bundle/inbox\n * app://bundle/deals/42 → app://bundle/deals/42\n */\nconst WEB_SCHEMES = new Set([\"http\", \"https\", \"about\", \"data\", \"blob\", \"javascript\"]);\n\nfunction appScheme(href: string): { u: URL; scheme: string } | null {\n let u: URL;\n try {\n u = new URL(href);\n } catch {\n return null;\n }\n const scheme = u.protocol.replace(/:$/, \"\").toLowerCase();\n return WEB_SCHEMES.has(scheme) ? null : { u, scheme };\n}\n\nexport function normalizeAppUrl(href: string): string {\n const app = appScheme(href);\n if (!app) return href;\n const { u, scheme } = app;\n const host = scheme === \"file\" ? \"app\" : u.host || \"app\";\n const hash = /^#!?(\\/.*)$/.exec(u.hash);\n if (hash) {\n // Hash routing: the route (with its own ?query) is the page.\n const route = hash[1]!;\n return `${scheme}://${host}${route.startsWith(\"/\") ? route : `/${route}`}`;\n }\n let path = safeDecode(u.pathname);\n if (scheme === \"file\" || /\\.html?$/i.test(path)) {\n // A page file: its name without the extension, `index` being the root.\n const file = path.split(\"/\").filter(Boolean).pop() ?? \"\";\n const name = file.replace(/\\.html?$/i, \"\");\n path = !name || name.toLowerCase() === \"index\" ? \"/\" : `/${name}`;\n }\n if (!path.startsWith(\"/\")) path = `/${path}`;\n return `${scheme}://${host}${path}${u.search}`;\n}\n\nfunction safeDecode(s: string): string {\n try {\n return decodeURI(s);\n } catch {\n return s;\n }\n}\n\n/** True for desktop-shell URLs (`file:`, custom protocols such as `app:`), which {@link normalizeAppUrl} makes app-relative. */\nexport function isAppUrl(href: string): boolean {\n return appScheme(href) !== null;\n}\n","/** What `page_leave` reports for the page being left. */\nexport interface PageLeaveInfo {\n url: string;\n /** Time the page was visible (pauses while `document.hidden`). */\n durationMs: number;\n /** Furthest point scrolled to, as a percentage (0–100) of the page height. */\n scrollDepth: number;\n}\n\n/** Current scroll depth (0–100): the bottom of the viewport relative to the page height. */\nexport function scrollDepth(): number {\n const de = document.documentElement;\n const height = Math.max(de?.scrollHeight || 0, document.body?.scrollHeight || 0);\n const view = window.innerHeight || de?.clientHeight || 0;\n if (height <= 0 || height <= view) return 100;\n const y = window.scrollY || de?.scrollTop || 0;\n return Math.max(0, Math.min(100, Math.round(((y + view) / height) * 100)));\n}\n\n/** Tracks visible time and maximum scroll depth of the current page (for `page_leave`). */\nexport class PageTracker {\n url = \"\";\n private visibleMs = 0;\n private visibleSince: number | null = null;\n private maxScroll = 0;\n\n /** Starts measuring a new page. */\n start(url: string, now = Date.now()): void {\n this.url = url;\n this.visibleMs = 0;\n this.visibleSince = typeof document !== \"undefined\" && document.visibilityState === \"hidden\" ? null : now;\n this.maxScroll = 0;\n this.measureScroll();\n }\n\n /** Pauses / resumes the visible-time clock. */\n setHidden(hidden: boolean, now = Date.now()): void {\n if (hidden && this.visibleSince !== null) {\n this.visibleMs += Math.max(0, now - this.visibleSince);\n this.visibleSince = null;\n } else if (!hidden && this.visibleSince === null) this.visibleSince = now;\n }\n\n measureScroll(): void {\n try {\n this.maxScroll = Math.max(this.maxScroll, scrollDepth());\n } catch {\n /* no layout */\n }\n }\n\n /** Final numbers for the current page. */\n leave(now = Date.now()): PageLeaveInfo {\n this.measureScroll();\n const running = this.visibleSince !== null ? Math.max(0, now - this.visibleSince) : 0;\n return { url: this.url, durationMs: Math.round(this.visibleMs + running), scrollDepth: this.maxScroll };\n }\n}\n","/**\n * In-app recruitment for Guidely prototype tests (Validate). A guide button that opens a Guidely test URL\n * (`<apiOrigin>/validate/<token>`, same origin as the SDK's API) shows the test in a full-screen overlay\n * iframe instead of navigating away. Attribution (public key, anonymous id, user id) goes in the URL\n * fragment, so it never reaches servers, proxies or logs; the test page reads and clears it.\n *\n * The overlay is a modal dialog: focus moves into it and is trapped between the close button and the\n * test frame, Escape closes it, and it closes when the test page posts `{ type: \"guidely:prototype:close\" }`.\n */\n\nexport const PROTOTYPE_CLOSE_MESSAGE = \"guidely:prototype:close\";\nconst TOKEN = /^[A-Za-z0-9_-]{16,64}$/;\nconst OVERLAY_ATTR = \"data-guidely-prototype-overlay\";\n\n/**\n * The test URL for a full test URL or a bare token, when it points at this Guidely deployment's\n * `/validate/<token>` page; null for anything else (other origins and paths keep their normal behaviour).\n */\nexport function matchPrototypeTestUrl(urlOrToken: string, apiUrl: string): URL | null {\n const value = (urlOrToken || \"\").trim();\n let api: URL;\n try {\n api = new URL(apiUrl);\n } catch {\n return null;\n }\n if (TOKEN.test(value)) return new URL(`/validate/${value}`, api.origin);\n let url: URL;\n try {\n url = new URL(value, typeof location !== \"undefined\" ? location.href : api.origin);\n } catch {\n return null;\n }\n if (url.origin !== api.origin) return null;\n const m = /^\\/validate\\/([^/]+)\\/?$/.exec(url.pathname);\n if (!m || !TOKEN.test(m[1]!)) return null;\n return new URL(`/validate/${m[1]}`, api.origin);\n}\n\nexport interface PrototypeOverlayOptions {\n /** Environment public key, so the test can attribute the session to the end user. */\n key: string;\n anonymousId?: string | null;\n userId?: string | null;\n zIndex?: number;\n onClose?: () => void;\n}\n\nexport interface PrototypeOverlay {\n element: HTMLElement;\n close: () => void;\n}\n\nlet current: PrototypeOverlay | null = null;\n\n/** Opens the test in a full-screen overlay (replacing one already open). */\nexport function openPrototypeOverlay(testUrl: URL, opts: PrototypeOverlayOptions): PrototypeOverlay {\n current?.close();\n const doc = document;\n const previous = doc.activeElement as HTMLElement | null;\n const src = new URL(testUrl.href);\n const hash = new URLSearchParams();\n hash.set(\"key\", opts.key);\n if (opts.anonymousId) hash.set(\"anon\", opts.anonymousId);\n if (opts.userId) hash.set(\"uid\", opts.userId);\n src.hash = hash.toString();\n\n const root = doc.createElement(\"div\");\n root.setAttribute(OVERLAY_ATTR, \"\");\n root.setAttribute(\"role\", \"dialog\");\n root.setAttribute(\"aria-modal\", \"true\");\n root.setAttribute(\"aria-label\", \"Prototype test\");\n root.style.cssText = `position:fixed;inset:0;z-index:${opts.zIndex ?? 2147483646};background:rgba(15,23,42,.55);display:flex;align-items:stretch;justify-content:center;padding:0;margin:0;`;\n\n const frame = doc.createElement(\"iframe\");\n frame.src = src.toString();\n frame.title = \"Prototype test\";\n frame.setAttribute(\"allow\", \"fullscreen\");\n frame.setAttribute(\"referrerpolicy\", \"no-referrer\");\n frame.style.cssText = \"border:0;width:100%;height:100%;background:#fff;display:block;\";\n\n const close = doc.createElement(\"button\");\n close.type = \"button\";\n close.setAttribute(\"aria-label\", \"Close prototype test\");\n close.textContent = \"×\";\n close.style.cssText =\n \"position:absolute;top:10px;right:10px;width:36px;height:36px;border-radius:999px;border:0;background:rgba(15,23,42,.75);color:#fff;font:600 22px/36px system-ui,sans-serif;text-align:center;cursor:pointer;padding:0;z-index:1;\";\n\n root.append(frame, close);\n const overflow = doc.documentElement.style.overflow;\n doc.documentElement.style.overflow = \"hidden\";\n\n let closed = false;\n const shut = () => {\n if (closed) return;\n closed = true;\n window.removeEventListener(\"message\", onMessage);\n doc.removeEventListener(\"keydown\", onKey, true);\n doc.removeEventListener(\"focusin\", onFocus, true);\n root.remove();\n doc.documentElement.style.overflow = overflow;\n if (current === overlay) current = null;\n try {\n previous?.focus?.();\n } catch {\n /* the element may be gone */\n }\n opts.onClose?.();\n };\n const onMessage = (e: MessageEvent) => {\n if (e.origin !== testUrl.origin || e.source !== frame.contentWindow) return;\n const data = e.data as { type?: unknown } | null;\n if (data && typeof data === \"object\" && data.type === PROTOTYPE_CLOSE_MESSAGE) shut();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n shut();\n } else if (e.key === \"Tab\") {\n // Two stops: the test frame and the close button.\n e.preventDefault();\n (doc.activeElement === close ? frame : close).focus();\n }\n };\n // Focus leaving the frame for the page behind (Tab out of the iframe) comes back to the dialog.\n const onFocus = (e: FocusEvent) => {\n if (!root.contains(e.target as Node)) close.focus();\n };\n close.addEventListener(\"click\", shut);\n window.addEventListener(\"message\", onMessage);\n doc.addEventListener(\"keydown\", onKey, true);\n doc.addEventListener(\"focusin\", onFocus, true);\n doc.body.appendChild(root);\n frame.focus();\n\n const overlay: PrototypeOverlay = { element: root, close: shut };\n current = overlay;\n return overlay;\n}\n","import type { SdkEvent } from \"@guidelytech/shared\";\nimport type { ServerHealth } from \"./health\";\nimport { backoffMs } from \"./http\";\nimport { readJson, writeJson, type KeyValueStore } from \"./storage\";\n\nexport interface EventQueueOptions {\n store: KeyValueStore;\n storageKey: string;\n /** Sends one batch. Resolve `{ ok: true }` on success, `{ ok: false, retry }` otherwise. */\n send: (events: SdkEvent[]) => Promise<{ ok: boolean; retry?: boolean }>;\n /** Synchronous best-effort send used on page hide. */\n beacon?: (events: SdkEvent[]) => boolean;\n /** Should events be flushed right now? (analytics enabled + consent granted). */\n enabled: () => boolean;\n /** API reachability: sends wait while its circuit is open, and beaconed events are only forgotten while it is reachable. */\n health?: ServerHealth;\n flushIntervalMs?: number;\n maxQueue?: number;\n batchSize?: number;\n maxAttempts?: number;\n onError?: (err: unknown) => void;\n}\n\n/**\n * Bounded, persisted event queue. Batches ≤50 events every 2s (or on demand), dedupes by\n * `eventId`, and keeps failed events (also across page loads) until the server takes them:\n * retries back off 1s→60s, wait while the API's circuit is open, and start again as soon as it\n * recovers. Drops the oldest events once the queue exceeds 500.\n */\nexport class EventQueue {\n private events: SdkEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private inflight = false;\n private inflightIds = new Set<string>();\n private attempt = 0;\n private destroyed = false;\n private offRecover: (() => void) | null = null;\n private readonly flushIntervalMs: number;\n private readonly maxQueue: number;\n private readonly batchSize: number;\n private readonly maxAttempts: number;\n\n constructor(private readonly opts: EventQueueOptions) {\n this.flushIntervalMs = opts.flushIntervalMs ?? 2000;\n this.maxQueue = opts.maxQueue ?? 500;\n this.batchSize = opts.batchSize ?? 50;\n this.maxAttempts = opts.maxAttempts ?? 5;\n const persisted = readJson<SdkEvent[]>(opts.store, opts.storageKey, []);\n if (Array.isArray(persisted)) this.events = persisted.filter((e) => e && typeof e.eventId === \"string\").slice(-this.maxQueue);\n // Events left over from a previous page load are flushed on the next tick.\n if (this.events.length) this.schedule();\n this.offRecover = opts.health?.onRecover(() => this.retryNow()) ?? null;\n }\n\n /** The API is back: drop any pending backoff and send what is queued. */\n private retryNow(): void {\n if (this.destroyed) return;\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.retryTimer = null;\n this.attempt = 0;\n void this.flush();\n }\n\n private retryIn(ms: number): void {\n if (this.retryTimer || this.destroyed) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n void this.flush();\n }, ms);\n }\n\n get size(): number {\n return this.events.length;\n }\n\n /** Pending events (read-only copy, for debugging). */\n peek(): SdkEvent[] {\n return this.events.slice();\n }\n\n enqueue(event: SdkEvent): void {\n if (this.destroyed) return;\n if (this.events.some((e) => e.eventId === event.eventId)) return;\n this.events.push(event);\n if (this.events.length > this.maxQueue) this.events.splice(0, this.events.length - this.maxQueue);\n this.persist();\n this.schedule();\n }\n\n private persist(): void {\n writeJson(this.opts.store, this.opts.storageKey, this.events);\n }\n\n private schedule(): void {\n if (this.timer || this.retryTimer || this.destroyed) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.flushIntervalMs);\n }\n\n /** Sends queued events now (one batch at a time). Safe to call at any time. */\n async flush(): Promise<void> {\n if (this.destroyed || this.inflight || !this.events.length || !this.opts.enabled()) return;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n const wait = this.opts.health?.waitMs() ?? 0;\n if (wait > 0) return this.retryIn(wait);\n this.inflight = true;\n const batch = this.events.slice(0, this.batchSize);\n this.inflightIds = new Set(batch.map((e) => e.eventId));\n let ok = false;\n let retry = true;\n try {\n const res = await this.opts.send(batch);\n ok = res.ok;\n retry = res.retry ?? !res.ok;\n } catch (err) {\n this.opts.onError?.(err);\n }\n this.inflight = false;\n this.inflightIds.clear();\n if (this.destroyed) return;\n if (ok || !retry) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n this.attempt = 0;\n this.persist();\n if (this.events.length) this.schedule();\n return;\n }\n // Fast retries first, then about once a minute until the server takes the events (or the\n // API's circuit says to wait longer); a recovery or the next page load sends them sooner.\n this.attempt = Math.min(this.attempt + 1, this.maxAttempts);\n const delay = this.attempt >= this.maxAttempts ? 60_000 : backoffMs(this.attempt - 1);\n this.retryIn(Math.max(delay, this.opts.health?.waitMs() ?? 0));\n }\n\n /** Best-effort synchronous flush on unload using `sendBeacon`. */\n flushSync(): void {\n if (this.destroyed || !this.opts.enabled() || !this.opts.beacon) return;\n // Events already in flight (fetch with keepalive) survive unload; only beacon the rest to avoid duplicate batches.\n const batch = this.events.filter((e) => !this.inflightIds.has(e.eventId)).slice(0, this.batchSize);\n if (!batch.length) return;\n // A beacon that was queued may still never arrive (the server is down), and nothing reports\n // back. Only forget its events while the API is answering; otherwise they stay persisted and the\n // next page load sends them again (the server drops events it already has, by eventId).\n if (this.opts.beacon(batch) && (this.opts.health?.reachable ?? true)) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n }\n this.persist();\n }\n\n clear(): void {\n this.events = [];\n this.persist();\n }\n\n destroy(): void {\n this.destroyed = true;\n this.offRecover?.();\n if (this.timer) clearTimeout(this.timer);\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.timer = null;\n this.retryTimer = null;\n this.persist();\n }\n}\n","import type { RecorderApi } from \"./recorder-types\";\n\n/**\n * Loads the session-replay chunk on demand. The import is rewritten per build: `./recorder.js`\n * (npm; consumers' bundlers code-split it) or, in the script-tag build, a loader that injects\n * `guidely-recorder.js` and resolves `window.__guidelyRecorder` (`recorder` is a thenable there).\n */\nexport const loadRecorder = async (): Promise<RecorderApi> => (await import(\"./recorder\")).recorder;\n"],"mappings":"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","names":["import_runtime","import_guide_runtime","import_runtime","import_guide_runtime","attr","import_runtime","import_guide_runtime","attr","matches","import_runtime","import_runtime","import_runtime","import_guide_runtime","current","pathOf"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/agent-turns.ts","../src/health.ts","../src/http.ts","../src/storage.ts","../src/outbox.ts","../src/authoring.ts","../src/snapshot.ts","../src/tagging.ts","../src/autocapture.ts","../src/capture-token.ts","../src/load-capture.ts","../src/context.ts","../src/heatmap.ts","../src/errors.ts","../src/emitter.ts","../src/frequency.ts","../src/messenger-api.ts","../src/messenger-visitor.ts","../src/navigation.ts","../src/page-url.ts","../src/page-tracking.ts","../src/prototype-overlay.ts","../src/queue.ts","../src/load-recorder.ts"],"sourcesContent":["/**\n * @guidelytech/sdk-core — framework-independent Guidely browser SDK.\n *\n * SSR-safe to import: nothing touches `window` at module scope. Create a client in the browser\n * with {@link createGuidely} (or `Guidely.init` for script-tag installs).\n */\nimport { GuidelyClient, createGuidely, SDK_VERSION } from \"./client\";\n\nexport { GuidelyClient, createGuidely, SDK_NAME, SDK_VERSION, DEFAULT_API_URL } from \"./client\";\nexport type { GuidelyOptions, GuidelyEvents, GuidelyEventName, GuidelyUser, GuidelyAccount, GuidelyEnvironment, ConsentState, ChecklistProgressState, PersistedState, SessionState, GuideStepInfo } from \"./types\";\nexport { isFrequencyEligible, isExclusiveGuide, areMutuallyExclusive, isWithinSchedule, countsTowardThrottle, isThrottleEligible, pruneLaunches } from \"./frequency\";\nexport type { GuideLocalState } from \"./frequency\";\nexport { detectDevice, buildContext } from \"./context\";\nexport type { DeviceInfo, ContextInput } from \"./context\";\nexport { EventQueue } from \"./queue\";\nexport type { EventQueueOptions } from \"./queue\";\nexport { watchNavigation } from \"./navigation\";\nexport { normalizeAppUrl, isAppUrl } from \"./page-url\";\nexport { createStorage, KEYS } from \"./storage\";\nexport type { KeyValueStore, StorageKind } from \"./storage\";\nexport { AUTHORING_PARAM, HEARTBEAT_MS } from \"./authoring\";\nexport { captureSnapshot } from \"./snapshot\";\nexport type { AuthoringIncomingMessage, AuthoringOutgoingMessage } from \"./authoring\";\nexport { CAPTURE_PARAM } from \"./capture-token\";\nexport type { CaptureMarker } from \"./capture-token\";\nexport type { CaptureOutgoingMessage } from \"./capture\";\nexport type { AppSnapshot, PublishedGuide, SdkConfigResponse, SdkEvent, TargetingContext, GuideConfig, GuideStep, AutocaptureSettings, ExceptionProperties, StackFrame } from \"@guidelytech/shared\";\nexport type { ClickProperties } from \"./autocapture\";\nexport type { FlagsClient, FlagsClientOptions, FlagDetails, FlagsBootstrap, FlagsPayload, EvaluationResult, Attributes, JsonValue } from \"@guidelytech/flags\";\nexport type { PageLeaveInfo } from \"./page-tracking\";\nexport type { AgentTurnRedactor } from \"./agent-turns\";\nexport type { AgentTurnInput, AgentToolCallInput, AgentOutcome, AgentTurnRole, AgentEventsResponse } from \"@guidelytech/shared\";\nexport { matchPrototypeTestUrl, PROTOTYPE_CLOSE_MESSAGE } from \"./prototype-overlay\";\n\n/** Global-style API used by the script-tag embed: `Guidely.init(options)` / `Guidely.get()`. */\nexport const Guidely = {\n init: (options: Parameters<typeof GuidelyClient.init>[0]) => GuidelyClient.init(options),\n get: () => GuidelyClient.get(),\n createGuidely,\n version: SDK_VERSION,\n};\n\nexport default Guidely;\n","import { evaluateRules, localizeGuide, localizeResourceCenter, normalizeLocale, randomId, rolloutBucket, sanitizeProperties, supportsPlatform, visibleAnnouncements, visitorLocales, type ExceptionProperties } from \"@guidelytech/shared/runtime\";\nimport {\n type AutocaptureSettings,\n type ChecklistTask,\n type EventName,\n type IdentifyRequest,\n type IdentifyResponse,\n type PublishedGuide,\n type ResourceCenterArticle,\n type SdkConfigResponse,\n type SdkEvent,\n type TargetingContext,\n} from \"@guidelytech/shared\";\nimport {\n closestComposed,\n composedTarget,\n destroyHost,\n isChecklistComplete,\n renderChecklist,\n renderResourceCenter,\n renderSurvey,\n runGuide,\n urlMatches,\n waitForTarget,\n type ChecklistWidget,\n type GuideController,\n type ResourceCenterWidget,\n type SurveyWidget,\n} from \"@guidelytech/guide-runtime\";\nimport { createScope } from \"@guidelytech/guide-runtime\";\nimport { createFlagsClient, type Attributes, type EvaluationResult, type FlagDetails, type FlagValue, type FlagsClient, type JsonValue } from \"@guidelytech/flags\";\nimport type { MessengerTab, MessengerWidget } from \"@guidelytech/guide-runtime/messenger\";\nimport type { AgentTurnInput } from \"@guidelytech/shared/runtime\";\nimport { AgentTurns, prepareAgentTurn } from \"./agent-turns\";\nimport { AuthoringBridge } from \"./authoring\";\nimport type { CaptureBridge } from \"./capture\";\nimport { takeCaptureToken } from \"./capture-token\";\nimport { loadCapture } from \"./load-capture\";\nimport { DEFAULT_MASK_SELECTORS, describeClick, interactiveElement, isIgnoredElement, RageClickDetector, validSelectors } from \"./autocapture\";\nimport { buildContext, detectDevice } from \"./context\";\nimport { HeatmapBuffer, heatmapPoint, movementBin } from \"./heatmap\";\nimport { clickPropertyValues, elementSnapshot, featureAttributeOf, pagePropertyValues } from \"./tagging\";\nimport { errorEventToException, exceptionFromError, ExceptionThrottle, isGuidelyException, rejectionToException } from \"./errors\";\nimport { Emitter } from \"./emitter\";\nimport { areMutuallyExclusive, countsTowardThrottle, dismissedAfterMerge, isExclusiveGuide, isFrequencyEligible, isThrottleEligible, isWithinSchedule, pruneLaunches, type GuideLocalState } from \"./frequency\";\nimport { Api, postWithRetry } from \"./http\";\nimport { createMessengerTransport, forgetConversations } from \"./messenger-api\";\nimport { buildMessengerVisitor, plainText } from \"./messenger-visitor\";\nimport { watchNavigation } from \"./navigation\";\nimport { normalizeAppUrl } from \"./page-url\";\nimport { PageTracker } from \"./page-tracking\";\nimport { matchPrototypeTestUrl, openPrototypeOverlay } from \"./prototype-overlay\";\nimport { Outbox } from \"./outbox\";\nimport { EventQueue } from \"./queue\";\nimport { loadRecorder } from \"./load-recorder\";\nimport type { ReplayController, ReplayRecordingConfig } from \"./replay\";\nimport { createStorage, KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\nimport type { ChecklistProgressState, ConsentState, GuidelyAccount, GuidelyEvents, GuidelyOptions, GuidelyUser, PersistedState, SessionState } from \"./types\";\n\nexport const SDK_NAME = \"@guidelytech/sdk-core\";\nexport const SDK_VERSION = \"0.12.0\";\nexport const DEFAULT_API_URL = \"https://api.guidely.app\";\n\ntype EvalReason = \"ready\" | \"navigation\" | \"event\" | \"click\" | \"visible\" | \"identify\" | \"after_guide\" | \"timer\" | \"manual\";\ninterface EvalDetail {\n eventName?: string;\n target?: Element | null;\n guideId?: string;\n endedGuide?: PublishedGuide;\n newAudiences?: Set<string>;\n}\n\ninterface ActiveGuide {\n guide: PublishedGuide;\n controller?: GuideController;\n survey?: SurveyWidget;\n scope?: { destroy(): void };\n manual: boolean;\n startUrl: string;\n}\n\ninterface QueuedGuide {\n guide: PublishedGuide;\n url: string;\n pageScoped: boolean;\n}\n\nconst PAGE_SCOPED = new Set([\"page_load\", \"url_match\", \"element_click\", \"element_visible\", \"delay\"]);\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst MAX_SESSION_EXCEPTIONS = 100;\n/**\n * With a cached config, start from it when the server takes longer than this to answer (config or\n * identify): guides, the messenger and flags keep working through an outage, and the fresh answer\n * is applied when it arrives.\n */\nconst CACHED_START_MS = 1500;\n\n/** Resolves true when `promise` settles within `ms`, false otherwise (it keeps running either way). */\nfunction settlesWithin(promise: Promise<unknown>, ms: number): Promise<boolean> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), ms);\n const done = () => {\n clearTimeout(timer);\n resolve(true);\n };\n promise.then(done, done);\n });\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction emptyState(): PersistedState {\n return { guides: {}, checklists: {}, surveysSubmitted: [], audienceIds: [] };\n}\n\nfunction newSession(now = Date.now()): SessionState {\n return { id: `s_${randomId(16)}`, startedAt: new Date(now).toISOString(), shownGuides: [], events: [], lastActivityAt: now };\n}\n\n/**\n * Framework-independent Guidely client. Create one per page with {@link createGuidely} or\n * {@link GuidelyClient.init}; adapters (`@guidelytech/react`, `@guidelytech/svelte`) wrap it.\n */\nexport class GuidelyClient {\n readonly options: Readonly<Required<Pick<GuidelyOptions, \"projectId\" | \"environment\" | \"apiUrl\" | \"analytics\" | \"consent\" | \"storage\" | \"configRefreshMs\" | \"pollIntervalMs\" | \"debug\">>> & GuidelyOptions;\n private readonly api: Api;\n private readonly store: KeyValueStore;\n private readonly sessionStore: KeyValueStore;\n private readonly emitter: Emitter<GuidelyEvents>;\n private readonly queue: EventQueue;\n /** Survey answers and guide/checklist progress, kept until the server accepts them. */\n private readonly outbox: Outbox;\n /** Agent Analytics turns (agentConversation), in their own outbox. */\n private readonly agentTurns: AgentTurns;\n private config: SdkConfigResponse | null = null;\n private etag: string | null = null;\n private anonymousId: string;\n private user: GuidelyUser | null = null;\n private state: PersistedState;\n private session: SessionState;\n private consent: ConsentState;\n private readyPromise: Promise<void> | null = null;\n private resolveReady: (() => void) | null = null;\n private isReady = false;\n private destroyed = false;\n private active: ActiveGuide | null = null;\n private queued: QueuedGuide[] = [];\n private widgets = new Map<string, { destroy(): void; checklist?: ChecklistWidget; scope?: { destroy(): void }; controller?: GuideController; manual?: boolean }>();\n private resourceCenter: ResourceCenterWidget | null = null;\n private resourceCenterScope: { destroy(): void } | null = null;\n private messenger: MessengerWidget | null = null;\n private messengerScope: { destroy(): void } | null = null;\n private messengerLoading: Promise<MessengerWidget | null> | null = null;\n private cleanups: Array<() => void> = [];\n private timers = new Set<ReturnType<typeof setTimeout>>();\n private visibilityObservers = new Map<string, () => void>();\n private firedDelays = new Set<string>();\n private firstVisit: boolean;\n private lastUrl: string;\n private authoring: AuthoringBridge | null = null;\n private capture: CaptureBridge | null = null;\n /** A capture token was found and the (lazily loaded) capture bridge is starting. */\n private captureStarting = false;\n private lastAudiences = new Set<string>();\n /** Set once the app calls identify()/reset(); bootstrap then leaves identity alone instead of re-identifying. */\n private identitySettled = false;\n // Product analytics (autocapture, error tracking, session replay)\n /** Created once the recorder chunk has loaded (it carries the replay controller). */\n private replay: ReplayController | null = null;\n private replayLoading = false;\n private readonly pageTracker = new PageTracker();\n private readonly rage = new RageClickDetector();\n private readonly heatmap = new HeatmapBuffer();\n private readonly exceptionThrottle = new ExceptionThrottle();\n /** Exceptions seen before the config was loaded (reported once it is known whether the server accepts them). */\n private earlyExceptions: Array<[ExceptionProperties, Record<string, unknown> | undefined]> = [];\n private initialPageViewSent = false;\n private pageViewUrl: string | null = null;\n private pageLeft = false;\n /** Feature flags for this environment: `guidely.flags.isEnabled(\"new-checkout\")`. */\n readonly flags: FlagsClient;\n /** Experiments already reported this session (`experiment_viewed` is sent once per session). */\n private exposures = new Set<string>();\n /** Language set with `setLocale()`. */\n private locale: string | null = null;\n /** Language each shown guide was rendered in; added to its events as `locale`. */\n private guideLocales = new Map<string, string>();\n\n constructor(options: GuidelyOptions) {\n if (!isBrowser()) throw new Error(\"[Guidely] createGuidely() must be called in the browser. Create the client inside useEffect / onMount, or use the framework adapters.\");\n if (!options || !options.projectId) throw new Error(\"[Guidely] `projectId` (your environment public key, e.g. pk_dev_…) is required.\");\n this.options = {\n ...options,\n environment: options.environment ?? (options.projectId.startsWith(\"pk_prod\") ? \"production\" : options.projectId.startsWith(\"pk_stag\") ? \"staging\" : \"development\"),\n apiUrl: options.apiUrl ?? DEFAULT_API_URL,\n analytics: options.analytics ?? true,\n consent: options.consent ?? \"granted\",\n storage: options.storage ?? \"local\",\n configRefreshMs: options.configRefreshMs ?? 5 * 60 * 1000,\n pollIntervalMs: options.pollIntervalMs ?? 1000,\n debug: options.debug ?? false,\n };\n this.consent = this.options.consent;\n this.emitter = new Emitter<GuidelyEvents>((err) => this.reportError(err));\n this.api = new Api(this.options.apiUrl, this.options.projectId, options.fetch);\n this.store = createStorage(this.options.storage);\n this.sessionStore = this.options.storage === \"memory\" ? this.store : createStorage(\"session\");\n this.anonymousId = this.store.get(KEYS.anon) || \"\";\n if (!this.anonymousId) {\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n }\n this.firstVisit = !this.store.get(KEYS.seen);\n this.store.set(KEYS.seen, nowIso());\n this.state = { ...emptyState(), ...readJson<Partial<PersistedState>>(this.store, KEYS.state(this.options.projectId), {}) };\n this.user = readJson<GuidelyUser | null>(this.store, KEYS.user(this.options.projectId), null);\n const session = readJson<SessionState | null>(this.sessionStore, KEYS.session, null);\n this.session = session && session.id ? session : newSession();\n this.persistSession();\n this.lastUrl = this.pageHref();\n this.lastAudiences = new Set(this.state.audienceIds);\n this.queue = new EventQueue({\n store: this.store,\n storageKey: KEYS.queue(this.options.projectId),\n enabled: () => this.analyticsEnabled(),\n health: this.api.health,\n send: async (events) => {\n const res = await this.api.post<{ accepted: number }>(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }, { keepalive: true });\n return { ok: res.ok, retry: !(res.status >= 400 && res.status < 500 && res.status !== 429) };\n },\n beacon: (events) => this.api.beacon(\"/events\", { events, sentAt: nowIso(), sdk: { name: SDK_NAME, version: SDK_VERSION } }),\n onError: (err) => this.reportError(err),\n });\n this.outbox = new Outbox({ api: this.api, store: this.store, storageKey: KEYS.outbox(this.options.projectId), health: this.api.health });\n this.agentTurns = new AgentTurns({ api: this.api, store: this.store, storageKey: KEYS.agentOutbox(this.options.projectId), health: this.api.health, sdk: { name: SDK_NAME, version: SDK_VERSION } });\n if (options.user) this.user = { ...options.user };\n this.flags = this.createFlags(options.flags);\n }\n\n private createFlags(opts: GuidelyOptions[\"flags\"]): FlagsClient {\n const base = { sdkKey: this.options.projectId, apiUrl: this.options.apiUrl, fetch: this.options.fetch, sdk: { name: SDK_NAME, version: SDK_VERSION } };\n // Disabled: a client that never fetches and serves fallbacks, so `guidely.flags` is always usable.\n if (opts === false) return createFlagsClient({ ...base, overrideBehaviour: \"localOnly\", offline: true, reportUsage: false, trackExposures: false, storage: false, logger: null });\n const o = opts ?? {};\n return createFlagsClient({\n ...base,\n storage: { getItem: (k) => this.store.get(k), setItem: (k, v) => this.store.set(k, v), removeItem: (k) => this.store.remove(k) },\n reportUsage: this.options.analytics,\n // Failures surface through onError (and `debug` logs); development warnings (unknown flag keys) reach the console.\n logger: { warn: (...a: unknown[]) => console.warn(\"[Guidely]\", ...a), error: (...a: unknown[]) => this.log(...a) },\n ...o,\n contextAttributes: this.flagContext(),\n // Exposures travel through the event pipeline (with the session) as `experiment_viewed`.\n trackExposures: false,\n onFlagEvaluated: (result) => {\n this.trackExposure(result);\n o.onFlagEvaluated?.(result);\n },\n onReady: () => {\n this.emitter.emit(\"flags:ready\");\n o.onReady?.();\n },\n onChange: (data) => {\n this.emitter.emit(\"flags:change\");\n o.onChange?.(data);\n },\n onError: (err) => {\n this.reportError(err);\n o.onError?.(err);\n },\n });\n }\n\n // ---------------------------------------------------------------------------\n // Lifecycle\n // ---------------------------------------------------------------------------\n\n /** Loads config (cache first, then network), wires listeners and evaluates triggers. Idempotent. */\n init(): Promise<void> {\n if (this.readyPromise) return this.readyPromise;\n this.readyPromise = new Promise<void>((resolve) => {\n this.resolveReady = resolve;\n });\n void this.bootstrap();\n return this.readyPromise;\n }\n\n /** Resolves once the client is ready (alias of `init()`). */\n ready(): Promise<void> {\n return this.init();\n }\n\n private async bootstrap(): Promise<void> {\n this.wireErrorListeners();\n try {\n const cached = readJson<SdkConfigResponse | null>(this.store, KEYS.config(this.options.projectId), null);\n this.etag = this.store.get(KEYS.etag(this.options.projectId));\n if (cached && cached.guides) this.config = webOnly(cached);\n const before = this.config?.configVersion;\n const fresh = this.fetchConfig();\n // With a cached config a slow or unreachable server doesn't hold guides back: start from the\n // cache and apply the fresh config when it lands. Without one there is nothing to show yet.\n if (!this.config) await fresh;\n else if (!(await settlesWithin(fresh, CACHED_START_MS))) void fresh.then(() => this.applyConfigChange(before));\n if (this.destroyed) return;\n this.wireListeners();\n if (!this.identitySettled) {\n // identify() re-evaluates guides when it completes, so a slow answer is applied later too.\n const known = this.options.user ?? (this.user?.id ? this.user : null);\n if (known) await settlesWithin(this.identify(known.id, known.traits, known.account), CACHED_START_MS);\n }\n if (this.destroyed) return;\n this.isReady = true;\n if (this.config) this.emitter.emit(\"ready\", this.config);\n this.resolveReady?.();\n // Capture is detected before anything renders, so guides and widgets never appear in its screenshots.\n const capturing = !this.options.disableAuthoring && this.maybeStartCapture();\n this.renderPersistentWidgets();\n this.resumeActiveGuide();\n this.evaluate(\"ready\");\n if (!this.options.disableAuthoring && !capturing) this.maybeStartAuthoring();\n this.pageTracker.start(this.pageHref());\n this.touchSession(); // a page load is activity: rotate an expired session before capture starts\n this.syncCapture();\n } catch (err) {\n this.reportError(err);\n this.isReady = true;\n this.resolveReady?.();\n }\n }\n\n private async fetchConfig(): Promise<boolean> {\n try {\n const res = await this.api.get<SdkConfigResponse>(\"/config\", { etag: this.etag, params: { platform: \"web\" } });\n if (res.status === 304) return true;\n if (res.ok && res.data && Array.isArray(res.data.guides)) {\n this.config = webOnly(res.data);\n this.etag = res.etag;\n writeJson(this.store, KEYS.config(this.options.projectId), res.data);\n if (res.etag) this.store.set(KEYS.etag(this.options.projectId), res.etag);\n else this.store.remove(KEYS.etag(this.options.projectId));\n this.emitter.emit(\"config\", res.data);\n this.log(\"config loaded\", res.data.configVersion, `${res.data.guides.length} guides`);\n return true;\n }\n this.reportError(new Error(`[Guidely] config request failed (${res.status})${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n } catch (err) {\n this.reportError(new Error(`[Guidely] config request failed: ${err instanceof Error ? err.message : String(err)}${this.config ? \"; using cached config\" : \"\"}`));\n return false;\n }\n }\n\n private wireListeners(): void {\n const doc = document;\n const win = window;\n this.cleanups.push(watchNavigation((url) => this.handleNavigation(this.pageHref(url))));\n const onClick = (e: Event) => this.handleDocumentClick(e);\n doc.addEventListener(\"click\", onClick, true);\n this.cleanups.push(() => doc.removeEventListener(\"click\", onClick, true));\n const onVisibility = () => {\n const hidden = doc.visibilityState === \"hidden\";\n this.pageTracker.setHidden(hidden);\n if (!hidden) return;\n this.replay?.flushOnHide();\n this.queue.flushSync();\n };\n const onPageHide = () => {\n this.flushHeatmap();\n if (!this.pageLeft) this.leavePage(null);\n this.pageLeft = true;\n this.replay?.flushOnHide();\n this.queue.flushSync();\n };\n const onPageShow = (e: PageTransitionEvent) => {\n if (!e.persisted || !this.pageLeft) return;\n this.pageLeft = false;\n this.pageTracker.start(this.pageHref());\n };\n // Activity keeps the session alive (and rotates it after the inactivity timeout).\n let lastScroll = 0;\n const onScroll = () => {\n const now = Date.now();\n if (now - lastScroll < 250) return;\n lastScroll = now;\n this.pageTracker.measureScroll();\n this.touchSession();\n };\n const onKey = () => this.touchSession();\n // Mouse-movement heatmap: one sample (the latest position) per 200ms while the pointer moves; fine pointers only.\n let move: MouseEvent | null = null;\n let moveTimer: ReturnType<typeof setTimeout> | null = null;\n const onMove = (e: MouseEvent) => {\n move = e;\n moveTimer ??= setTimeout(() => {\n moveTimer = null;\n if (move) this.sampleMove(move);\n move = null;\n }, 200);\n };\n if (win.matchMedia?.(\"(pointer: fine)\").matches) {\n doc.addEventListener(\"mousemove\", onMove, { passive: true });\n this.cleanups.push(() => {\n doc.removeEventListener(\"mousemove\", onMove);\n if (moveTimer) clearTimeout(moveTimer);\n });\n }\n doc.addEventListener(\"visibilitychange\", onVisibility);\n win.addEventListener(\"pagehide\", onPageHide);\n win.addEventListener(\"pageshow\", onPageShow);\n win.addEventListener(\"scroll\", onScroll, { passive: true });\n doc.addEventListener(\"keydown\", onKey, true);\n this.cleanups.push(() => {\n doc.removeEventListener(\"visibilitychange\", onVisibility);\n win.removeEventListener(\"pagehide\", onPageHide);\n win.removeEventListener(\"pageshow\", onPageShow);\n win.removeEventListener(\"scroll\", onScroll);\n doc.removeEventListener(\"keydown\", onKey, true);\n });\n // Skipped while the API's circuit is open; the cached config keeps serving meanwhile.\n const refresh = setInterval(() => {\n if (this.api.health.canSend()) void this.refresh();\n }, this.options.configRefreshMs);\n // Back online: queued events, answers and recordings retry at once (see ServerHealth).\n const onOnline = () => this.api.health.online();\n win.addEventListener(\"online\", onOnline);\n this.cleanups.push(() => win.removeEventListener(\"online\", onOnline));\n this.cleanups.push(() => clearInterval(refresh));\n // Idle re-check: DOM can change without navigation (lazy content), so re-arm element-visibility\n // observers for eligible guides and drain the queue.\n const poll = setInterval(() => {\n if (!this.isReady || !this.config || this.editing() || doc.visibilityState === \"hidden\") return;\n const url = this.pageHref();\n const ctx = this.getContext();\n for (const guide of this.config.guides) {\n if (guide.config.trigger.type === \"element_visible\" && guide.config.trigger.value) this.armVisibility(guide, ctx, url);\n }\n this.drainQueue(url, ctx);\n }, Math.max(250, this.options.pollIntervalMs));\n this.cleanups.push(() => clearInterval(poll));\n const onMessage = (e: MessageEvent) => this.authoring?.handleMessage(e);\n win.addEventListener(\"message\", onMessage);\n this.cleanups.push(() => win.removeEventListener(\"message\", onMessage));\n }\n\n /** Uncaught errors + unhandled rejections; attached before the config loads so boot errors are kept. */\n private wireErrorListeners(): void {\n const win = window;\n const onError = (e: ErrorEvent) => this.captureGlobalException(errorEventToException(e));\n const onRejection = (e: PromiseRejectionEvent) => this.captureGlobalException(rejectionToException(e));\n win.addEventListener(\"error\", onError);\n win.addEventListener(\"unhandledrejection\", onRejection);\n this.cleanups.push(() => {\n win.removeEventListener(\"error\", onError);\n win.removeEventListener(\"unhandledrejection\", onRejection);\n });\n }\n\n /** Re-fetches the published config and re-evaluates triggers. */\n async refresh(): Promise<void> {\n if (this.destroyed) return;\n const before = this.config?.configVersion;\n await this.fetchConfig();\n this.applyConfigChange(before);\n }\n\n /** Re-renders after a config change (refresh, or a config that arrived after start). */\n private applyConfigChange(before: number | undefined): void {\n if (this.destroyed || !this.isReady) return;\n if (this.config && this.config.configVersion !== before) {\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n }\n this.syncCapture();\n }\n\n /** Tears everything down: guides, widgets, listeners, timers, host element. Re-init is allowed via a new client. */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.active?.controller?.destroy();\n this.active?.survey?.destroy();\n this.active?.scope?.destroy();\n this.active = null;\n this.queued = [];\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n this.resourceCenter?.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.destroyMessenger();\n this.visibilityObservers.forEach((stop) => stop());\n this.visibilityObservers.clear();\n this.timers.forEach((t) => clearTimeout(t));\n this.timers.clear();\n this.cleanups.splice(0).forEach((fn) => fn());\n this.authoring?.stop();\n this.authoring = null;\n this.capture?.destroy();\n this.capture = null;\n this.replay?.destroy();\n this.replay = null;\n this.queue.flushSync();\n this.queue.destroy();\n this.outbox.destroy();\n this.agentTurns.destroy();\n this.flags.destroy();\n this.emitter.clear();\n destroyHost();\n if (current === this) current = null;\n }\n\n // ---------------------------------------------------------------------------\n // Identity\n // ---------------------------------------------------------------------------\n\n /** Identifies the end user and loads server-held state (audiences, guide history, checklist progress). */\n async identify(userId: string, traits?: Record<string, unknown>, account?: GuidelyAccount): Promise<void> {\n if (this.destroyed) return;\n this.identitySettled = true;\n this.user = { id: String(userId), traits: { ...(this.user?.id === String(userId) ? this.user.traits : {}), ...(traits || {}) }, account: account ?? (this.user?.id === String(userId) ? this.user.account : undefined) };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n this.syncFlagAttributes();\n this.enqueue(\"identify\", { properties: { traits: sanitizeProperties(this.user.traits) } });\n await this.syncIdentify();\n this.emitter.emit(\"identify\", { userId: this.user.id, anonymousId: this.anonymousId });\n if (this.isReady) this.evaluate(\"identify\");\n }\n\n private async syncIdentify(): Promise<void> {\n const body: IdentifyRequest = { anonymousId: this.anonymousId, userId: this.user?.id ?? null, traits: this.user?.traits, account: this.user?.account ? { id: this.user.account.id, traits: this.user.account.traits } : null, sessionId: this.session.id, url: this.collectUrls() ? this.pageHref() : undefined };\n const res = await postWithRetry<IdentifyResponse>(this.api, \"/identify\", body, 2);\n if (res?.ok && res.data) this.mergeServerState(res.data);\n }\n\n private mergeServerState(data: IdentifyResponse): void {\n const guides = { ...this.state.guides };\n for (const [id, s] of Object.entries(data.guideState || {})) {\n const local = guides[id];\n guides[id] = {\n ...local,\n impressions: Math.max(local?.impressions ?? 0, s.impressions ?? 0),\n completedAt: local?.completedAt ?? s.completedAt ?? null,\n dismissedAt: local?.dismissedAt ?? s.dismissedAt ?? null,\n lastShownAt: local?.lastShownAt ?? s.lastShownAt ?? null,\n };\n }\n const checklists = { ...this.state.checklists };\n for (const [id, p] of Object.entries(data.checklistProgress || {})) {\n const local = checklists[id];\n checklists[id] = {\n completedTaskIds: Array.from(new Set([...(local?.completedTaskIds ?? []), ...(p.completedTaskIds ?? [])])),\n completedAt: local?.completedAt ?? p.completedAt ?? null,\n dismissedAt: dismissedAfterMerge(local, p),\n dismissResetAt: p.dismissResetAt ?? local?.dismissResetAt ?? null,\n };\n }\n this.state = {\n guides,\n checklists,\n surveysSubmitted: Array.from(new Set([...this.state.surveysSubmitted, ...(data.surveysSubmitted || [])])),\n audienceIds: data.audienceIds || [],\n firstSeenAt: this.state.firstSeenAt ?? data.firstSeenAt,\n // Device-local only (the server doesn't hold them).\n ...(this.state.throttle ? { throttle: this.state.throttle } : {}),\n ...(this.state.announcementsSeenAt ? { announcementsSeenAt: this.state.announcementsSeenAt } : {}),\n };\n if (data.firstSeenAt && Date.now() - Date.parse(data.firstSeenAt) > 60_000) this.firstVisit = false;\n this.persistState();\n this.syncFlagAttributes(); // audiences\n this.widgets.forEach((w, id) => {\n const g = this.findGuide(id);\n if (w.checklist && g) w.checklist.setProgress(this.getChecklistProgress(g.id));\n });\n // Name, audiences and progress may have changed.\n this.messenger?.refresh();\n }\n\n /** Sets or replaces the account (company/organisation) for the current user. */\n async setAccount(account: GuidelyAccount): Promise<void> {\n if (!this.user) {\n this.user = { id: \"\", account };\n writeJson(this.store, KEYS.user(this.options.projectId), this.user);\n this.syncFlagAttributes();\n return;\n }\n await this.identify(this.user.id, undefined, account);\n }\n\n /** Merges additional traits into the current user. */\n async updateTraits(traits: Record<string, unknown>): Promise<void> {\n if (!this.user?.id) {\n this.user = { id: \"\", traits: { ...(this.user?.traits || {}), ...traits } };\n this.syncFlagAttributes();\n return;\n }\n await this.identify(this.user.id, traits, this.user.account);\n }\n\n /** Forgets the user: new anonymous id, cleared local guide/checklist state, triggers re-evaluated. */\n reset(): void {\n this.identitySettled = true;\n this.stopGuide();\n this.user = null;\n this.store.remove(KEYS.user(this.options.projectId));\n this.anonymousId = `anon_${randomId(20)}`;\n this.store.set(KEYS.anon, this.anonymousId);\n this.state = emptyState();\n this.persistState();\n this.session = newSession();\n this.persistSession();\n this.sessionStore.remove(KEYS.active);\n this.replay?.stop(); // the recording belongs to the previous user; restarted below when eligible\n this.syncCapture();\n this.lastAudiences = new Set();\n this.firedDelays.clear();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n // Conversations belong to the previous user: forget their tokens and rebuild the messenger.\n forgetConversations(this.store, this.options.projectId);\n this.destroyMessenger();\n this.exposures.clear();\n this.syncFlagAttributes();\n this.emitter.emit(\"identify\", { userId: null, anonymousId: this.anonymousId });\n if (this.isReady) {\n this.renderPersistentWidgets();\n this.evaluate(\"identify\");\n }\n }\n\n // ---------------------------------------------------------------------------\n // Events\n // ---------------------------------------------------------------------------\n\n /** Updates consent at runtime (`granted` flushes buffered events; `denied` drops them). */\n setConsent(consent: ConsentState): void {\n this.consent = consent;\n if (consent === \"denied\") this.queue.clear();\n else if (consent === \"granted\") void this.queue.flush();\n if (consent !== \"granted\") this.replay?.stop({ discard: true });\n if (consent !== \"pending\") this.agentTurns.consentChanged(consent === \"granted\");\n this.syncCapture();\n }\n\n private analyticsEnabled(): boolean {\n return this.options.analytics && this.consent === \"granted\" && (this.config?.settings?.analyticsEnabled ?? true);\n }\n\n private collectUrls(): boolean {\n return this.config?.settings?.collectUrls ?? true;\n }\n\n private enqueue(name: EventName, extra: Partial<SdkEvent> = {}): SdkEvent | null {\n if (this.consent === \"denied\" || !this.options.analytics) return null;\n if (name !== \"page_leave\" && name !== \"heatmap\") this.touchSession();\n const event: SdkEvent = {\n eventId: randomId(24),\n name,\n occurredAt: nowIso(),\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n accountId: this.user?.account?.id || null,\n sessionId: this.session.id,\n url: this.collectUrls() ? this.pageHref() : undefined,\n ...extra,\n };\n if (extra.properties) event.properties = sanitizeProperties(extra.properties);\n const locale = extra.guideId ? this.guideLocales.get(extra.guideId) : undefined;\n if (locale) event.properties = { ...(event.properties ?? {}), locale };\n this.queue.enqueue(event);\n this.replay?.addCustomEvent(\"guidely\", { name, customName: event.customName, guideId: event.guideId });\n this.emitter.emit(\"track\", event);\n return event;\n }\n\n /** Tracks a custom event. Events drive `event` triggers, `advanceOn: \"event\"` steps and checklist tasks. */\n track(name: string, properties?: Record<string, unknown>): void {\n if (this.destroyed || !name) return;\n if (!this.session.events.includes(name)) {\n this.session.events.push(name);\n this.persistSession();\n }\n this.enqueue(\"custom\", { customName: name.slice(0, 120), properties: properties ?? {} });\n this.customListeners.get(name)?.forEach((cb) => {\n try {\n cb();\n } catch (err) {\n this.reportError(err);\n }\n });\n this.completeChecklistTasksBy(\"event\", name);\n if (this.isReady) this.evaluate(\"event\", { eventName: name });\n }\n\n /**\n * Agent Analytics: records one or more turns of a conversation with your own AI agent or chatbot\n * (`{ conversationId, agentId, role, text, toolCalls?, latencyMs?, outcome?, … }`). The visitor's\n * anonymous id, user id, account id and session id are filled in, `agents.redact` from the init\n * options runs on each turn, and turns are retried until Guidely accepts them. Returns false when\n * nothing was queued (analytics off or consent denied, or every turn was invalid or dropped).\n */\n agentConversation(turns: AgentTurnInput | AgentTurnInput[]): boolean {\n if (this.destroyed || !this.options.analytics || this.consent === \"denied\" || this.config?.settings?.analyticsEnabled === false) return false;\n const identity = { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, sessionId: this.session.id };\n const prepared = (Array.isArray(turns) ? turns : [turns]).map((t) => prepareAgentTurn(t, identity, this.options.agents?.redact, (err) => this.reportError(err))).filter((t): t is AgentTurnInput => !!t);\n if (!prepared.length) return false;\n this.touchSession();\n this.agentTurns.add(prepared, this.consent === \"pending\");\n return true;\n }\n\n /** Alias of {@link agentConversation}. */\n trackAgentTurn(turns: AgentTurnInput | AgentTurnInput[]): boolean {\n return this.agentConversation(turns);\n }\n\n /** Records a page view and re-evaluates triggers. Called automatically on SPA navigation. */\n page(href?: string): void {\n if (this.destroyed) return;\n const url = this.pageHref(href);\n this.leavePage(url);\n this.trackPageView(url);\n this.handleNavigation(url, true);\n }\n\n private readonly customListeners = new Map<string, Set<() => void>>();\n private readonly eventBus = {\n on: (name: string, cb: () => void) => {\n let set = this.customListeners.get(name);\n if (!set) {\n set = new Set();\n this.customListeners.set(name, set);\n }\n set.add(cb);\n return () => {\n set?.delete(cb);\n };\n },\n };\n\n private handleNavigation(url: string, explicit = false): void {\n if (this.destroyed) return;\n const changed = url !== this.lastUrl;\n this.lastUrl = url;\n if (changed) this.syncFlagAttributes();\n if (!explicit && changed) {\n this.leavePage(url);\n this.trackPageView(url);\n }\n this.completeChecklistTasksBy(\"url_visited\", url);\n this.active?.controller?.resume();\n if (this.active?.controller) {\n const st = this.active.controller.getState();\n if (st.status === \"running\" && !this.active.manual) {\n const g = this.active.guide;\n if (g.config.urlPatterns.length && !g.config.urlPatterns.some((p) => urlMatches(p, url))) this.active.controller.destroy();\n }\n }\n // Banners and hotspots are page-scoped too: close the ones whose URL patterns no longer match.\n this.widgets.forEach((w, id) => {\n if (!w.controller || w.manual) return;\n const g = this.findGuide(id);\n if (g?.config.urlPatterns.length && !g.config.urlPatterns.some((p) => urlMatches(p, url))) w.controller.destroy();\n });\n this.firedDelays.clear();\n if (this.isReady) this.evaluate(\"navigation\");\n if (changed) this.messenger?.refresh();\n if (changed) void this.queue.flush();\n }\n\n private handleDocumentClick(e: Event): void {\n const target = composedTarget(e);\n if (!target || typeof target.closest !== \"function\") return;\n this.autocaptureClick(e as MouseEvent, target);\n this.completeChecklistTasksBy(\"click\", target);\n if (this.isReady) this.evaluate(\"click\", { target });\n }\n\n // ---------------------------------------------------------------------------\n // Product analytics: sessions, page views, clicks, errors, session replay\n // ---------------------------------------------------------------------------\n\n /** Records activity; starts a new session after `sessionTimeoutMinutes` of inactivity or 24h. */\n private touchSession(): void {\n const now = Date.now();\n const s = this.session;\n const timeout = Math.max(1, this.config?.settings?.sessionTimeoutMinutes ?? 30) * 60_000;\n const last = s.lastActivityAt ?? now;\n if (now - last > timeout || now - (Date.parse(s.startedAt) || now) > DAY_MS) return this.rotateSession(now);\n if (now - (s.lastActivityAt ?? 0) < 1000) return;\n s.lastActivityAt = now;\n this.persistSession();\n }\n\n private rotateSession(now: number): void {\n this.session = newSession(now);\n this.persistSession();\n this.log(\"session rotated\", this.session.id);\n if (this.replay?.activeSessionId) this.replay.stop();\n this.syncReplay();\n }\n\n /** Autocapture, error tracking and replay need analytics on, consent granted and no authoring or how-to capture session. */\n private captureAllowed(): boolean {\n return !this.destroyed && this.analyticsEnabled() && !this.editing();\n }\n\n /** Authoring or how-to capture is running: no guides, widgets, replay or autocapture. */\n private editing(): boolean {\n return !!this.authoring?.isActive() || this.captureStarting || !!this.capture?.isActive();\n }\n\n /** A capability is on when the project enables it (absent on old servers → off) and no option turns it off. */\n private autocaptureOn(key: keyof AutocaptureSettings): boolean {\n const o = this.options.autocapture;\n return !!this.config?.settings?.autocapture?.[key] && o !== false && !(typeof o === \"object\" && o[key] === false) && this.captureAllowed();\n }\n\n /** Page views on SPA navigation predate autocapture: only an explicit opt-out stops them. */\n private pageviewsOn(): boolean {\n const o = this.options.autocapture;\n return this.config?.settings?.autocapture?.pageviews !== false && o !== false && !(typeof o === \"object\" && o.pageviews === false) && !this.editing();\n }\n\n private trackPageView(url: string): void {\n if (url === this.pageViewUrl || !this.pageviewsOn()) return;\n this.pageViewUrl = url;\n this.touchSession();\n const collect = this.collectUrls();\n const device = detectDevice(navigator.userAgent, window.innerWidth);\n const props: Record<string, unknown> = { deviceType: device.type, browser: device.browser, os: device.os, screenWidth: window.screen?.width, viewportWidth: window.innerWidth };\n if (collect) {\n props.path = pathOf(url);\n props.title = (document.title || \"\").slice(0, 200);\n const ref = !this.session.pageViews ? externalReferrer() : undefined;\n if (ref) props.referrer = ref;\n }\n const ep = this.captureAllowed() ? pagePropertyValues(this.config?.tagging, url, { mask: this.maskSelector(), maskAll: this.maskAllText() }) : undefined;\n if (ep) props.ep = ep;\n this.session.pageViews = (this.session.pageViews ?? 0) + 1;\n this.persistSession();\n this.enqueue(\"page_view\", { url: collect ? url : undefined, properties: props });\n }\n\n /** Emits `page_leave` for the page being left and starts measuring `nextUrl` (null: page unload). */\n private leavePage(nextUrl: string | null): void {\n const t = this.pageTracker;\n if (!t.url || t.url === nextUrl) return;\n this.flushHeatmap();\n if (!this.pageLeft && this.autocaptureOn(\"pageLeave\")) {\n const info = t.leave();\n const collect = this.collectUrls();\n this.enqueue(\"page_leave\", { url: collect ? info.url : undefined, properties: { ...(collect ? { path: pathOf(info.url) } : {}), durationMs: info.durationMs, scrollDepth: info.scrollDepth } });\n }\n if (nextUrl !== null) {\n t.start(nextUrl);\n this.pageLeft = false;\n }\n }\n\n private autocaptureClick(e: MouseEvent, target: Element): void {\n const clicks = this.autocaptureOn(\"clicks\");\n const rage = this.autocaptureOn(\"rageClicks\");\n const heat = this.autocaptureOn(\"heatmaps\");\n if ((!clicks && !rage && !heat) || isIgnoredElement(target)) return;\n this.touchSession();\n // An element carrying the feature attribute (or inside one) counts as clicked even when not interactive.\n const featureAttribute = this.config?.tagging?.featureAttribute ?? null;\n const feature = featureAttributeOf(target, featureAttribute);\n const el = interactiveElement(target) ?? feature?.el ?? null;\n const opts = { mask: this.maskSelector(), maskAll: this.maskAllText(), collectUrls: this.collectUrls() };\n const clickProps = (on: Element) => {\n const p = describeClick(on, e, opts);\n const ep = clickPropertyValues(this.config?.tagging, on, p, opts);\n return { ...p, el: elementSnapshot(on, { ...opts, featureAttribute }), ...(feature ? { fa: feature.value } : {}), ...(ep ? { ep } : {}) };\n };\n if (clicks && el) this.enqueue(\"click\", { properties: clickProps(el) });\n const count = this.rage.add(e.pageX ?? 0, e.pageY ?? 0, Date.now());\n if (rage && count) this.enqueue(\"rage_click\", { properties: { ...clickProps(el ?? target), count } });\n if (!heat) return;\n const url = this.pageHref();\n if (this.heatmap.url !== url) this.flushHeatmap();\n if (this.heatmap.add(url, heatmapPoint(el ?? target, e, this.rage.burst > 0), this.rage.burst)) this.flushHeatmap();\n }\n\n /** Bins one pointer sample into the heatmap buffer. Not session activity. */\n private sampleMove(e: MouseEvent): void {\n const target = composedTarget(e);\n if (document.visibilityState === \"hidden\" || !target?.closest || !this.autocaptureOn(\"mouseMovement\") || isIgnoredElement(target)) return;\n const url = this.pageHref();\n if (this.heatmap.url !== url) this.flushHeatmap();\n if (this.heatmap.move(url, movementBin(interactiveElement(target) ?? target, e))) this.flushHeatmap();\n }\n\n /** Sends the buffered heatmap clicks as one `heatmap` event attributed to the page they happened on. */\n private flushHeatmap(): void {\n const batch = this.heatmap.take();\n if (!batch || !this.captureAllowed()) return;\n const collect = this.collectUrls();\n const de = document.documentElement;\n const properties = { path: collect ? pathOf(batch.url) : undefined, viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, pageHeight: Math.max(de.scrollHeight, document.body?.scrollHeight || 0), points: batch.points };\n if (!collect) delete properties.path;\n this.enqueue(\"heatmap\", { url: collect ? batch.url : undefined, properties });\n }\n\n private captureGlobalException(props: ExceptionProperties | null): void {\n if (!props || isGuidelyException(props) || this.options.captureErrors === false) return;\n if (!this.config) {\n if (this.earlyExceptions.length < 10) this.earlyExceptions.push([props, undefined]);\n return;\n }\n this.sendException(props);\n }\n\n /**\n * Reports a caught error as an `exception` event (`source: \"manual\"`, `handled: true`), grouped\n * into an issue on the Errors page. Extra properties are attached to the occurrence. Needs the\n * project's error tracking on (plus analytics + consent); `captureErrors: false` does not stop it.\n */\n captureException(error: unknown, properties?: Record<string, unknown>): void {\n if (this.destroyed) return;\n const props = exceptionFromError(error, \"manual\", true);\n if (!this.config) {\n if (this.earlyExceptions.length < 10) this.earlyExceptions.push([props, properties]);\n return;\n }\n this.sendException(props, properties);\n }\n\n private sendException(props: ExceptionProperties, extra?: Record<string, unknown>): void {\n // Error tracking off (or a server that predates it and would reject the event): nothing is sent.\n if (!this.config?.settings?.errorTracking?.enabled || !this.captureAllowed() || !this.exceptionThrottle.allow(props)) return;\n const count = this.session.exceptions ?? 0;\n if (count >= MAX_SESSION_EXCEPTIONS) return;\n const properties: Record<string, unknown> = { ...props };\n if (this.options.release) properties.release = String(this.options.release).slice(0, 100);\n for (const [k, v] of Object.entries(extra ?? {})) if (!(k in properties)) properties[k] = v;\n this.enqueue(\"exception\", { properties });\n this.session.exceptions = count + 1;\n this.persistSession();\n }\n\n private maskSelector(): string {\n return validSelectors([...DEFAULT_MASK_SELECTORS, ...(this.config?.settings?.maskSelectors || []), ...(this.options.maskSelectors || [])]).join(\",\");\n }\n\n private maskAllText(): boolean {\n const o = this.options.sessionReplay;\n return !!this.config?.settings?.replay?.maskAllText || (typeof o === \"object\" && !!o.maskAllText);\n }\n\n /** Replay settings for this installation, or null when the project (or an option) disables replay. */\n private replayConfig(): { sampleRate: number; config: ReplayRecordingConfig } | null {\n const r = this.config?.settings?.replay;\n const o = this.options.sessionReplay;\n if (!r?.enabled || o === false) return null;\n const opt = typeof o === \"object\" ? o : {};\n const extra = opt.blockSelectors || [];\n return {\n sampleRate: r.sampleRate ?? 100,\n config: {\n recordConsole: r.recordConsole !== false,\n maskTextSelector: this.maskAllText() ? \"*\" : this.maskSelector(),\n blockSelector: validSelectors([\"[data-guidely-block]\", ...(r.blockSelectors || []), ...extra]).join(\",\"),\n network: r.recordNetwork && opt.recordNetwork !== false ? { payloads: !!r.recordNetworkPayloads && opt.recordNetworkPayloads !== false, apiUrl: this.options.apiUrl, mask: opt.maskNetworkRequest } : null,\n },\n };\n }\n\n /** Reconciles capture with the current config / consent / authoring state. Idempotent. */\n private syncCapture(): void {\n if (!this.isReady || this.destroyed) return;\n if (this.config && !this.initialPageViewSent && this.config.settings?.autocapture) {\n this.initialPageViewSent = true;\n this.trackPageView(this.pageHref());\n }\n if (this.config) {\n for (const [props, extra] of this.earlyExceptions.splice(0)) {\n if (props.handled) this.sendException(props, extra);\n else this.captureGlobalException(props);\n }\n }\n this.syncReplay();\n }\n\n private syncReplay(): void {\n const cfg = this.isReady && this.captureAllowed() ? this.replayConfig() : null;\n if (cfg && this.session.replay === undefined) {\n this.session.replay = rolloutBucket(this.session.id, \"replay\") < cfg.sampleRate;\n this.persistSession();\n }\n if (!cfg || !this.session.replay) {\n if (this.replay?.activeSessionId) this.replay.stop({ discard: !this.analyticsEnabled() });\n return;\n }\n if (this.replay) return this.replay.start(this.session.id, cfg.config);\n if (this.replayLoading) return;\n this.replayLoading = true;\n loadRecorder().then(\n (api) => {\n this.replayLoading = false;\n if (this.destroyed || this.replay) return;\n this.replay = api.createReplay({\n url: (params) => this.api.url(\"/replay\", params),\n fetch: () => this.options.fetch ?? (typeof fetch === \"function\" ? fetch.bind(globalThis) : null),\n meta: () => {\n const device = detectDevice(navigator.userAgent, window.innerWidth);\n return {\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n url: this.collectUrls() ? this.pageHref() : undefined,\n device: { type: device.type, browser: device.browser, os: device.os },\n viewport: { width: window.innerWidth, height: window.innerHeight },\n sdk: { name: SDK_NAME, version: SDK_VERSION },\n };\n },\n onDisabled: (sessionId) => {\n if (sessionId !== this.session.id) return;\n this.session.replay = false;\n this.persistSession();\n this.replay?.stop({ discard: true });\n },\n onError: (err) => this.reportError(err),\n health: this.api.health,\n stash: this.sessionStore,\n });\n this.syncReplay(); // re-decide: consent, session or settings may have changed while loading\n },\n (err) => {\n this.replayLoading = false;\n this.reportError(err);\n },\n );\n }\n\n /**\n * Records this session even when it was not sampled, provided the project has session replay\n * enabled (and analytics + consent allow it). The decision sticks for the rest of the session.\n */\n startSessionRecording(): void {\n if (this.destroyed) return;\n this.session.replay = true;\n this.persistSession();\n this.syncReplay();\n }\n\n /** Stops recording for the rest of this session (what was recorded so far is uploaded). */\n stopSessionRecording(): void {\n this.session.replay = false;\n this.persistSession();\n this.replay?.stop();\n }\n\n /** True while the session is being recorded. */\n isRecording(): boolean {\n return !!this.replay?.isRecording();\n }\n\n /** The current analytics session id (rotates after inactivity; also the replay id). */\n getSessionId(): string {\n return this.session.id;\n }\n\n // ---------------------------------------------------------------------------\n // Targeting + triggers\n // ---------------------------------------------------------------------------\n\n /** The page URL Guidely works with: `options.pageUrl`, else app-relative for `file:` / custom protocols (`normalizeAppUrl`). */\n pageHref(href: string = location.href): string {\n try {\n return this.options.pageUrl ? this.options.pageUrl(href) || href : normalizeAppUrl(href);\n } catch {\n return href;\n }\n }\n\n /** Builds the targeting context for the current moment. */\n getContext(): TargetingContext {\n const guides = this.state.guides;\n const completedChecklists = Object.entries(this.state.checklists).filter(([, p]) => !!p.completedAt).map(([id]) => id);\n const keysOf = (ids: string[]) => ids.flatMap((id) => [id, this.findGuide(id)?.key ?? id]);\n return buildContext({\n anonymousId: this.anonymousId,\n userId: this.user?.id || null,\n userAttributes: this.user?.traits ?? {},\n accountAttributes: this.user?.account?.traits ?? {},\n url: this.pageHref(),\n firstVisit: this.firstVisit,\n eventsSeen: this.session.events,\n completedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.completedAt)),\n dismissedGuides: keysOf(Object.keys(guides).filter((id) => guides[id]?.dismissedAt)),\n seenGuides: keysOf(Object.keys(guides).filter((id) => (guides[id]?.impressions ?? 0) > 0)),\n completedChecklists: keysOf(completedChecklists),\n audienceIds: this.state.audienceIds,\n environment: this.options.environment,\n platform: \"web\",\n ...(this.options.appVersion ? { appVersion: this.options.appVersion } : {}),\n });\n }\n\n private isTargeted(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n const c = guide.config;\n if (c.urlPatterns.length && !c.urlPatterns.some((p) => urlMatches(p, url))) return false;\n if (c.trigger.urlPattern && !urlMatches(c.trigger.urlPattern, url)) return false;\n if (!isWithinSchedule(guide)) return false;\n if (guide.kind === \"survey\" && (this.state.surveysSubmitted.includes(guide.id) || this.state.surveysSubmitted.includes(guide.key))) return false;\n ctx.rolloutSalt = guide.id;\n return evaluateRules(c.targeting, ctx);\n }\n\n /** Guide throttling: may this guide launch automatically now? */\n private throttleAllows(guide: PublishedGuide): boolean {\n if (!countsTowardThrottle(guide)) return true;\n return isThrottleEligible(this.config?.settings.throttling, this.state.throttle ?? []);\n }\n\n private recordLaunch(guide: PublishedGuide, manual: boolean): void {\n if (manual || !countsTowardThrottle(guide) || !this.config?.settings.throttling?.enabled) return;\n this.state.throttle = pruneLaunches([...(this.state.throttle ?? []), nowIso()], this.config.settings.throttling);\n this.persistState();\n }\n\n /** Guides and A/B test control groups, which are evaluated the same way but never render. */\n private candidates(): PublishedGuide[] {\n const guides = this.config?.guides ?? [];\n const holdouts = this.config?.guideHoldouts ?? [];\n return holdouts.length ? [...guides, ...holdouts.map((h) => h.guide)] : guides;\n }\n\n private holdoutFor(guide: PublishedGuide) {\n return this.config?.guideHoldouts?.find((h) => h.guide.id === guide.id) ?? null;\n }\n\n /** The visitor's language candidates, most preferred first. */\n private locales(): string[] {\n const nav = typeof navigator !== \"undefined\" ? [...(navigator.languages ?? []), navigator.language] : [];\n return visitorLocales(this.locale ?? this.options.locale, this.user?.traits, nav);\n }\n\n private defaultLocale(): string {\n return this.config?.settings.localization?.defaultLocale || \"en\";\n }\n\n /** The guide in the visitor's language (remembered so its events carry `locale`). */\n private localize(guide: PublishedGuide): PublishedGuide {\n const localized = localizeGuide(guide, this.locales(), this.defaultLocale());\n this.guideLocales.set(guide.id, localized.locale);\n return localized;\n }\n\n /**\n * Sets the language for guides and the resource center (`null` = back to the traits / browser).\n * Guides already on screen keep their language; the resource center re-renders.\n */\n setLocale(locale: string | null): void {\n this.locale = locale ? normalizeLocale(locale) || null : null;\n if (this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.renderPersistentWidgets();\n }\n }\n\n private isEligible(guide: PublishedGuide, ctx: TargetingContext, url: string): boolean {\n if (!this.isTargeted(guide, ctx, url)) return false;\n const shownThisSession = this.session.shownGuides.includes(guide.id);\n if (guide.kind === \"checklist\") {\n const p = this.state.checklists[guide.id];\n return !p?.dismissedAt;\n }\n return isFrequencyEligible(guide.config.frequency, this.state.guides[guide.id], shownThisSession);\n }\n\n private triggerFires(guide: PublishedGuide, reason: EvalReason, detail: EvalDetail): boolean {\n const t = guide.config.trigger;\n switch (t.type) {\n case \"page_load\":\n // A delayed page_load re-evaluates from its own timer.\n if (t.delayMs > 0) return reason === \"timer\" && detail.guideId === guide.id;\n return reason === \"ready\" || reason === \"navigation\" || reason === \"identify\";\n case \"url_match\":\n return (reason === \"ready\" || reason === \"navigation\" || reason === \"identify\") && urlMatches(t.value, this.pageHref());\n case \"event\":\n return reason === \"event\" && !!t.value && detail.eventName === t.value;\n case \"element_click\":\n if (reason !== \"click\" || !t.value || !detail.target) return false;\n try {\n return !!closestComposed(detail.target, t.value);\n } catch {\n return false;\n }\n case \"element_visible\":\n return reason === \"visible\" && detail.guideId === guide.id;\n case \"delay\":\n return reason === \"timer\" && detail.guideId === guide.id;\n case \"after_guide\":\n return reason === \"after_guide\" && !!detail.endedGuide && (detail.endedGuide.id === t.value || detail.endedGuide.key === t.value);\n case \"segment_enter\":\n return reason === \"identify\" && !!t.value && !!detail.newAudiences?.has(t.value);\n case \"manual\":\n default:\n return false;\n }\n }\n\n private evaluate(reason: EvalReason, detail: EvalDetail = {}): void {\n if (!this.config || this.destroyed || this.editing()) return;\n const url = this.pageHref();\n const ctx = this.getContext();\n if (reason === \"identify\") {\n const current = new Set(this.state.audienceIds);\n detail.newAudiences = new Set(Array.from(current).filter((a) => !this.lastAudiences.has(a)));\n this.lastAudiences = current;\n }\n const candidates: PublishedGuide[] = [];\n for (const guide of this.candidates()) {\n const t = guide.config.trigger;\n if (detail.endedGuide && detail.endedGuide.id === guide.id) continue; // never re-show the guide that just ended\n // Arm element-visibility observers and delay timers on page-level evaluations.\n if (reason === \"ready\" || reason === \"navigation\") {\n if (t.type === \"element_visible\" && t.value) this.armVisibility(guide, ctx, url);\n if ((t.type === \"delay\" || (t.type === \"page_load\" && t.delayMs > 0)) && !this.firedDelays.has(guide.id)) {\n if (!this.isEligible(guide, ctx, url)) continue;\n this.firedDelays.add(guide.id);\n this.setTimer(() => this.evaluate(\"timer\", { guideId: guide.id }), t.delayMs);\n continue;\n }\n }\n if (t.type === \"page_load\" && t.delayMs > 0 && reason !== \"timer\") continue;\n if (t.type === \"page_load\" && t.delayMs > 0 && reason === \"timer\" && detail.guideId !== guide.id) continue;\n if (!this.triggerFires(guide, reason, detail)) continue;\n if (!this.isEligible(guide, ctx, url)) continue;\n if (!this.throttleAllows(guide)) {\n this.log(\"throttled\", guide.key);\n continue;\n }\n candidates.push(guide);\n }\n if (reason === \"after_guide\" || reason === \"navigation\") this.drainQueue(url, ctx);\n if (!candidates.length) return;\n candidates.sort((a, b) => a.config.frequency.priority - b.config.frequency.priority);\n for (const guide of candidates) {\n if (this.widgets.has(guide.id) || this.active?.guide.id === guide.id) continue;\n const delay = guide.config.trigger.type !== \"delay\" && guide.config.trigger.type !== \"page_load\" ? guide.config.trigger.delayMs : 0;\n if (delay > 0) {\n this.setTimer(() => this.tryShow(guide, url, false), delay);\n continue;\n }\n this.tryShow(guide, url, false);\n }\n }\n\n private armVisibility(guide: PublishedGuide, ctx: TargetingContext, url: string): void {\n const selector = guide.config.trigger.value;\n if (!selector || this.visibilityObservers.has(guide.id)) return;\n if (!this.isEligible(guide, ctx, url)) return;\n const ac = new AbortController();\n let io: IntersectionObserver | null = null;\n const stop = () => {\n ac.abort();\n io?.disconnect();\n this.visibilityObservers.delete(guide.id);\n };\n this.visibilityObservers.set(guide.id, stop);\n waitForTarget([{ kind: \"css\", value: selector }], { timeoutMs: 0, signal: ac.signal })\n .then((el) => {\n if (ac.signal.aborted) return;\n const fire = () => {\n stop();\n this.evaluate(\"visible\", { guideId: guide.id });\n };\n if (typeof IntersectionObserver === \"undefined\") return fire();\n io = new IntersectionObserver((entries) => {\n if (entries.some((e) => e.isIntersecting)) fire();\n });\n io.observe(el);\n })\n .catch(() => stop());\n }\n\n private setTimer(fn: () => void, ms: number): void {\n const t = setTimeout(() => {\n this.timers.delete(t);\n if (!this.destroyed) fn();\n }, ms);\n this.timers.add(t);\n }\n\n /** Decides whether a guide can show now, otherwise queues it. */\n private tryShow(guide: PublishedGuide, url: string, manual: boolean): boolean {\n if (this.destroyed) return false;\n // Another automatic guide may have launched since this one was picked (delays, queue).\n if (!manual && !this.throttleAllows(guide)) return false;\n const holdout = this.holdoutFor(guide);\n if (holdout) {\n // A/B test control group: count the exposure as if the guide had shown, render nothing.\n if (this.active && !manual) return false;\n this.recordImpression(guide, manual);\n return true;\n }\n if (!isExclusiveGuide(guide)) {\n if (this.widgets.has(guide.id)) return false;\n this.show(guide, manual);\n return true;\n }\n if (this.active) {\n if (this.active.guide.id === guide.id) return false;\n if (manual) this.stopGuide();\n else {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: PAGE_SCOPED.has(guide.config.trigger.type) });\n this.log(\"queued\", guide.key, \"behind\", this.active.guide.key);\n return false;\n }\n }\n const blocked = Array.from(this.widgets.keys()).map((id) => this.findGuide(id)).some((g) => g && areMutuallyExclusive(g, guide));\n if (blocked && !manual) {\n if (!this.queued.some((q) => q.guide.id === guide.id)) this.queued.push({ guide, url, pageScoped: true });\n return false;\n }\n this.show(guide, manual);\n return true;\n }\n\n private drainQueue(url: string, ctx: TargetingContext): void {\n if (this.active) return;\n this.queued = this.queued.filter((q) => !(q.pageScoped && q.url !== url));\n while (this.queued.length) {\n const next = this.queued.shift() as QueuedGuide;\n if (!this.isEligible(next.guide, ctx, url)) continue;\n if (this.tryShow(next.guide, url, false)) return;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Showing guides\n // ---------------------------------------------------------------------------\n\n private findGuide(idOrKey: string): PublishedGuide | undefined {\n return this.config?.guides.find((g) => g.id === idOrKey || g.key === idOrKey);\n }\n\n private guideState(id: string): GuideLocalState {\n return this.state.guides[id] ?? (this.state.guides[id] = { impressions: 0 });\n }\n\n private recordImpression(guide: PublishedGuide, manual = false): void {\n const s = this.guideState(guide.id);\n s.impressions += 1;\n s.lastShownAt = nowIso();\n if (!this.session.shownGuides.includes(guide.id)) this.session.shownGuides.push(guide.id);\n this.recordLaunch(guide, manual);\n this.persistState();\n this.persistSession();\n const holdout = this.holdoutFor(guide);\n const experiment = holdout ? { id: holdout.experimentId, variantId: holdout.variantId } : guide.experiment;\n if (experiment) this.enqueue(\"experiment_viewed\", { properties: { guideExperimentId: experiment.id, variantId: experiment.variantId, ...(holdout ? {} : { guideId: guide.id }) } });\n // Control groups are local only: the server knows no guide by that id.\n if (!holdout) this.syncGuideState(guide.id, { impression: true });\n }\n\n private recordEnd(guide: PublishedGuide, reason: \"completed\" | \"dismissed\" | \"skipped\"): void {\n const s = this.guideState(guide.id);\n if (reason === \"completed\") s.completedAt = nowIso();\n else s.dismissedAt = nowIso();\n this.persistState();\n this.syncGuideState(guide.id, reason === \"completed\" ? { completed: true } : { dismissed: true });\n if (reason === \"completed\") this.completeChecklistTasksBy(\"guide_completed\", guide);\n }\n\n private syncGuideState(guideId: string, update: { impression?: boolean; completed?: boolean; dismissed?: boolean }): void {\n const body = { anonymousId: this.anonymousId, userId: this.user?.id || null, updates: [{ guideId, ...update }] };\n // Impressions are counters (a resend would count twice) and matter less; completions and\n // dismissals are kept until the server has them, so a guide doesn't come back on another device.\n if (update.impression) void postWithRetry(this.api, \"/guide-state\", body);\n else this.outbox.add(`guide:${guideId}:${update.completed ? \"completed\" : \"dismissed\"}:${this.anonymousId}`, \"/guide-state\", body);\n }\n\n private show(guide: PublishedGuide, manual: boolean, stepId?: string): void {\n try {\n if (guide.kind === \"checklist\" && guide.config.checklist) return this.showChecklist(guide);\n if (guide.kind === \"survey\" && guide.config.survey) return this.showSurvey(guide, manual);\n this.showFlow(guide, manual, stepId);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private showFlow(raw: PublishedGuide, manual: boolean, stepId?: string): void {\n if (this.editing()) return; // authoring mode renders previews only; capture renders nothing\n const guide = this.localize(raw);\n const exclusive = isExclusiveGuide(guide);\n const entry: ActiveGuide = { guide, manual, startUrl: this.pageHref() };\n const controller = runGuide(guide, {\n theme: this.theme(),\n // Code blocks only arrive when a workspace admin allowed them (the server strips them otherwise).\n runCode: true,\n ctx: () => this.getContext(),\n currentUrl: () => this.pageHref(),\n startAtStep: stepId,\n eventBus: this.eventBus,\n // Started from Help, Scout or startGuide(): steps on other pages offer to take the user there.\n promptForUrl: manual,\n // Also while a step waits for its page, so a link that loads that page resumes on it.\n onPosition: (id) => {\n if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: id, manual });\n },\n onError: (err) => this.reportError(err),\n onEvent: (e) => {\n const step = e.stepId ? guide.config.steps.find((s) => s.id === e.stepId) : undefined;\n this.enqueue(e.name, { guideId: guide.id, guideVersion: guide.version, stepId: e.stepId, stepIndex: e.stepIndex, properties: e.properties });\n if (e.name === \"guide_started\") {\n this.recordImpression(guide, manual);\n this.emitter.emit(\"guide:start\", guide);\n }\n if (e.name === \"step_viewed\" && step) {\n if (exclusive) writeJson(this.sessionStore, KEYS.active, { guideId: guide.id, stepId: step.id, manual });\n if (guide.kind === \"flow\" && guide.config.steps.length > 1) {\n this.guideState(guide.id).lastStepId = step.id;\n this.persistState();\n }\n this.emitter.emit(\"guide:step\", { guide, stepId: step.id, stepIndex: e.stepIndex ?? 0 });\n }\n if (e.name === \"guide_completed\") {\n this.recordEnd(guide, \"completed\");\n this.emitter.emit(\"guide:complete\", guide);\n }\n if (e.name === \"guide_dismissed\") {\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n if (e.name === \"guide_skipped\") {\n this.recordEnd(guide, \"skipped\");\n this.emitter.emit(\"guide:skip\", guide);\n }\n },\n onNavigate: (url, newTab) => this.navigate(url, newTab),\n onAction: (action, value) => {\n if (action === \"start_guide\" && value) this.setTimer(() => this.startGuide(value), 0);\n else if (action === \"event\" && value) this.track(value);\n else if (action === \"open_resource_center\") this.openResourceCenter();\n },\n onEnd: (reason) => {\n if (exclusive) {\n if (this.active?.controller === controller) this.active = null;\n this.sessionStore.remove(KEYS.active);\n } else this.widgets.delete(guide.id);\n if (reason !== \"destroyed\" && !this.destroyed) this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n },\n });\n entry.controller = controller;\n if (exclusive) this.active = entry;\n else this.widgets.set(guide.id, { destroy: () => controller.destroy(), controller, manual });\n controller.start();\n if (controller.getState().status === \"ended\") {\n if (exclusive && this.active === entry) this.active = null;\n this.widgets.delete(guide.id);\n }\n }\n\n private showChecklist(raw: PublishedGuide): void {\n if (this.editing()) return; // authoring mode renders previews only; capture renders nothing\n const guide = this.localize(raw);\n const config = guide.config.checklist;\n if (!config || this.widgets.has(guide.id)) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const progress = this.getChecklistProgress(guide.id);\n const first = !this.state.guides[guide.id]?.impressions;\n const widget = renderChecklist({\n scope: scope.el,\n config,\n progress,\n open: config.autoOpen && first && !progress.completedAt,\n onTaskClick: (task) => this.handleChecklistTaskClick(guide, task),\n onDismiss: () => this.dismissChecklist(guide),\n onOpen: () => this.enqueue(\"guide_viewed\", { guideId: guide.id, guideVersion: guide.version }),\n });\n this.widgets.set(guide.id, { destroy: () => { widget.destroy(); scope.destroy(); }, checklist: widget, scope });\n if (first) this.recordImpression(guide);\n }\n\n private showSurvey(raw: PublishedGuide, manual: boolean): void {\n if (this.editing()) return; // authoring mode renders previews only; capture renders nothing\n const guide = this.localize(raw);\n const config = guide.config.survey;\n if (!config) return;\n const scope = createScope(this.theme(), guide.config.appearance);\n const entry: ActiveGuide = { guide, manual, startUrl: this.pageHref(), scope };\n const finish = (reason: \"submitted\" | \"dismissed\") => {\n widget.destroy();\n scope.destroy();\n if (this.active === entry) this.active = null;\n if (reason === \"dismissed\") {\n this.enqueue(\"survey_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n this.recordEnd(guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", guide);\n }\n this.setTimer(() => this.evaluate(\"after_guide\", { endedGuide: guide }), 0);\n };\n const widget = renderSurvey({\n scope: scope.el,\n config,\n title: guide.name,\n onDismiss: () => finish(this.state.surveysSubmitted.includes(guide.id) ? \"submitted\" : \"dismissed\"),\n onSubmit: (answers) => {\n const responseId = randomId(24);\n this.state.surveysSubmitted.push(guide.id);\n this.persistState();\n this.recordEnd(guide, \"completed\");\n this.enqueue(\"survey_submitted\", { guideId: guide.id, guideVersion: guide.version, properties: { responseId } });\n this.outbox.add(`survey:${responseId}`, `/surveys/${encodeURIComponent(guide.id)}/responses`, { anonymousId: this.anonymousId, userId: this.user?.id || null, accountId: this.user?.account?.id || null, guideVersion: guide.version, answers, responseId });\n this.emitter.emit(\"survey:submit\", { guide, answers, responseId });\n this.emitter.emit(\"guide:complete\", guide);\n widget.showThankYou();\n },\n });\n entry.survey = widget;\n this.active = entry;\n this.recordImpression(guide, manual);\n this.enqueue(\"survey_displayed\", { guideId: guide.id, guideVersion: guide.version });\n this.emitter.emit(\"guide:start\", guide);\n }\n\n private theme() {\n return { ...(this.config?.theme || {}), ...(this.options.theme || {}) };\n }\n\n private navigate(url: string, newTab?: boolean): void {\n try {\n if (this.openPrototypeTest(url)) return;\n if (newTab) window.open(url, \"_blank\", \"noopener\");\n else location.assign(url);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n private renderPersistentWidgets(): void {\n if (!this.config || this.captureStarting || this.capture?.isActive()) return;\n const rc = this.config.resourceCenter;\n if (this.config.messenger?.enabled) {\n // One launcher: the messenger's Help tab replaces the resource center.\n if (this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n if (!this.messenger) void this.loadMessenger();\n return;\n }\n this.destroyMessenger();\n if (rc && rc.enabled && !this.resourceCenter) {\n const scope = createScope(this.theme());\n this.resourceCenterScope = scope;\n this.resourceCenter = renderResourceCenter({\n scope: scope.el,\n config: localizeResourceCenter(rc, this.locales(), this.defaultLocale()),\n evaluate: (rules) => evaluateRules(rules, this.getContext()),\n announcementsSeenAt: () => this.state.announcementsSeenAt ?? null,\n onAnnouncementsSeen: () => {\n this.state.announcementsSeenAt = nowIso();\n this.persistState();\n },\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n search: (q) => this.searchResourceCenter(q),\n audienceIds: () => this.state.audienceIds,\n loadArticle: (id) => this.loadArticle(id),\n onStartGuide: (id) => this.startGuide(id),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"resource_center_opened\");\n this.emitter.emit(\"resource-center:open\");\n },\n });\n } else if ((!rc || !rc.enabled) && this.resourceCenter) {\n this.resourceCenter.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n }\n }\n\n private resumeActiveGuide(): void {\n const saved = readJson<{ guideId: string; stepId: string; manual?: boolean } | null>(this.sessionStore, KEYS.active, null);\n if (!saved) return;\n this.sessionStore.remove(KEYS.active);\n const guide = this.findGuide(saved.guideId);\n if (!guide || !guide.config.steps.some((s) => s.id === saved.stepId)) return;\n this.showFlow(guide, saved.manual ?? false, saved.stepId);\n }\n\n /** Loads the messenger widget on demand (it is a separate chunk) and renders it. */\n private loadMessenger(): Promise<MessengerWidget | null> {\n if (this.messenger) return Promise.resolve(this.messenger);\n if (this.messengerLoading) return this.messengerLoading;\n this.messengerLoading = import(\"@guidelytech/guide-runtime/messenger\")\n .then(({ renderMessenger, parseLauncherSpot }) => {\n const cfg = this.config?.messenger;\n if (this.destroyed || !this.config || !cfg?.enabled || this.messenger) return this.messenger;\n const scope = createScope(this.theme());\n this.messengerScope = scope;\n this.messenger = renderMessenger({\n scope: scope.el,\n config: cfg,\n api: createMessengerTransport({\n api: this.api,\n store: this.store,\n projectId: this.options.projectId,\n anonymousId: () => this.anonymousId,\n userId: () => this.user?.id || null,\n pageUrl: () => (this.collectUrls() ? this.pageHref() : undefined),\n locale: () => this.rcLocale(),\n }),\n visitor: () => this.messengerVisitor(),\n launcherSpot: parseLauncherSpot(this.store.get(KEYS.launcher(this.options.projectId))),\n onLauncherMove: (spot) => writeJson(this.store, KEYS.launcher(this.options.projectId), spot),\n brand: { logoUrl: this.theme().logoUrl ?? null, name: this.theme().brandName ?? null },\n onResumeGuide: (guideId, stepId) => this.startGuide(guideId, { stepId }),\n onNewsSeen: (ids) => {\n const seen = readJson<string[]>(this.store, KEYS.newsSeen(this.options.projectId), []);\n writeJson(this.store, KEYS.newsSeen(this.options.projectId), Array.from(new Set([...ids, ...(Array.isArray(seen) ? seen : [])])).slice(0, 200));\n },\n resourceCenter: this.config.resourceCenter ? localizeResourceCenter(this.config.resourceCenter, this.locales(), this.defaultLocale()) : null,\n evaluate: (rules) => evaluateRules(rules, this.getContext()),\n audienceIds: () => this.state.audienceIds,\n guides: this.config.guides.map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind })),\n onStartGuide: (idOrKey) => this.startGuide(idOrKey),\n onOpenChecklist: (id) => this.openChecklist(id),\n onArticleView: (a) => this.enqueue(\"article_viewed\", { properties: { articleId: a.id, slug: a.slug } }),\n onOpen: () => {\n this.enqueue(\"messenger_opened\");\n this.emitter.emit(\"messenger:open\");\n },\n onMessage: (message, conversation) => this.emitter.emit(\"conversation:message\", { message, conversation }),\n });\n return this.messenger;\n })\n .catch((err) => {\n this.reportError(err);\n return null;\n })\n .finally(() => {\n this.messengerLoading = null;\n });\n return this.messengerLoading;\n }\n\n /** What the messenger personalises from, computed fresh on every render. */\n private messengerVisitor() {\n const ctx = this.getContext();\n const url = this.pageHref();\n const seen = readJson<string[]>(this.store, KEYS.newsSeen(this.options.projectId), []);\n const visitor = buildMessengerVisitor({\n guides: this.config?.guides ?? [],\n state: this.state,\n traits: this.user?.traits,\n url,\n isTargeted: (g) => this.isTargeted(g, ctx, url),\n isAudienceTargeted: (g) => {\n if (!isWithinSchedule(g)) return false;\n ctx.rolloutSalt = g.id;\n return evaluateRules(g.config.targeting, ctx);\n },\n newsSeen: Array.isArray(seen) ? seen : [],\n });\n // The resource center's \"What's new\" joins the messenger's News (the messenger replaces the resource center).\n const rc = this.config?.resourceCenter;\n const rcNews = rc?.announcements?.length\n ? visibleAnnouncements(localizeResourceCenter(rc, this.locales(), this.defaultLocale()).announcements, this.state.audienceIds).map((a) => ({\n id: `rc_${a.id}`,\n key: a.guideId ?? \"\",\n title: a.title,\n body: plainText(a.body),\n imageUrl: null,\n publishedAt: a.publishedAt,\n unread: !(Array.isArray(seen) && seen.includes(`rc_${a.id}`)),\n articleId: a.articleId ?? null,\n url: a.url ?? null,\n }))\n : [];\n const news = rcNews.length ? [...visitor.news, ...rcNews].sort((a, b) => b.publishedAt.localeCompare(a.publishedAt)).slice(0, 10) : visitor.news;\n return { ...visitor, news, identified: !!this.user?.id };\n }\n\n private destroyMessenger(): void {\n this.messenger?.destroy();\n this.messengerScope?.destroy();\n this.messenger = null;\n this.messengerScope = null;\n }\n\n /** The resource center's language for this visitor, or null for the default language. */\n private rcLocale(): string | null {\n const rc = this.config?.resourceCenter;\n if (!rc) return null;\n const locale = localizeResourceCenter(rc, this.locales(), this.defaultLocale()).locale;\n return locale.toLowerCase() === this.defaultLocale().toLowerCase() ? null : locale;\n }\n\n private async loadArticle(id: string): Promise<ResourceCenterArticle | null> {\n try {\n const locale = this.rcLocale();\n const res = await this.api.get<{ article: ResourceCenterArticle }>(`/articles/${encodeURIComponent(id)}`, locale ? { params: { locale } } : undefined);\n return res.ok && res.data ? res.data.article : null;\n } catch {\n return null;\n }\n }\n\n private async searchResourceCenter(q: string): Promise<ResourceCenterArticle[]> {\n try {\n const res = await this.api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n } catch {\n return [];\n }\n }\n\n // ---------------------------------------------------------------------------\n // Checklists\n // ---------------------------------------------------------------------------\n\n /** Current progress for a checklist guide (by id or key). */\n getChecklistProgress(idOrKey: string): ChecklistProgressState {\n const guide = this.findGuide(idOrKey);\n const id = guide?.id ?? idOrKey;\n const p = this.state.checklists[id];\n return p ? { completedTaskIds: [...p.completedTaskIds], completedAt: p.completedAt ?? null, dismissedAt: p.dismissedAt ?? null } : { completedTaskIds: [], completedAt: null, dismissedAt: null };\n }\n\n /** Marks a checklist task complete (manual completion) and syncs progress. */\n completeChecklistTask(idOrKey: string, taskId: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n const task = guide.config.checklist.tasks.find((t) => t.id === taskId);\n if (task) this.markTaskDone(guide, task);\n }\n\n private markTaskDone(guide: PublishedGuide, task: ChecklistTask): void {\n const config = guide.config.checklist;\n if (!config) return;\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n if (progress.completedTaskIds.includes(task.id)) return;\n progress.completedTaskIds.push(task.id);\n this.enqueue(\"checklist_task_completed\", { guideId: guide.id, guideVersion: guide.version, properties: { taskId: task.id } });\n const complete = isChecklistComplete(config, progress) && !progress.completedAt;\n if (complete) {\n progress.completedAt = nowIso();\n this.enqueue(\"checklist_completed\", { guideId: guide.id, guideVersion: guide.version });\n }\n this.persistState();\n this.widgets.get(guide.id)?.checklist?.setProgress(this.getChecklistProgress(guide.id));\n this.outbox.add(`checklist:${guide.id}:progress:${this.anonymousId}`, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, completed: !!progress.completedAt });\n this.emitter.emit(\"checklist:task\", { guide, task, progress: this.getChecklistProgress(guide.id) });\n if (complete) {\n this.emitter.emit(\"checklist:complete\", guide);\n this.widgets.get(guide.id)?.checklist?.open();\n }\n }\n\n private completeChecklistTasksBy(kind: ChecklistTask[\"completion\"], value: string | Element | PublishedGuide): void {\n if (!this.config) return;\n for (const guide of this.config.guides) {\n const tasks = guide.config.checklist?.tasks;\n if (!tasks) continue;\n for (const task of tasks) {\n if (task.completion !== kind || !task.completionValue) continue;\n let hit = false;\n if (kind === \"event\") hit = value === task.completionValue;\n else if (kind === \"url_visited\") hit = urlMatches(task.completionValue, value as string);\n else if (kind === \"guide_completed\") hit = (value as PublishedGuide).id === task.completionValue || (value as PublishedGuide).key === task.completionValue;\n else if (kind === \"click\") {\n try {\n hit = !!closestComposed(value as Element, task.completionValue);\n } catch {\n hit = false;\n }\n }\n if (hit) this.markTaskDone(guide, task);\n }\n }\n }\n\n private handleChecklistTaskClick(guide: PublishedGuide, task: ChecklistTask): void {\n if (task.completion === \"manual\") this.markTaskDone(guide, task);\n if (task.action === \"start_guide\" && task.actionValue) this.startGuide(task.actionValue);\n else if (task.action === \"url\" && task.actionValue) this.navigate(task.actionValue);\n else if (task.action === \"event\" && task.actionValue) this.track(task.actionValue);\n }\n\n private dismissChecklist(guide: PublishedGuide): void {\n const progress = this.state.checklists[guide.id] ?? (this.state.checklists[guide.id] = { completedTaskIds: [] });\n progress.dismissedAt = nowIso();\n this.persistState();\n this.enqueue(\"checklist_dismissed\", { guideId: guide.id, guideVersion: guide.version });\n this.outbox.add(`checklist:${guide.id}:dismissed:${this.anonymousId}`, `/checklists/${encodeURIComponent(guide.id)}/progress`, { anonymousId: this.anonymousId, userId: this.user?.id || null, guideVersion: guide.version, completedTaskIds: progress.completedTaskIds, dismissed: true });\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n }\n\n /** Opens (rendering if needed) the checklist panel. */\n openChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (!guide?.config.checklist) return;\n if (!this.widgets.has(guide.id)) {\n const p = this.state.checklists[guide.id];\n if (p?.dismissedAt) {\n delete p.dismissedAt;\n this.persistState();\n }\n this.showChecklist(guide);\n }\n this.widgets.get(guide.id)?.checklist?.open();\n }\n\n closeChecklist(idOrKey: string): void {\n const guide = this.findGuide(idOrKey);\n if (guide) this.widgets.get(guide.id)?.checklist?.close();\n }\n\n // ---------------------------------------------------------------------------\n // Public guide controls\n // ---------------------------------------------------------------------------\n\n /** Starts a guide by id or key, bypassing targeting and frequency rules. */\n startGuide(idOrKey: string, options: { stepId?: string } = {}): boolean {\n const guide = this.findGuide(idOrKey);\n if (!guide) {\n this.reportError(new Error(`[Guidely] startGuide: unknown guide \"${idOrKey}\"`));\n return false;\n }\n if (guide.kind === \"checklist\") {\n this.openChecklist(guide.id);\n return true;\n }\n if (this.active) this.stopGuide();\n this.widgets.get(guide.id)?.destroy();\n this.widgets.delete(guide.id);\n this.show(guide, true, options.stepId);\n return true;\n }\n\n /** Stops the active guide silently (no dismiss event). */\n stopGuide(): void {\n const a = this.active;\n if (!a) return;\n this.active = null;\n a.controller?.destroy();\n a.survey?.destroy();\n a.scope?.destroy();\n this.sessionStore.remove(KEYS.active);\n }\n\n /** Dismisses the active guide (records a dismissal). */\n dismissGuide(): void {\n const a = this.active;\n if (!a) return;\n if (a.controller) a.controller.dismiss();\n else {\n this.stopGuide();\n this.recordEnd(a.guide, \"dismissed\");\n this.emitter.emit(\"guide:dismiss\", a.guide);\n }\n }\n\n getActiveGuide(): PublishedGuide | null {\n return this.active?.guide ?? null;\n }\n\n /** Published guides for this environment (read-only). */\n getGuides(): ReadonlyArray<PublishedGuide> {\n return this.config?.guides ?? [];\n }\n\n isGuideCompleted(idOrKey: string): boolean {\n const guide = this.findGuide(idOrKey);\n return !!this.state.guides[guide?.id ?? idOrKey]?.completedAt;\n }\n\n openResourceCenter(): void {\n if (this.config?.messenger?.enabled) return this.openMessenger(\"help\");\n if (!this.resourceCenter) this.renderPersistentWidgets();\n this.resourceCenter?.open();\n }\n\n closeResourceCenter(): void {\n if (this.messenger) return this.closeMessenger();\n this.resourceCenter?.close();\n }\n\n /** Opens the Scout messenger (when enabled for the project), optionally on a tab. */\n openMessenger(tab?: MessengerTab): void {\n if (!this.config?.messenger?.enabled) return;\n void this.loadMessenger().then((m) => m?.open(tab));\n }\n\n closeMessenger(): void {\n this.messenger?.close();\n }\n\n /**\n * Opens a Guidely prototype test (its `/validate/<token>` URL on this SDK's API origin, or the bare\n * token) in a full-screen overlay, attributed to the current user. Returns false, doing nothing, for\n * any other URL. Guide buttons that open a test URL use this automatically.\n */\n openPrototypeTest(urlOrToken: string): boolean {\n if (typeof document === \"undefined\") return false;\n const url = matchPrototypeTestUrl(urlOrToken, this.options.apiUrl);\n if (!url) return false;\n openPrototypeOverlay(url, { key: this.options.projectId, anonymousId: this.anonymousId, userId: this.user?.id ?? null });\n return true;\n }\n\n /**\n * Opens the complaint form in the messenger, optionally with a category picked (its id from\n * Complaints → Categories). Does nothing when the project doesn't take complaints.\n */\n openComplaint(categoryId?: string): void {\n if (!this.config?.messenger?.enabled || !this.config.messenger.complaints?.categories.length) return;\n void this.loadMessenger().then((m) => m?.openComplaint(categoryId));\n }\n\n /**\n * Opens the Ideas tab in the messenger (feature requests and voting), or one idea by its id.\n * Does nothing when the project hasn't turned on Ideas.\n */\n openIdeas(requestId?: string): void {\n if (!this.config?.messenger?.enabled || !this.config.messenger.ideas) return;\n void this.loadMessenger().then((m) => m?.openIdeas(requestId));\n }\n\n /** Opens a new messenger conversation, optionally pre-filling the message. */\n showNewMessage(text?: string): void {\n if (!this.config?.messenger?.enabled) return;\n void this.loadMessenger().then((m) => m?.showNewMessage(text));\n }\n\n // ---------------------------------------------------------------------------\n // Feature flags\n // ---------------------------------------------------------------------------\n\n /** Boolean flag value for the current user; `fallback` (default `false`) until loaded or when missing. */\n isFeatureEnabled(key: string, fallback = false): boolean {\n return this.flags.isEnabled(key, fallback);\n }\n\n /** Flag value for the current user; `fallback` when missing or of a different type. */\n getFeatureValue<T extends JsonValue>(key: string, fallback: T): FlagValue<T> {\n return this.flags.getValue(key, fallback);\n }\n\n /** Flag value plus why it was served (reason, rule, variation, experiment). */\n getFeatureDetails<T extends JsonValue>(key: string, fallback: T): FlagDetails<FlagValue<T>> {\n return this.flags.getDetails(key, fallback);\n }\n\n /** Calls `cb` whenever flag values may have changed (new rules, identity, page, overrides). Returns an unsubscribe function. */\n onFlagsChange(cb: () => void): () => void {\n return this.flags.subscribe(cb);\n }\n\n /** Attributes flags are evaluated with: identity, traits, account, audiences, page and device. */\n private flagContext(): Attributes {\n const device = detectDevice(navigator.userAgent, window.innerWidth);\n const account = this.user?.account;\n return {\n url: this.pageHref(),\n path: pathOf(this.pageHref()),\n deviceType: device.type,\n browser: device.browser,\n os: device.os,\n locale: navigator.language || undefined,\n environment: this.options.environment,\n platform: \"web\",\n ...(this.options.appVersion ? { appVersion: this.options.appVersion } : {}),\n ...(this.user?.traits ?? {}),\n id: this.user?.id || this.anonymousId,\n anonymousId: this.anonymousId,\n account: account ? { ...(account.traits ?? {}), id: account.id } : undefined,\n $audiences: [...this.state.audienceIds],\n };\n }\n\n private syncFlagAttributes(): void {\n if (!this.destroyed) this.flags?.setContextAttributes(this.flagContext());\n }\n\n /** `experiment_viewed`, once per session and assignment, through the event queue (consent applies). */\n private trackExposure(result: EvaluationResult): void {\n const exp = result.inExperiment ? result.experiment : undefined;\n if (!exp || this.destroyed) return;\n const key = `${this.session.id}|${exp.key}|${exp.hashValue}|${exp.variationId}`;\n if (this.exposures.has(key)) return;\n if (this.exposures.size > 500) this.exposures.clear();\n this.exposures.add(key);\n this.enqueue(\"experiment_viewed\", { properties: { experimentKey: exp.key, variationId: exp.variationId, flagKey: result.key, hashAttribute: exp.hashAttribute, ...(exp.variationName ? { variationName: exp.variationName } : {}) } });\n }\n\n on<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): () => void {\n return this.emitter.on(event, cb);\n }\n\n off<K extends keyof GuidelyEvents>(event: K, cb: GuidelyEvents[K]): void {\n this.emitter.off(event, cb);\n }\n\n /** Snapshot for debugging / devtools. */\n getState() {\n return {\n ready: this.isReady,\n destroyed: this.destroyed,\n anonymousId: this.anonymousId,\n user: this.user,\n consent: this.consent,\n configVersion: this.config?.configVersion ?? null,\n guides: this.getGuides().map((g) => ({ id: g.id, key: g.key, kind: g.kind })),\n activeGuide: this.active ? { id: this.active.guide.id, key: this.active.guide.key, ...(this.active.controller?.getState() ?? {}) } : null,\n queued: this.queued.map((q) => q.guide.key),\n widgets: Array.from(this.widgets.keys()),\n guideState: this.state.guides,\n checklists: this.state.checklists,\n audienceIds: this.state.audienceIds,\n session: this.session,\n pendingEvents: this.queue.size,\n authoring: !!this.authoring?.isActive(),\n capture: !!this.capture?.isActive(),\n flagsReady: this.flags.isReady(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Authoring\n // ---------------------------------------------------------------------------\n\n private maybeStartAuthoring(): void {\n try {\n const bridge = new AuthoringBridge({\n api: this.api,\n sessionStore: this.sessionStore,\n theme: () => this.theme(),\n ctx: () => this.getContext(),\n maskSelectors: [...(this.options.maskSelectors || []), ...(this.config?.settings?.maskSelectors || [])],\n onError: (err) => this.reportError(err),\n onActive: (active) => this.setEditing(\"authoring\", active),\n });\n if (bridge.detect()) this.authoring = bridge;\n } catch (err) {\n this.reportError(err);\n }\n }\n\n /** Authoring or capture started / ended: pause everything a visitor would see or be recorded by. */\n private setEditing(kind: \"authoring\" | \"capture\", active: boolean): void {\n this.emitter.emit(kind, { active });\n if (active) {\n this.replay?.stop({ discard: true });\n this.stopGuide();\n this.widgets.forEach((w) => w.destroy());\n this.widgets.clear();\n if (kind === \"capture\") this.hidePersistentWidgets();\n } else {\n this.syncCapture();\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n }\n }\n\n private hidePersistentWidgets(): void {\n this.resourceCenter?.destroy();\n this.resourceCenterScope?.destroy();\n this.resourceCenter = null;\n this.resourceCenterScope = null;\n this.destroyMessenger();\n }\n\n // ---------------------------------------------------------------------------\n // How-to capture\n // ---------------------------------------------------------------------------\n\n /**\n * Starts how-to capture when the URL carries `guidely_capture` (or this tab is mid-recording).\n * The bridge, toolbar and screenshot code are a separate chunk loaded only then.\n */\n private maybeStartCapture(): boolean {\n let marker: ReturnType<typeof takeCaptureToken> = null;\n try {\n marker = takeCaptureToken(this.sessionStore);\n } catch (err) {\n this.reportError(err);\n }\n if (!marker) return false;\n const found = marker;\n this.captureStarting = true;\n this.replay?.stop({ discard: true });\n loadCapture()\n .then(async (capture) => {\n if (this.destroyed) return;\n const bridge = capture.createBridge({\n api: this.api,\n sessionStore: this.sessionStore,\n marker: found,\n maskSelector: this.maskSelector(),\n onError: (err) => this.reportError(err),\n onActive: (active) => {\n this.captureStarting = false;\n this.setEditing(\"capture\", active);\n },\n });\n this.capture = bridge;\n await bridge.start();\n })\n .catch((err) => this.reportError(err))\n .finally(() => {\n if (!this.captureStarting) return;\n // The session was rejected (or failed to load): carry on as a normal page.\n this.captureStarting = false;\n if (this.destroyed) return;\n this.syncCapture();\n this.renderPersistentWidgets();\n this.evaluate(\"ready\");\n });\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------------------\n\n private persistState(): void {\n writeJson(this.store, KEYS.state(this.options.projectId), this.state);\n }\n\n private persistSession(): void {\n writeJson(this.sessionStore, KEYS.session, this.session);\n }\n\n private reportError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n this.log(\"error\", error.message);\n try {\n this.options.onError?.(error);\n } catch {\n /* ignore */\n }\n this.emitter.emit(\"error\", error);\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug && typeof console !== \"undefined\") console.debug(\"[Guidely]\", ...args);\n }\n\n // ---------------------------------------------------------------------------\n // Static helpers (used by the embed)\n // ---------------------------------------------------------------------------\n\n /** Creates (or returns the existing) client and starts initialisation. */\n static init(options: GuidelyOptions): GuidelyClient {\n if (current && !current.destroyed && current.options.projectId === options.projectId) return current;\n current?.destroy();\n current = new GuidelyClient(options);\n void current.init();\n return current;\n }\n\n /** The most recently created client, if any. */\n static get(): GuidelyClient | null {\n return current && !current.destroyed ? current : null;\n }\n}\n\nlet current: GuidelyClient | null = null;\n\n/** Mobile-only guides never run in the browser (older servers ignore `?platform=web`). */\nfunction webOnly(config: SdkConfigResponse): SdkConfigResponse {\n return config.guides.every((g) => supportsPlatform(g.config, \"web\")) ? config : { ...config, guides: config.guides.filter((g) => supportsPlatform(g.config, \"web\")) };\n}\n\nfunction pathOf(url: string): string {\n try {\n return new URL(url, \"http://localhost\").pathname;\n } catch {\n return url.replace(/[?#].*$/, \"\");\n }\n}\n\n/** `document.referrer` as origin + path, only when it is another site. */\nfunction externalReferrer(): string | undefined {\n try {\n if (!document.referrer) return undefined;\n const u = new URL(document.referrer);\n return u.origin === location.origin ? undefined : u.origin + u.pathname;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Creates a Guidely client and starts loading configuration. Throws a friendly error when called\n * during server-side rendering; framework adapters guard this for you.\n */\nexport function createGuidely(options: GuidelyOptions): GuidelyClient {\n const client = new GuidelyClient(options);\n current = client;\n void client.init();\n return client;\n}\n","import { AGENT_TOOL_CALLS_PER_TURN, AGENT_TURN_MAX_TEXT, AGENT_TURNS_PER_BATCH, randomId, type AgentToolCallInput, type AgentTurnInput } from \"@guidelytech/shared/runtime\";\nimport type { ServerHealth } from \"./health\";\nimport type { Api } from \"./http\";\nimport { Outbox } from \"./outbox\";\nimport type { KeyValueStore } from \"./storage\";\n\n/**\n * Agent Analytics in the browser: turns of conversations with the app's own AI agent, sent to\n * `POST /api/v1/sdk/agent-events`. Turns are filled in with the visitor's ids and session, passed through\n * the app's `agents.redact` callback, and kept in a persisted outbox until the server accepts them\n * (retried with backoff while it is unreachable; the server ignores turns it already has).\n */\n\n/** Last say over each turn before it leaves the browser: return a changed copy, or null to drop it. */\nexport type AgentTurnRedactor = (turn: AgentTurnInput) => AgentTurnInput | null | undefined;\n\nexport interface AgentTurnIdentity {\n anonymousId: string;\n userId: string | null;\n accountId: string | null;\n sessionId: string;\n}\n\nconst PENDING_MAX = 500;\n\nfunction toolCalls(calls: unknown): AgentToolCallInput[] | undefined {\n if (!Array.isArray(calls)) return undefined;\n // Only name, status and latency leave the browser: arguments and results are never sent.\n return calls\n .filter((c): c is AgentToolCallInput => !!c && typeof (c as AgentToolCallInput).name === \"string\" && !!(c as AgentToolCallInput).name)\n .slice(0, AGENT_TOOL_CALLS_PER_TURN)\n .map((c) => ({\n name: c.name.slice(0, 100),\n ...(c.status === \"ok\" || c.status === \"error\" ? { status: c.status } : {}),\n ...(typeof c.latencyMs === \"number\" && Number.isFinite(c.latencyMs) && c.latencyMs >= 0 ? { latencyMs: Math.round(c.latencyMs) } : {}),\n }));\n}\n\n/**\n * A turn ready to send: identity and session filled in where the app left them out, a turn id and time\n * when missing, the redactor applied, then text and tool calls trimmed to what the server accepts.\n * Returns null for a turn that is missing its ids or that the redactor dropped.\n */\nexport function prepareAgentTurn(turn: AgentTurnInput, identity: AgentTurnIdentity, redact?: AgentTurnRedactor, onError?: (err: unknown) => void): AgentTurnInput | null {\n if (!turn || typeof turn !== \"object\" || !turn.conversationId || !turn.agentId || !turn.role) return null;\n let out: AgentTurnInput = {\n ...turn,\n type: \"agent.conversation\",\n turnId: turn.turnId || `t_${randomId(20)}`,\n occurredAt: turn.occurredAt || new Date().toISOString(),\n anonymousId: turn.anonymousId ?? identity.anonymousId,\n userId: turn.userId !== undefined ? turn.userId : identity.userId,\n accountId: turn.accountId !== undefined ? turn.accountId : identity.accountId,\n sessionId: turn.sessionId ?? identity.sessionId,\n };\n if (redact) {\n try {\n const r = redact({ ...out, toolCalls: out.toolCalls ? out.toolCalls.map((c) => ({ ...c })) : undefined, metadata: out.metadata ? { ...out.metadata } : undefined });\n if (!r) return null;\n // The redactor may change content, not which conversation or turn this is.\n out = { ...r, type: \"agent.conversation\", conversationId: out.conversationId, agentId: out.agentId, turnId: out.turnId, role: out.role };\n } catch (err) {\n onError?.(err);\n return null; // when in doubt, send nothing\n }\n }\n if (typeof out.text === \"string\" && out.text.length > AGENT_TURN_MAX_TEXT) out.text = out.text.slice(0, AGENT_TURN_MAX_TEXT);\n if (out.text !== undefined && typeof out.text !== \"string\") out.text = String(out.text);\n const calls = toolCalls(out.toolCalls);\n if (calls) out.toolCalls = calls;\n else delete out.toolCalls;\n return out;\n}\n\nexport interface AgentTurnsOptions {\n api: Api;\n store: KeyValueStore;\n storageKey: string;\n health?: ServerHealth;\n sdk: { name: string; version: string };\n}\n\n/** Sends prepared turns in batches through their own outbox; holds them in memory while consent is pending. */\nexport class AgentTurns {\n private readonly outbox: Outbox;\n private pending: AgentTurnInput[] = [];\n\n constructor(private readonly opts: AgentTurnsOptions) {\n // Own outbox, kept small: turns can be long, and they must not crowd out survey answers.\n this.outbox = new Outbox({ api: opts.api, store: opts.store, storageKey: opts.storageKey, health: opts.health, maxItems: 20, maxAgeMs: 24 * 60 * 60 * 1000 });\n }\n\n get queued(): number {\n return this.outbox.size + this.pending.length;\n }\n\n /** Queues turns to send now, or (`hold`) until consent is granted. */\n add(turns: AgentTurnInput[], hold = false): void {\n if (!turns.length) return;\n if (hold) {\n this.pending.push(...turns);\n if (this.pending.length > PENDING_MAX) this.pending.splice(0, this.pending.length - PENDING_MAX);\n return;\n }\n for (let i = 0; i < turns.length; i += AGENT_TURNS_PER_BATCH) {\n const batch = turns.slice(i, i + AGENT_TURNS_PER_BATCH);\n this.outbox.add(`agent:${batch[0]!.turnId}`, \"/agent-events\", { turns: batch, sdk: this.opts.sdk });\n }\n }\n\n /** Consent changed: granted sends what was held, anything else drops it. */\n consentChanged(granted: boolean): void {\n const held = this.pending.splice(0);\n if (granted) this.add(held);\n }\n\n destroy(): void {\n this.pending = [];\n this.outbox.destroy();\n }\n}\n","/**\n * Whether the Guidely API is reachable right now: a circuit breaker shared by everything the SDK\n * sends in the background (event batches, replay uploads, config refreshes, queued survey answers).\n *\n * Every API answer is reported here. After `threshold` failures in a row (network errors, timeouts,\n * 429, 5xx) the circuit opens for a cooldown that doubles with each further failure (5 s up to\n * 5 min, ±20% jitter so tabs don't retry in step); a `Retry-After` answer sets the cooldown\n * directly. While it is open, background senders wait `waitMs()` instead of sending. Requests the\n * person makes (a messenger message) still go out, and any answer closes the circuit again. The\n * browser's `online` event ends the cooldown early.\n */\nexport interface ServerHealthOptions {\n threshold?: number;\n baseMs?: number;\n maxMs?: number;\n now?: () => number;\n random?: () => number;\n}\n\n/** Longest `Retry-After` honoured, so a bad header can't silence the SDK for days. */\nconst MAX_RETRY_AFTER_MS = 60 * 60 * 1000;\n/** How long background senders wait while the browser reports being offline (the `online` event usually comes first). */\nconst OFFLINE_WAIT_MS = 30_000;\n\nexport class ServerHealth {\n private failures = 0;\n private openUntil = 0;\n private lastOkAt = 0;\n private readonly listeners = new Set<() => void>();\n private readonly threshold: number;\n private readonly baseMs: number;\n private readonly maxMs: number;\n private readonly now: () => number;\n private readonly random: () => number;\n\n constructor(opts: ServerHealthOptions = {}) {\n this.threshold = opts.threshold ?? 3;\n this.baseMs = opts.baseMs ?? 5000;\n this.maxMs = opts.maxMs ?? 5 * 60 * 1000;\n this.now = opts.now ?? Date.now;\n this.random = opts.random ?? Math.random;\n }\n\n /** The server answered (2xx, 3xx, or a 4xx other than 429): it is up. */\n success(): void {\n const wasDown = this.failures > 0 || this.openUntil > 0;\n this.failures = 0;\n this.openUntil = 0;\n this.lastOkAt = this.now();\n if (wasDown) this.notify();\n }\n\n /** The request failed or the server is overloaded. `retryAfterMs` comes from a `Retry-After` header. */\n failure(retryAfterMs?: number | null): void {\n this.failures += 1;\n const now = this.now();\n if (retryAfterMs != null && retryAfterMs > 0) {\n this.openUntil = Math.max(this.openUntil, now + Math.min(retryAfterMs, MAX_RETRY_AFTER_MS));\n return;\n }\n if (this.failures < this.threshold) return;\n const cooldown = Math.min(this.maxMs, this.baseMs * 2 ** (this.failures - this.threshold));\n this.openUntil = Math.max(this.openUntil, now + cooldown * (0.8 + this.random() * 0.4));\n }\n\n /** Milliseconds background traffic should wait before trying again (0: send now). */\n waitMs(): number {\n if (typeof navigator !== \"undefined\" && navigator.onLine === false) return OFFLINE_WAIT_MS;\n return Math.max(0, this.openUntil - this.now());\n }\n\n canSend(): boolean {\n return this.waitMs() === 0;\n }\n\n /**\n * The last request got an answer. Unload beacons can't report back, so what they carry is only\n * forgotten while this holds; otherwise it stays queued and is sent again (the server drops duplicates).\n */\n get reachable(): boolean {\n return this.failures === 0 && this.lastOkAt > 0;\n }\n\n /** The browser came back online: end the cooldown and let queued traffic try straight away. */\n online(): void {\n this.openUntil = 0;\n this.notify();\n }\n\n /** Called when the server answers again after failures, or the browser comes back online. */\n onRecover(cb: () => void): () => void {\n this.listeners.add(cb);\n return () => this.listeners.delete(cb);\n }\n\n private notify(): void {\n for (const cb of Array.from(this.listeners)) {\n try {\n cb();\n } catch {\n /* a listener must not break the others */\n }\n }\n }\n}\n\n/** `Retry-After` as milliseconds: delta-seconds or an HTTP date. Null when absent or unparseable. */\nexport function parseRetryAfter(value: string | null | undefined, now = Date.now()): number | null {\n if (!value) return null;\n const trimmed = value.trim();\n if (/^\\d+$/.test(trimmed)) return Number(trimmed) * 1000;\n const at = Date.parse(trimmed);\n return Number.isNaN(at) ? null : Math.max(0, at - now);\n}\n\n/** Answers that mean the server is down or shedding load (retry later) rather than refusing the request. */\nexport function isServerFailure(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import { isServerFailure, parseRetryAfter, ServerHealth } from \"./health\";\n\nexport interface ApiResponse<T> {\n status: number;\n ok: boolean;\n data: T | null;\n etag: string | null;\n}\n\nexport type FetchLike = typeof fetch;\n\n/** Reply streams: the response must start within this long, and then never go quiet longer than the idle limit (the server sends a keepalive every 15 s). */\nexport const STREAM_RESPONSE_TIMEOUT_MS = 30_000;\nexport const STREAM_IDLE_TIMEOUT_MS = 60_000;\n\n/** Thin HTTP client for the public SDK API. Adds the public key as query + header. */\nexport class Api {\n /** Reachability of the API, fed by every answer (see {@link ServerHealth}). */\n readonly health: ServerHealth;\n\n constructor(\n private readonly baseUrl: string,\n private readonly key: string,\n private readonly fetchImpl?: FetchLike,\n health?: ServerHealth,\n ) {\n this.health = health ?? new ServerHealth();\n }\n\n /** Feeds an answer (or a failed request, `null`) into {@link health}. */\n private observe(res: Response | null): void {\n if (!res) this.health.failure();\n else if (isServerFailure(res.status)) this.health.failure(parseRetryAfter(res.headers?.get?.(\"retry-after\")));\n else this.health.success();\n }\n\n url(path: string, params: Record<string, string | undefined> = {}): string {\n // Built by hand rather than with URL/searchParams, which React Native does not implement.\n const query = Object.entries({ key: this.key, ...params })\n .filter((e): e is [string, string] => e[1] != null)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n return `${this.baseUrl.replace(/\\/$/, \"\")}/api/v1/sdk${path}?${query}`;\n }\n\n private get fetcher(): FetchLike | null {\n if (this.fetchImpl) return this.fetchImpl;\n return typeof fetch === \"function\" ? fetch.bind(globalThis) : null;\n }\n\n async request<T>(method: \"GET\" | \"POST\", path: string, options: { body?: unknown; etag?: string | null; params?: Record<string, string | undefined>; keepalive?: boolean; timeoutMs?: number; headers?: Record<string, string> } = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const headers: Record<string, string> = { ...options.headers, \"X-Guidely-Key\": this.key, Accept: \"application/json\" };\n // Multipart bodies set their own Content-Type (with the boundary).\n const form = typeof FormData !== \"undefined\" && options.body instanceof FormData;\n if (options.body !== undefined && !form) headers[\"Content-Type\"] = \"application/json\";\n if (options.etag) headers[\"If-None-Match\"] = options.etag;\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n const timer = ac ? setTimeout(() => ac.abort(), options.timeoutMs ?? 10000) : null;\n try {\n let res: Response;\n try {\n res = await f(this.url(path, options.params), {\n method,\n headers,\n body: options.body === undefined ? undefined : form ? (options.body as FormData) : JSON.stringify(options.body),\n keepalive: options.keepalive,\n signal: ac?.signal,\n credentials: \"omit\",\n mode: \"cors\",\n });\n } catch (err) {\n this.observe(null);\n throw err;\n }\n this.observe(res);\n let data: T | null = null;\n if (res.status !== 304 && res.status !== 204) {\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n }\n return { status: res.status, ok: res.ok, data, etag: res.headers?.get?.(\"etag\") ?? null };\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n get<T>(path: string, options?: { etag?: string | null; params?: Record<string, string | undefined>; headers?: Record<string, string> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"GET\", path, options);\n }\n\n post<T>(path: string, body: unknown, options?: { params?: Record<string, string | undefined>; keepalive?: boolean; headers?: Record<string, string> }): Promise<ApiResponse<T>> {\n return this.request<T>(\"POST\", path, { body, ...options });\n }\n\n /** Multipart POST (file uploads). No Content-Type header: the browser adds it with the boundary. */\n postForm<T>(path: string, form: FormData, options?: { params?: Record<string, string | undefined>; timeoutMs?: number }): Promise<ApiResponse<T>> {\n return this.request<T>(\"POST\", path, { body: form, ...options });\n }\n\n /**\n * POST that may answer with server-sent events. Each event is passed to `onEvent`; a JSON answer is\n * returned instead. Scout replies can take a while, so there is no overall timeout: the response\n * must start within 30 s and then never go quiet for more than 60 s (the server sends keepalives),\n * otherwise the request is aborted and rejects.\n */\n async stream<T>(path: string, body: unknown, onEvent: (event: string, data: unknown) => void, headers: Record<string, string> = {}): Promise<ApiResponse<T>> {\n const f = this.fetcher;\n if (!f) throw new Error(\"fetch is not available\");\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const arm = (ms: number) => {\n if (!ac) return;\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => ac.abort(), ms);\n };\n arm(STREAM_RESPONSE_TIMEOUT_MS);\n try {\n let res: Response;\n try {\n res = await f(this.url(path), {\n method: \"POST\",\n headers: { ...headers, \"X-Guidely-Key\": this.key, Accept: \"text/event-stream, application/json\", \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: ac?.signal,\n credentials: \"omit\",\n mode: \"cors\",\n });\n } catch (err) {\n this.observe(null);\n throw err;\n }\n this.observe(res);\n const type = res.headers?.get?.(\"content-type\") ?? \"\";\n if (!type.includes(\"text/event-stream\") || !res.body) {\n let data: T | null = null;\n try {\n data = (await res.json()) as T;\n } catch {\n data = null;\n }\n return { status: res.status, ok: res.ok, data, etag: null };\n }\n arm(STREAM_IDLE_TIMEOUT_MS);\n await readEventStream(res.body, onEvent, () => arm(STREAM_IDLE_TIMEOUT_MS));\n return { status: res.status, ok: res.ok, data: null, etag: null };\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /** `navigator.sendBeacon` when available (page unload); returns false when it could not be queued. */\n beacon(path: string, body: unknown): boolean {\n try {\n if (typeof navigator === \"undefined\" || typeof navigator.sendBeacon !== \"function\") return false;\n // text/plain is a CORS-safelisted type: cross-origin beacons need no preflight (which\n // browsers drop during unload). The API parses the body regardless of content type.\n const blob = new Blob([JSON.stringify(body)], { type: \"text/plain;charset=UTF-8\" });\n return navigator.sendBeacon(this.url(path), blob);\n } catch {\n return false;\n }\n }\n}\n\nexport const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\n/** Exponential backoff helper: 1s → 2s → 4s … capped. */\nexport function backoffMs(attempt: number, baseMs = 1000, maxMs = 30000): number {\n return Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt));\n}\n\n/**\n * Sends with bounded retries: network errors, 429 and 5xx are retried with backoff; success and\n * other 4xx answers are returned as they are. Null when every attempt failed.\n */\nexport async function withRetry<T>(send: () => Promise<ApiResponse<T>>, attempts = 3, baseMs = 500): Promise<ApiResponse<T> | null> {\n for (let i = 0; i < attempts; i++) {\n try {\n const res = await send();\n if (res.ok || (res.status >= 400 && res.status < 500 && res.status !== 429)) return res;\n } catch {\n /* network error → retry */\n }\n if (i < attempts - 1) await sleep(backoffMs(i, baseMs, 8000));\n }\n return null;\n}\n\n/** Fire-and-forget POST with bounded retries (used for state sync; never blocks UI). */\nexport function postWithRetry<T>(api: Api, path: string, body: unknown, attempts = 3, baseMs = 500): Promise<ApiResponse<T> | null> {\n return withRetry(() => api.post<T>(path, body), attempts, baseMs);\n}\n\n/** Parses a `text/event-stream` body (`event:` + single-line JSON `data:`; comment lines ignored). `onChunk` runs whenever bytes arrive. */\nexport async function readEventStream(body: ReadableStream<Uint8Array>, onEvent: (event: string, data: unknown) => void, onChunk?: () => void): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const dispatch = (raw: string) => {\n let event = \"message\";\n const data: string[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) continue;\n const i = line.indexOf(\":\");\n const field = i < 0 ? line : line.slice(0, i);\n const value = i < 0 ? \"\" : line.slice(i + 1).replace(/^ /, \"\");\n if (field === \"event\") event = value;\n else if (field === \"data\") data.push(value);\n }\n if (!data.length) return;\n try {\n onEvent(event, JSON.parse(data.join(\"\\n\")));\n } catch {\n /* ignore malformed events */\n }\n };\n for (;;) {\n const { done, value } = await reader.read();\n if (value) onChunk?.();\n if (value) buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n?/g, \"\\n\");\n let sep: number;\n while ((sep = buffer.indexOf(\"\\n\\n\")) >= 0) {\n dispatch(buffer.slice(0, sep));\n buffer = buffer.slice(sep + 2);\n }\n if (done) break;\n }\n if (buffer.trim()) dispatch(buffer);\n}\n","export type StorageKind = \"local\" | \"session\" | \"memory\";\n\n/** Minimal synchronous key/value store; never throws (private mode, quota, SSR). */\nexport interface KeyValueStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\nexport function memoryStore(): KeyValueStore {\n const map = new Map<string, string>();\n return { get: (k) => map.get(k) ?? null, set: (k, v) => void map.set(k, v), remove: (k) => void map.delete(k) };\n}\n\nfunction webStore(area: \"localStorage\" | \"sessionStorage\"): KeyValueStore | null {\n try {\n if (typeof window === \"undefined\") return null;\n const s = window[area];\n if (!s) return null;\n const probe = \"__guidely_probe__\";\n s.setItem(probe, \"1\");\n s.removeItem(probe);\n return {\n get: (k) => {\n try {\n return s.getItem(k);\n } catch {\n return null;\n }\n },\n set: (k, v) => {\n try {\n s.setItem(k, v);\n } catch {\n /* quota / private mode */\n }\n },\n remove: (k) => {\n try {\n s.removeItem(k);\n } catch {\n /* ignore */\n }\n },\n };\n } catch {\n return null;\n }\n}\n\n/** Creates a store of the requested kind, degrading to memory when unavailable. */\nexport function createStorage(kind: StorageKind = \"local\"): KeyValueStore {\n if (kind === \"memory\") return memoryStore();\n return webStore(kind === \"local\" ? \"localStorage\" : \"sessionStorage\") ?? memoryStore();\n}\n\nexport function readJson<T>(store: KeyValueStore, key: string, fallback: T): T {\n const raw = store.get(key);\n if (raw == null) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\nexport function writeJson(store: KeyValueStore, key: string, value: unknown): void {\n try {\n store.set(key, JSON.stringify(value));\n } catch {\n /* ignore */\n }\n}\n\n/** Storage keys used by the SDK (documented for integrators). */\nexport const KEYS = {\n anon: \"guidely:anon\",\n seen: \"guidely:seen\",\n config: (key: string) => `guidely:config:${key}`,\n etag: (key: string) => `guidely:etag:${key}`,\n state: (key: string) => `guidely:state:${key}`,\n user: (key: string) => `guidely:user:${key}`,\n queue: (key: string) => `guidely:queue:${key}`,\n /** Survey answers and guide/checklist progress not yet accepted by the server. */\n outbox: (key: string) => `guidely:outbox:${key}`,\n /** Agent Analytics turns not yet accepted by the server. */\n agentOutbox: (key: string) => `guidely:agents:${key}`,\n session: \"guidely:session\",\n active: \"guidely:active\",\n authoring: \"guidely:authoring\",\n /** How-to capture session marker ({ token, … }) and its not-yet-uploaded steps. */\n capture: \"guidely:capture\",\n capturePending: \"guidely:capture:pending\",\n /** Messenger conversations this browser can read: [{ id, token }]. */\n conversations: (key: string) => `guidely:conversations:${key}`,\n /** Announcement ids opened in the messenger's News tab. */\n newsSeen: (key: string) => `guidely:news:${key}`,\n /** Where the visitor dragged the messenger launcher ({ side, y }). */\n launcher: (key: string) => `guidely:launcher:${key}`,\n} as const;\n","import type { ServerHealth } from \"./health\";\nimport { backoffMs, type Api } from \"./http\";\nimport { readJson, writeJson, type KeyValueStore } from \"./storage\";\n\n/** One request waiting to reach the server. */\ninterface OutboxItem {\n /** Same key → the newer request replaces the older one (e.g. a checklist's latest progress). */\n key: string;\n path: string;\n body: unknown;\n createdAt: number;\n}\n\nexport interface OutboxOptions {\n api: Api;\n store: KeyValueStore;\n storageKey: string;\n health?: ServerHealth;\n maxItems?: number;\n maxAgeMs?: number;\n onError?: (err: unknown) => void;\n}\n\n/**\n * Persisted queue for writes that must not be lost when the API is down: survey answers, guide\n * completions and checklist progress. Each request is kept (also across page loads) until the\n * server answers it; 5xx, 429 and network errors are retried with backoff, waiting while the API's\n * circuit is open. Every request is idempotent on the server (survey answers dedupe by\n * `responseId`, progress merges), so sending one twice is harmless. Bounded to 50 requests and 7 days.\n */\nexport class Outbox {\n private items: OutboxItem[];\n private sending = false;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private destroyed = false;\n private readonly offRecover: (() => void) | null;\n private readonly maxItems: number;\n private readonly maxAgeMs: number;\n\n constructor(private readonly opts: OutboxOptions) {\n this.maxItems = opts.maxItems ?? 50;\n this.maxAgeMs = opts.maxAgeMs ?? 7 * 24 * 60 * 60 * 1000;\n const stored = readJson<OutboxItem[]>(opts.store, opts.storageKey, []);\n const cutoff = Date.now() - this.maxAgeMs;\n this.items = Array.isArray(stored) ? stored.filter((i) => i && typeof i.path === \"string\" && typeof i.key === \"string\" && i.createdAt > cutoff).slice(-this.maxItems) : [];\n this.offRecover = opts.health?.onRecover(() => {\n this.attempt = 0;\n this.retryIn(0);\n }) ?? null;\n if (this.items.length) this.retryIn(0);\n }\n\n get size(): number {\n return this.items.length;\n }\n\n /** Queues `POST path` and sends it now (or as soon as the API is reachable). */\n add(key: string, path: string, body: unknown): void {\n if (this.destroyed) return;\n this.items = this.items.filter((i) => i.key !== key);\n this.items.push({ key, path, body, createdAt: Date.now() });\n if (this.items.length > this.maxItems) this.items.splice(0, this.items.length - this.maxItems);\n this.persist();\n void this.flush();\n }\n\n private persist(): void {\n writeJson(this.opts.store, this.opts.storageKey, this.items);\n }\n\n private retryIn(ms: number): void {\n if (this.destroyed) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, ms);\n }\n\n /** Sends queued requests in order, one at a time. */\n async flush(): Promise<void> {\n if (this.destroyed || this.sending || !this.items.length) return;\n const wait = this.opts.health?.waitMs() ?? 0;\n if (wait > 0) return this.retryIn(wait);\n this.sending = true;\n try {\n while (this.items.length && !this.destroyed) {\n const item = this.items[0] as OutboxItem;\n let retry = false;\n try {\n const res = await this.opts.api.post(item.path, item.body);\n retry = !res.ok && (res.status === 429 || res.status >= 500);\n } catch (err) {\n retry = true;\n this.opts.onError?.(err);\n }\n if (retry) {\n this.attempt += 1;\n this.retryIn(Math.max(backoffMs(this.attempt - 1, 1000, 60_000), this.opts.health?.waitMs() ?? 0));\n return;\n }\n // Answered (or refused for good, e.g. the survey was deleted): done with it. A newer request\n // under the same key may have replaced it while this one was in flight; keep that one.\n this.attempt = 0;\n this.items = this.items.filter((i) => i !== item);\n this.persist();\n }\n } finally {\n this.sending = false;\n }\n }\n\n destroy(): void {\n this.destroyed = true;\n this.offRecover?.();\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n }\n}\n","import { type AppSnapshot, type AuthoringPick, type AuthoringSessionInfo, type ProjectTheme, type SelectorStrategy, type TargetingContext } from \"@guidelytech/shared\";\nimport { closestComposed, highlightSelectors, previewStep, runGuide, startAuthoring, type AuthoringSession, type GuideController, type PreviewHandle, type RunnableGuide } from \"@guidelytech/guide-runtime\";\nimport type { Api } from \"./http\";\nimport { captureSnapshot } from \"./snapshot\";\nimport { elementSnapshot } from \"./tagging\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\n/** Schemas are only needed in authoring mode; load them lazily so the normal runtime stays zod-free. */\nasync function loadSchemas() {\n const m = await import(\"@guidelytech/shared\");\n return { StepSchema: m.StepSchema, GuideConfigSchema: m.GuideConfigSchema };\n}\n\nexport const AUTHORING_PARAM = \"guidely_authoring\";\nexport const HEARTBEAT_MS = 15000;\n/** Quiet period after DOM changes / navigation before a new page snapshot is sent. */\nexport const SNAPSHOT_DEBOUNCE_MS = 800;\n/** Upper bound on how long continuous DOM churn can delay a snapshot. */\nexport const SNAPSHOT_MAX_WAIT_MS = 4000;\n\n/** Messages the SDK posts to the dashboard window (`window.opener`). */\nexport type AuthoringOutgoingMessage =\n | { type: \"guidely:authoring-ready\"; sessionId: string; url: string }\n | { type: \"guidely:pick\"; sessionId: string; pick: AuthoringPick }\n | { type: \"guidely:highlight-result\"; sessionId: string; counts: number[]; resolved: boolean }\n | { type: \"guidely:preview-ended\"; sessionId: string; reason: string }\n | { type: \"guidely:exit\"; sessionId: string }\n | { type: \"guidely:pong\"; sessionId: string; url: string }\n | { type: \"guidely:snapshot\"; sessionId: string; snapshot: AppSnapshot };\n\n/** Messages the dashboard may post to the app window (origin-checked against `dashboardOrigin`). */\nexport type AuthoringIncomingMessage =\n | { type: \"guidely:preview-step\"; step: unknown; theme?: Partial<ProjectTheme> | null; appearance?: unknown }\n | { type: \"guidely:preview-guide\"; guide: { id?: string; key?: string; name?: string; kind?: string; version?: number; config: unknown } }\n | { type: \"guidely:highlight\"; selectors: SelectorStrategy[] }\n | { type: \"guidely:stop-preview\" }\n | { type: \"guidely:ping\" }\n | { type: \"guidely:request-snapshot\" }\n | { type: \"guidely:exit\" };\n\nexport interface AuthoringBridgeOptions {\n api: Api;\n sessionStore: KeyValueStore;\n theme: () => Partial<ProjectTheme>;\n ctx: () => TargetingContext;\n maskSelectors: string[];\n onError: (err: unknown) => void;\n onActive: (active: boolean) => void;\n}\n\n/**\n * Detects `?guidely_authoring=<token>`, verifies the session with the public API, runs the\n * runtime's element picker and bridges picks/previews with the dashboard via `postMessage`.\n */\nexport class AuthoringBridge {\n private token: string | null = null;\n private info: AuthoringSessionInfo | null = null;\n private session: AuthoringSession | null = null;\n private heartbeat: ReturnType<typeof setInterval> | null = null;\n private preview: PreviewHandle | null = null;\n private previewGuide: GuideController | null = null;\n private active = false;\n private observer: MutationObserver | null = null;\n private snapshotTimer: ReturnType<typeof setTimeout> | null = null;\n private snapshotDue = 0;\n private lastSnapshot = \"\";\n\n constructor(private readonly opts: AuthoringBridgeOptions) {}\n\n isActive(): boolean {\n return this.active;\n }\n\n /** Returns true when a token was found (in the URL or the session marker) and verification started. */\n detect(): boolean {\n if (typeof window === \"undefined\") return false;\n let token: string | null = null;\n try {\n const url = new URL(window.location.href);\n token = url.searchParams.get(AUTHORING_PARAM);\n if (token) {\n url.searchParams.delete(AUTHORING_PARAM);\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n } catch {\n token = null;\n }\n if (!token) {\n const marker = readJson<{ token?: string } | null>(this.opts.sessionStore, KEYS.authoring, null);\n token = marker?.token ?? null;\n }\n if (!token) return false;\n this.token = token;\n writeJson(this.opts.sessionStore, KEYS.authoring, { token });\n void this.start();\n return true;\n }\n\n private async start(): Promise<void> {\n if (!this.token) return;\n try {\n const res = await this.opts.api.get<AuthoringSessionInfo>(\"/authoring/session\", { params: { token: this.token } });\n if (!res.ok || !res.data) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(`[Guidely] authoring session invalid or expired (${res.status})`));\n return;\n }\n this.info = res.data;\n if (Date.parse(this.info.expiresAt) < Date.now()) {\n this.opts.sessionStore.remove(KEYS.authoring);\n this.opts.onError(new Error(\"[Guidely] authoring session expired\"));\n return;\n }\n this.active = true;\n this.opts.onActive(true);\n this.session = startAuthoring({\n dashboardOrigin: this.info.dashboardOrigin,\n // Tag mode (Pages & Features): picks become feature rules; the page itself is tagged from the dashboard.\n message: this.info.purpose === \"tag\" ? \"Guidely tagging — click an element to tag it as a feature · tag the page from the dashboard · Esc to finish\" : undefined,\n onPick: (pick) => this.sendPick(pick),\n onExit: () => this.stop(),\n });\n this.heartbeat = setInterval(() => {\n void this.opts.api.post(\"/authoring/session/heartbeat\", {}, { params: { token: this.token ?? undefined } }).catch(() => {});\n }, HEARTBEAT_MS);\n this.post({ type: \"guidely:authoring-ready\", sessionId: this.info.id, url: window.location.href });\n this.watchPage();\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private masked(el: Element): boolean {\n return this.opts.maskSelectors.some((sel) => {\n try {\n return !!closestComposed(el, sel);\n } catch {\n return false;\n }\n });\n }\n\n private sendPick(raw: AuthoringPick & { element: Element }): void {\n if (!this.info || !this.token) return;\n const { element, ...rest } = raw;\n const pick: AuthoringPick = this.masked(element) ? { ...rest, textSnapshot: \"\", selectors: rest.selectors.filter((s) => s.kind !== \"text\") } : rest;\n pick.url = window.location.href;\n // Tag mode: a compact description of the element, so the dashboard can propose CSS rules for it.\n if (this.info.purpose === \"tag\") pick.elementSnapshot = elementSnapshot(element, { mask: this.opts.maskSelectors.join(\",\"), maskAll: false, featureAttribute: null }) as unknown as Record<string, unknown>;\n this.post({ type: \"guidely:pick\", sessionId: this.info.id, pick });\n void this.opts.api.post(\"/authoring/session/picks\", pick, { params: { token: this.token } }).catch((err) => this.opts.onError(err));\n }\n\n /** Sends a snapshot now and again whenever the page settles after DOM changes or navigation. */\n private watchPage(): void {\n this.scheduleSnapshot();\n if (typeof MutationObserver === \"undefined\") return;\n this.observer = new MutationObserver(() => this.scheduleSnapshot());\n this.observer.observe(document.documentElement, { subtree: true, childList: true, attributes: true, characterData: true });\n }\n\n private scheduleSnapshot(): void {\n const now = Date.now();\n if (!this.snapshotTimer) this.snapshotDue = now + SNAPSHOT_MAX_WAIT_MS;\n else clearTimeout(this.snapshotTimer);\n this.snapshotTimer = setTimeout(() => this.sendSnapshot(), Math.max(0, Math.min(SNAPSHOT_DEBOUNCE_MS, this.snapshotDue - now)));\n }\n\n private sendSnapshot(): void {\n if (this.snapshotTimer) clearTimeout(this.snapshotTimer);\n this.snapshotTimer = null;\n if (!this.info || !this.active) return;\n try {\n const snapshot = captureSnapshot(document, this.opts.maskSelectors);\n if (!snapshot || snapshot.html === this.lastSnapshot) return;\n this.lastSnapshot = snapshot.html;\n this.post({ type: \"guidely:snapshot\", sessionId: this.info.id, snapshot });\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n private post(message: AuthoringOutgoingMessage): void {\n if (!this.info) return;\n try {\n window.opener?.postMessage(message, this.info.dashboardOrigin);\n } catch {\n /* opener may be gone */\n }\n }\n\n private stopPreview(): void {\n this.preview?.destroy();\n this.preview = null;\n this.previewGuide?.destroy();\n this.previewGuide = null;\n this.session?.setPicking(true);\n }\n\n /** Handles `message` events; ignores anything not from `dashboardOrigin`. */\n async handleMessage(e: MessageEvent): Promise<void> {\n if (!this.active || !this.info) return;\n if (e.origin !== this.info.dashboardOrigin) return;\n const msg = e.data as AuthoringIncomingMessage | null;\n if (!msg || typeof msg !== \"object\" || typeof msg.type !== \"string\") return;\n try {\n switch (msg.type) {\n case \"guidely:preview-step\": {\n this.stopPreview();\n const { StepSchema, GuideConfigSchema } = await loadSchemas();\n const step = StepSchema.parse(msg.step);\n const appearance = msg.appearance ? GuideConfigSchema.shape.appearance.parse(msg.appearance) : undefined;\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing step “${step.title || step.id}” — close it to continue picking`);\n this.preview = previewStep(step, { ...this.opts.theme(), ...(msg.theme || {}) }, {\n appearance,\n onEnd: () => {\n this.preview = null;\n this.session?.setPicking(true);\n this.session?.setStatus(\"Guidely authoring — hover an element and click to select · Esc to cancel\");\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason: \"step\" });\n },\n });\n break;\n }\n case \"guidely:preview-guide\": {\n this.stopPreview();\n const g = msg.guide;\n const guide: RunnableGuide = { id: g.id || \"preview\", key: g.key || \"preview\", name: g.name || \"Preview\", kind: g.kind || \"flow\", version: g.version ?? 0, config: (await loadSchemas()).GuideConfigSchema.parse(g.config) };\n this.session?.setPicking(false);\n this.session?.setStatus(`Previewing “${guide.name}”`);\n this.previewGuide = runGuide(guide, {\n theme: this.opts.theme(),\n ctx: this.opts.ctx,\n onNavigate: (url, newTab) => (newTab ? window.open(url, \"_blank\", \"noopener\") : window.location.assign(url)),\n onEnd: (reason) => {\n this.previewGuide = null;\n this.session?.setPicking(true);\n this.post({ type: \"guidely:preview-ended\", sessionId: this.info!.id, reason });\n },\n });\n this.previewGuide.start();\n break;\n }\n case \"guidely:highlight\": {\n const result = highlightSelectors(Array.isArray(msg.selectors) ? msg.selectors : [], { durationMs: 3000 });\n this.post({ type: \"guidely:highlight-result\", sessionId: this.info.id, counts: result.counts, resolved: !!result.resolved });\n break;\n }\n case \"guidely:stop-preview\":\n this.stopPreview();\n break;\n case \"guidely:request-snapshot\":\n this.lastSnapshot = \"\";\n this.sendSnapshot();\n break;\n case \"guidely:ping\":\n this.post({ type: \"guidely:pong\", sessionId: this.info.id, url: window.location.href });\n break;\n case \"guidely:exit\":\n this.stop();\n break;\n default:\n break;\n }\n } catch (err) {\n this.opts.onError(err);\n }\n }\n\n /** Leaves authoring mode and clears the session marker. */\n stop(): void {\n if (!this.active) return;\n this.active = false;\n this.stopPreview();\n this.observer?.disconnect();\n this.observer = null;\n if (this.snapshotTimer) clearTimeout(this.snapshotTimer);\n this.snapshotTimer = null;\n if (this.heartbeat) clearInterval(this.heartbeat);\n this.heartbeat = null;\n this.session?.stop();\n this.session = null;\n this.opts.sessionStore.remove(KEYS.authoring);\n if (this.info) this.post({ type: \"guidely:exit\", sessionId: this.info.id });\n this.opts.onActive(false);\n }\n}\n","import type { AppSnapshot } from \"@guidelytech/shared\";\n\n/** Snapshots larger than this are not sent (postMessage copies the string). */\nexport const MAX_SNAPSHOT_BYTES = 6 * 1024 * 1024;\n\nconst STRIP = \"script, noscript, template, #guidely-root, [data-guidely], meta[http-equiv], link[rel~='preload'], link[rel~='modulepreload'], link[rel~='prefetch'], link[rel~='manifest'], link[rel~='serviceworker']\";\n\n/** Text of a stylesheet built through the CSSOM (CSS-in-JS often leaves `<style>` empty). */\nfunction rulesText(sheet: CSSStyleSheet | null | undefined): string | null {\n if (!sheet) return null;\n try {\n return Array.from(sheet.cssRules, (r) => r.cssText).join(\"\\n\");\n } catch {\n return null; // cross-origin sheet\n }\n}\n\n/** Replaces text inside masked elements with bullets of the same length, keeping the layout. */\nfunction maskText(root: Element): void {\n const walker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n for (let n = walker.nextNode(); n; n = walker.nextNode()) {\n n.textContent = (n.textContent ?? \"\").replace(/\\S/g, \"•\");\n }\n}\n\n/**\n * Serializes the current page into a static HTML document for the dashboard's editor canvas.\n * Scripts, event handlers, Guidely's own UI and form values are dropped; `maskSelectors` text is\n * replaced with bullets. Same-origin CSSOM rules are inlined; everything else resolves through a\n * `<base href>` so stylesheets and images load from the app.\n */\nexport function captureSnapshot(doc: Document, maskSelectors: string[], maxBytes = MAX_SNAPSHOT_BYTES): AppSnapshot | null {\n const win = doc.defaultView;\n if (!win || !doc.documentElement) return null;\n const clone = doc.documentElement.cloneNode(true) as HTMLElement;\n\n // Elements whose state lives outside their markup are matched to the clone by document order,\n // so do this before anything is removed from the clone.\n const origStyles = doc.documentElement.querySelectorAll(\"style\");\n clone.querySelectorAll(\"style\").forEach((el, i) => {\n const css = rulesText(origStyles[i]?.sheet as CSSStyleSheet | null);\n if (css !== null && css.length > (el.textContent ?? \"\").length) el.textContent = css;\n });\n const origFrames = doc.documentElement.querySelectorAll(\"iframe, canvas, video, embed, object\");\n clone.querySelectorAll(\"iframe, canvas, video, embed, object\").forEach((el, i) => {\n const r = origFrames[i]?.getBoundingClientRect();\n const box = doc.createElement(\"div\");\n box.setAttribute(\"style\", `${el.getAttribute(\"style\") ?? \"\"};width:${r?.width ?? 0}px;height:${r?.height ?? 0}px;background:#e2e8f0;border-radius:4px`);\n if (el.getAttribute(\"class\")) box.setAttribute(\"class\", el.getAttribute(\"class\")!);\n el.replaceWith(box);\n });\n\n clone.querySelectorAll(STRIP).forEach((el) => el.remove());\n for (const sel of maskSelectors) {\n try {\n clone.querySelectorAll(sel).forEach(maskText);\n } catch {\n /* invalid selector */\n }\n }\n clone.querySelectorAll(\"*\").forEach((el) => {\n for (const attr of Array.from(el.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith(\"on\") || ((name === \"href\" || name === \"src\" || name === \"action\") && /^\\s*javascript:/i.test(attr.value))) el.removeAttribute(attr.name);\n }\n if (el instanceof HTMLInputElement) {\n el.removeAttribute(\"value\");\n el.removeAttribute(\"checked\");\n } else if (el instanceof HTMLTextAreaElement) {\n el.textContent = \"\";\n }\n el.removeAttribute(\"autofocus\");\n });\n\n const adopted = Array.from((doc as Document & { adoptedStyleSheets?: CSSStyleSheet[] }).adoptedStyleSheets ?? [])\n .map(rulesText)\n .filter(Boolean)\n .join(\"\\n\");\n let head = clone.querySelector(\"head\");\n if (!head) {\n head = doc.createElement(\"head\");\n clone.prepend(head);\n }\n if (adopted) {\n const style = doc.createElement(\"style\");\n style.textContent = adopted;\n head.append(style);\n }\n clone.querySelectorAll(\"base\").forEach((el) => el.remove());\n const base = doc.createElement(\"base\");\n base.setAttribute(\"href\", doc.baseURI || win.location.href);\n base.setAttribute(\"target\", \"_blank\");\n head.prepend(base);\n\n const html = `<!DOCTYPE html>\\n${clone.outerHTML}`;\n if (html.length > maxBytes) return null;\n return { html, url: win.location.href, title: doc.title, width: win.innerWidth, height: win.innerHeight, capturedAt: new Date().toISOString() };\n}\n","import { NOISY_DATA_ATTR, SNAPSHOT_LIMITS, TAG_PROPERTY_LIMITS, featureRuleMatchesClick, pageRuleMatches, pageRulesMatch, type ElementNode, type ElementSnapshot, type TaggingSdkConfig } from \"@guidelytech/shared/runtime\";\nimport { closestComposed, isStableClass, isStableId, querySelectorStrategy } from \"@guidelytech/guide-runtime\";\nimport type { ClickProperties } from \"./autocapture\";\nimport { elementText } from \"./autocapture\";\n\n/**\n * Tagged pages and features in the browser: the compact element snapshot attached to clicks (so CSS\n * selector rules written later still match them), the feature attribute, and the DOM properties a\n * project asked to read on matching clicks and page views.\n */\n\n/** Text-like attributes dropped from masked elements. */\nconst TEXT_ATTRS = new Set([\"aria-label\", \"title\", \"alt\"]);\nconst SAFE_ATTRS = [\"role\", \"name\", \"type\", \"aria-label\", \"title\", \"alt\", \"for\"];\n/** Classes that only describe a passing state; they would split one element into many. */\nconst STATE_CLASS = /^(is-|has-)?(active|hover|hovered|focus|focused|focus-visible|selected|open|opened|closed|disabled|visible|hidden|show|shown|collapsed|expanded|checked|pressed|loading|current)$/i;\n\nfunction nthOfType(el: Element): number | undefined {\n const parent = el.parentElement;\n if (!parent) return undefined;\n let n = 0;\n for (const c of Array.from(parent.children)) {\n if (c.tagName === el.tagName) n++;\n if (c === el) return n;\n }\n return undefined;\n}\n\nfunction nodeOf(el: Element, masked: boolean, featureAttribute: string | null): ElementNode {\n const node: ElementNode = { t: el.tagName.toLowerCase().slice(0, SNAPSHOT_LIMITS.tag) };\n if (el.id && isStableId(el.id) && el.id.length <= SNAPSHOT_LIMITS.id) node.id = el.id;\n const classes = Array.from(el.classList).filter((c) => isStableClass(c) && !STATE_CLASS.test(c) && c.length <= SNAPSHOT_LIMITS.className);\n if (classes.length) node.c = classes.slice(0, SNAPSHOT_LIMITS.classes);\n const a: Record<string, string> = {};\n const put = (name: string, value: string | null) => {\n if (value === null || Object.keys(a).length >= SNAPSHOT_LIMITS.attrs || name in a) return;\n if (masked && TEXT_ATTRS.has(name)) return;\n a[name] = value.slice(0, SNAPSHOT_LIMITS.attrValue);\n };\n // The feature attribute first: auto-tagged features are matched on it.\n if (featureAttribute && el.hasAttribute(featureAttribute)) put(featureAttribute, el.getAttribute(featureAttribute));\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"data-\") && !NOISY_DATA_ATTR.test(attr.name) && attr.value.length <= SNAPSHOT_LIMITS.attrValue) put(attr.name, attr.value);\n }\n for (const name of SAFE_ATTRS) if (el.hasAttribute(name)) put(name, el.getAttribute(name));\n if (Object.keys(a).length) node.a = a;\n const n = nthOfType(el);\n if (n) node.n = n;\n return node;\n}\n\n/**\n * Compact snapshot of an element: itself, up to 5 ancestors in its own tree and up to 3 shadow\n * hosts. Never values of form fields; text-like attributes are left out under masking.\n */\nexport function elementSnapshot(el: Element, opts: { mask: string; maskAll: boolean; featureAttribute: string | null }): ElementSnapshot {\n const masked = opts.maskAll || isMasked(el, opts.mask);\n const snap: ElementSnapshot = nodeOf(el, masked, opts.featureAttribute);\n const p: ElementNode[] = [];\n for (let cur = el.parentElement; cur && p.length < SNAPSHOT_LIMITS.ancestors; cur = cur.parentElement) {\n if (cur.tagName === \"BODY\" || cur.tagName === \"HTML\") break;\n p.push(nodeOf(cur, masked, opts.featureAttribute));\n }\n if (p.length) snap.p = p;\n const h: ElementNode[] = [];\n let root = el.getRootNode?.() as (Node & { host?: Element }) | undefined;\n while (root && root.nodeType === 11 && root.host && h.length < SNAPSHOT_LIMITS.hosts) {\n h.push(nodeOf(root.host, masked, opts.featureAttribute));\n root = root.host.getRootNode?.() as (Node & { host?: Element }) | undefined;\n }\n if (h.length) snap.h = h;\n return snap;\n}\n\nfunction isMasked(el: Element, mask: string): boolean {\n if (!mask) return false;\n try {\n return !!closestComposed(el, mask);\n } catch {\n return false;\n }\n}\n\n/** The element carrying the feature attribute at or above the click target, and its value. */\nexport function featureAttributeOf(target: Element, attribute: string | null): { el: Element; value: string } | null {\n if (!attribute) return null;\n try {\n const el = closestComposed(target, `[${attribute}]`);\n const value = el?.getAttribute(attribute)?.replace(/\\s+/g, \" \").trim();\n return el && value ? { el, value: value.slice(0, 100) } : null;\n } catch {\n return null;\n }\n}\n\nfunction readProperty(def: { selector?: string; source: \"text\" | \"attribute\"; attribute?: string }, base: Element | null, opts: { mask: string; maskAll: boolean }): string | undefined {\n let el: Element | null = base;\n if (def.selector) {\n try {\n el = querySelectorStrategy({ kind: \"css\", value: def.selector }, document)[0] ?? null;\n } catch {\n el = null;\n }\n }\n if (!el) return undefined;\n if (def.source === \"attribute\") {\n const name = (def.attribute ?? \"\").toLowerCase();\n if (!name || name === \"value\" || name.startsWith(\"on\")) return undefined;\n if (opts.maskAll || isMasked(el, opts.mask)) return undefined;\n const v = el.getAttribute(name);\n return v ? v.replace(/\\s+/g, \" \").trim().slice(0, TAG_PROPERTY_LIMITS.value) || undefined : undefined;\n }\n return elementText(el, opts.mask, opts.maskAll);\n}\n\n/** DOM properties for a click on `el` (features whose rules match it), keyed by property id. */\nexport function clickPropertyValues(config: TaggingSdkConfig | undefined, el: Element, click: ClickProperties, opts: { mask: string; maskAll: boolean }): Record<string, string> | undefined {\n if (!config?.properties.length) return undefined;\n const out: Record<string, string> = {};\n const css = (selector: string) => {\n try {\n return !!closestComposed(el, selector);\n } catch {\n return false;\n }\n };\n const here = { url: location.href, path: location.pathname, title: document.title };\n for (const tag of config.properties) {\n if (tag.kind !== \"feature\" || !tag.featureRules) continue;\n const rules = tag.featureRules;\n const matches = (r: (typeof rules)[number]) => featureRuleMatchesClick(r, click, css) && (!r.page?.pattern || pageRuleMatches({ type: \"url\", value: r.page.pattern }, here));\n if (!rules.some((r) => !r.exclude && matches(r)) || rules.some((r) => r.exclude && matches(r))) continue;\n for (const def of tag.properties) {\n const v = readProperty(def, el, opts);\n if (v) out[def.id] = v;\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n\n/** DOM properties for a page view of `url` (pages whose rules match it), keyed by property id. */\nexport function pagePropertyValues(config: TaggingSdkConfig | undefined, url: string, opts: { mask: string; maskAll: boolean }): Record<string, string> | undefined {\n if (!config?.properties.length) return undefined;\n const out: Record<string, string> = {};\n let path = \"/\";\n try {\n path = new URL(url, location.href).pathname;\n } catch {\n /* keep / */\n }\n const ctx = { url, path, title: document.title };\n for (const tag of config.properties) {\n if (tag.kind !== \"page\" || !tag.pageRules || !pageRulesMatch(tag.pageRules, ctx)) continue;\n for (const def of tag.properties) {\n if (!def.selector) continue;\n const v = readProperty(def, null, opts);\n if (v) out[def.id] = v;\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n","import { closestComposed, isGuidelyElement, isStableId, SHADOW_SEPARATOR, shadowHostChain } from \"@guidelytech/guide-runtime\";\n\n/** Elements whose clicks are autocaptured (the click may land on a descendant). */\nexport const INTERACTIVE_SELECTOR =\n \"a,button,input[type=button],input[type=submit],input[type=reset],input[type=checkbox],input[type=radio],select,summary,label,[role=button],[role=link],[role=tab],[role=menuitem],[role=checkbox],[role=switch],[role=option],[onclick],[data-guidely-track]\";\n\n/** Always-on mask selectors (text never captured, masked in replays). */\nexport const DEFAULT_MASK_SELECTORS = [\"[data-guidely-mask]\", \".guidely-mask\"];\n\n/** `click` / `rage_click` event properties. */\nexport interface ClickProperties {\n tag: string;\n text?: string;\n selector: string;\n href?: string;\n x: number;\n y: number;\n count?: number;\n}\n\nconst PREFERRED_ATTRS = [\"data-testid\", \"data-test-id\", \"data-test\", \"data-cy\", \"data-qa\", \"data-guidely-track\", \"data-tour\"];\nconst NOISY_DATA_ATTR = /^data-(state|v-|react|radix|headlessui|svelte|orientation|highlighted|focus|key|index|side|align|disabled|selected|active|open|guidely-(mask|ignore|block))/i;\n\n/** Drops empty and syntactically invalid CSS selectors. */\nexport function validSelectors(list: Array<string | null | undefined>): string[] {\n const out: string[] = [];\n const probe = typeof document !== \"undefined\" ? document.createDocumentFragment() : null;\n for (const raw of list) {\n const s = (raw || \"\").trim();\n if (!s || out.includes(s)) continue;\n try {\n probe?.querySelector(s);\n out.push(s);\n } catch {\n /* invalid selector */\n }\n }\n return out;\n}\n\n/** True for clicks Guidely must never capture: its own UI and anything under `[data-guidely-ignore]`. */\nexport function isIgnoredElement(el: Element): boolean {\n return isGuidelyElement(el) || !!closestComposed(el, \"[data-guidely-ignore]\");\n}\n\n/** The interactive element a click landed on (or inside), if any. */\nexport function interactiveElement(target: Element): Element | null {\n try {\n return closestComposed(target, INTERACTIVE_SELECTOR);\n } catch {\n return null;\n }\n}\n\nfunction esc(value: string): string {\n const g = globalThis as { CSS?: { escape?: (v: string) => string } };\n return g.CSS?.escape ? g.CSS.escape(value) : value.replace(/[^\\w-]/g, (c) => `\\\\${c}`);\n}\n\nconst attr = (tag: string, name: string, value: string) => (value ? `${tag}[${name}=\"${value.replace(/[\"\\\\]/g, \"\\\\$&\")}\"]` : `${tag}[${name}]`);\n\n/**\n * Stable selector: id → test/tracking data attributes → other data-* → aria-label → short CSS path.\n * Inside a shadow root it is prefixed with the host chain (`c-app >>> button.save`).\n */\nexport function elementSelector(el: Element): string {\n const own = ownSelector(el);\n const chain = shadowHostChain(el);\n return (chain ? chain + SHADOW_SEPARATOR + own : own).slice(0, 300);\n}\n\nfunction ownSelector(el: Element): string {\n const tag = el.tagName.toLowerCase();\n if (el.id && isStableId(el.id)) return `#${esc(el.id)}`;\n for (const name of PREFERRED_ATTRS) if (el.hasAttribute(name)) return attr(tag, name, el.getAttribute(name) || \"\");\n for (const a of Array.from(el.attributes)) {\n if (a.name.startsWith(\"data-\") && !NOISY_DATA_ATTR.test(a.name) && a.value && a.value.length <= 60) return attr(tag, a.name, a.value);\n }\n const label = el.getAttribute(\"aria-label\");\n if (label && label.length <= 80) return attr(tag, \"aria-label\", label);\n const parts: string[] = [];\n let cur: Element | null = el;\n while (cur && parts.length < 4) {\n const t = cur.tagName.toLowerCase();\n if (t === \"html\" || t === \"body\") break;\n if (cur !== el && cur.id && isStableId(cur.id)) {\n parts.unshift(`#${esc(cur.id)}`);\n break;\n }\n const parent: Element | null = cur.parentElement;\n const node: Element = cur;\n const same = parent ? Array.from(parent.children).filter((c) => c.tagName === node.tagName) : [];\n parts.unshift(same.length > 1 ? `${t}:nth-of-type(${same.indexOf(node) + 1})` : t);\n cur = parent;\n }\n return parts.join(\" > \") || tag;\n}\n\nfunction matches(el: Element, selector: string, deep: boolean): boolean {\n if (!selector) return false;\n try {\n return !!closestComposed(el, selector) || (deep && !!el.querySelector(selector));\n } catch {\n return false;\n }\n}\n\n/**\n * Visible text of a clicked element (≤100 chars, whitespace collapsed). Never the value of a form\n * field (only button-like inputs), and nothing when the element is (or contains) masked content.\n */\nexport function elementText(el: Element, mask: string, maskAll: boolean): string | undefined {\n if (maskAll || matches(el, mask, true)) return undefined;\n const tag = el.tagName.toLowerCase();\n let text = \"\";\n if (tag === \"input\") {\n if (!/^(button|submit|reset)$/i.test((el as HTMLInputElement).type || \"\")) return undefined;\n text = (el as HTMLInputElement).value;\n } else if (tag === \"select\" || tag === \"textarea\") return undefined;\n else text = (el as HTMLElement).innerText ?? el.textContent ?? \"\";\n text = (text || el.getAttribute(\"aria-label\") || el.getAttribute(\"title\") || \"\").replace(/\\s+/g, \" \").trim();\n return text ? text.slice(0, 100) : undefined;\n}\n\n/** Link target for analytics: the path for same-origin links, only the origin otherwise. */\nexport function linkHref(el: Element): string | undefined {\n const a = closestComposed(el, \"a[href]\");\n if (!a) return undefined;\n try {\n const u = new URL(a.getAttribute(\"href\") || \"\", location.href);\n if (!/^https?:$/.test(u.protocol)) return undefined;\n return u.origin === location.origin ? u.pathname : u.origin;\n } catch {\n return undefined;\n }\n}\n\n/** Builds `click` properties for an element. */\nexport function describeClick(el: Element, e: MouseEvent, opts: { mask: string; maskAll: boolean; collectUrls: boolean }): ClickProperties {\n const props: ClickProperties = { tag: el.tagName.toLowerCase(), selector: elementSelector(el), x: Math.round(e.pageX ?? 0) || 0, y: Math.round(e.pageY ?? 0) || 0 };\n const text = elementText(el, opts.mask, opts.maskAll);\n if (text) props.text = text;\n const href = opts.collectUrls ? linkHref(el) : undefined;\n if (href) props.href = href;\n return props;\n}\n\n/** Detects rage clicks: 3+ clicks within 1s and 30px of each other, reported once per burst. */\nexport class RageClickDetector {\n private clicks: Array<{ x: number; y: number; t: number }> = [];\n private fired = false;\n\n constructor(\n private readonly threshold = 3,\n private readonly windowMs = 1000,\n private readonly radius = 30,\n ) {}\n\n /** Clicks in the current burst once it has fired (rage), otherwise 0. */\n get burst(): number {\n return this.fired ? this.clicks.length : 0;\n }\n\n /** Records a click; returns the click count when it completes a burst, otherwise 0. */\n add(x: number, y: number, t: number): number {\n const first = this.clicks[0];\n const last = this.clicks[this.clicks.length - 1];\n if (!first || !last || t - last.t > this.windowMs || Math.hypot(x - first.x, y - first.y) > this.radius) {\n this.clicks = [];\n this.fired = false;\n }\n this.clicks = this.clicks.filter((c) => t - c.t <= this.windowMs);\n this.clicks.push({ x, y, t });\n if (this.fired || this.clicks.length < this.threshold) return 0;\n this.fired = true;\n return this.clicks.length;\n }\n}\n","import { CAPTURE_PARAM } from \"@guidelytech/shared/runtime\";\nimport { AUTHORING_PARAM } from \"./authoring\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\nexport { CAPTURE_PARAM };\n\n/** What the SDK remembers about a capture session in this tab (`guidely:capture` in sessionStorage). */\nexport interface CaptureMarker {\n token: string;\n /** Recording has started (a page load continues it instead of showing \"Start recording\"). */\n started?: boolean;\n /** The user chose to take screenshots. */\n screenshots?: boolean;\n /** Epoch ms and action of the last recorded step. */\n lastStepAt?: number;\n lastAction?: string;\n}\n\n/**\n * Finds a capture token in the URL (and strips it) or in this tab's session marker. A capture\n * param wins over an authoring param; a leftover marker does not win over a fresh authoring link.\n */\nexport function takeCaptureToken(sessionStore: KeyValueStore): CaptureMarker | null {\n if (typeof window === \"undefined\") return null;\n let token: string | null = null;\n let authoringLink = false;\n try {\n const url = new URL(window.location.href);\n token = url.searchParams.get(CAPTURE_PARAM);\n authoringLink = url.searchParams.has(AUTHORING_PARAM);\n if (token) {\n url.searchParams.delete(CAPTURE_PARAM);\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n } catch {\n token = null;\n }\n const saved = readJson<CaptureMarker | null>(sessionStore, KEYS.capture, null);\n let marker: CaptureMarker | null = null;\n if (token) marker = saved?.token === token ? saved : { token };\n else if (saved?.token && !authoringLink) marker = saved;\n if (!marker) {\n if (saved) {\n sessionStore.remove(KEYS.capture);\n sessionStore.remove(KEYS.capturePending);\n }\n return null;\n }\n if (token && saved?.token !== token) sessionStore.remove(KEYS.capturePending);\n writeJson(sessionStore, KEYS.capture, marker);\n sessionStore.remove(KEYS.authoring);\n return marker;\n}\n","import type { CaptureApi } from \"./capture\";\n\n/**\n * Loads the how-to capture chunk on demand (only in a capture session). Like the replay recorder,\n * the import is rewritten per build: `./capture.js` (npm; consumers' bundlers code-split it) or, in\n * the script-tag build, a loader that injects `guidely-capture.js` and resolves `window.__guidelyCapture`.\n */\nexport const loadCapture = async (): Promise<CaptureApi> => (await import(\"./capture\")).capture;\n","import type { TargetingContext } from \"@guidelytech/shared\";\n\nexport interface DeviceInfo {\n type: \"desktop\" | \"tablet\" | \"mobile\";\n browser?: string;\n os?: string;\n}\n\n/** Lightweight UA sniffing (good enough for targeting; not for feature detection). */\nexport function detectDevice(ua: string, width: number): DeviceInfo {\n const u = ua || \"\";\n let type: DeviceInfo[\"type\"] = \"desktop\";\n if (/iPad|Tablet|PlayBook|Silk/i.test(u) || (/Android/i.test(u) && !/Mobile/i.test(u))) type = \"tablet\";\n else if (/Mobi|iPhone|iPod|Android.*Mobile|Windows Phone/i.test(u)) type = \"mobile\";\n else if (width > 0 && width < 768) type = \"mobile\";\n else if (width > 0 && width < 1024) type = \"tablet\";\n let browser: string | undefined;\n if (/Electron\\//i.test(u)) browser = \"electron\";\n else if (/Edg\\//i.test(u)) browser = \"edge\";\n else if (/OPR\\/|Opera/i.test(u)) browser = \"opera\";\n else if (/SamsungBrowser/i.test(u)) browser = \"samsung\";\n else if (/Chrome\\/|CriOS/i.test(u)) browser = \"chrome\";\n else if (/Firefox\\/|FxiOS/i.test(u)) browser = \"firefox\";\n else if (/Safari\\//i.test(u) && /Version\\//i.test(u)) browser = \"safari\";\n else if (/MSIE|Trident/i.test(u)) browser = \"ie\";\n let os: string | undefined;\n if (/Windows/i.test(u)) os = \"windows\";\n else if (/iPhone|iPad|iPod/i.test(u)) os = \"ios\";\n else if (/Mac OS X|Macintosh/i.test(u)) os = \"macos\";\n else if (/Android/i.test(u)) os = \"android\";\n else if (/CrOS/i.test(u)) os = \"chromeos\";\n else if (/Linux/i.test(u)) os = \"linux\";\n return { type, browser, os };\n}\n\nexport interface ContextInput {\n anonymousId: string;\n userId?: string | null;\n userAttributes: Record<string, unknown>;\n accountAttributes: Record<string, unknown>;\n url: string;\n firstVisit: boolean;\n eventsSeen: Iterable<string>;\n completedGuides: Iterable<string>;\n dismissedGuides: Iterable<string>;\n seenGuides: Iterable<string>;\n completedChecklists: Iterable<string>;\n audienceIds: Iterable<string>;\n environment: string;\n locale?: string;\n device?: DeviceInfo;\n now?: Date;\n platform?: string;\n screen?: string;\n appVersion?: string;\n}\n\n/** Builds the `TargetingContext` consumed by `evaluateRules`. */\nexport function buildContext(input: ContextInput): TargetingContext {\n let path = \"\";\n const query: Record<string, string> = {};\n try {\n const u = new URL(input.url, \"http://localhost\");\n path = u.pathname;\n u.searchParams.forEach((v, k) => {\n query[k] = v;\n });\n } catch {\n path = input.url;\n }\n const device = input.device ?? (typeof navigator !== \"undefined\" ? detectDevice(navigator.userAgent, typeof window !== \"undefined\" ? window.innerWidth : 0) : { type: \"desktop\" });\n return {\n anonymousId: input.anonymousId,\n userId: input.userId ?? null,\n userAttributes: input.userAttributes,\n accountAttributes: input.accountAttributes,\n url: input.url,\n path,\n query,\n device,\n firstVisit: input.firstVisit,\n eventsSeen: new Set(input.eventsSeen),\n completedGuides: new Set(input.completedGuides),\n dismissedGuides: new Set(input.dismissedGuides),\n seenGuides: new Set(input.seenGuides),\n completedChecklists: new Set(input.completedChecklists),\n audienceIds: new Set(input.audienceIds),\n now: input.now ?? new Date(),\n environment: input.environment,\n locale: input.locale ?? (typeof navigator !== \"undefined\" ? navigator.language : undefined),\n platform: input.platform ?? \"web\",\n ...(input.screen !== undefined ? { screen: input.screen } : {}),\n ...(input.appVersion !== undefined ? { appVersion: input.appVersion } : {}),\n };\n}\n","import type { HeatmapPoint } from \"@guidelytech/shared\";\nimport { elementSelector } from \"./autocapture\";\n\n/** Points per `heatmap` event, and the JSON size at which a batch is sent early (properties cap at 8KB). */\nexport const HEATMAP_MAX_POINTS = 40;\nexport const HEATMAP_MAX_BYTES = 6000;\n/** Movement bins per batch before it is sent. */\nexport const HEATMAP_MAX_BINS = 60;\n\nconst r2 = (n: number) => Math.round(Math.min(1, Math.max(0, n)) * 100) / 100;\n\n/** One heatmap point: page coordinates, a stable selector and the position inside the element (0–1). */\nexport function heatmapPoint(el: Element, e: MouseEvent, rage: boolean): HeatmapPoint {\n const p: HeatmapPoint = { k: rage ? \"r\" : \"c\", x: Math.round(e.pageX ?? 0) || 0, y: Math.round(e.pageY ?? 0) || 0 };\n const s = elementSelector(el).slice(0, 120);\n if (s) p.s = s;\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n p.rx = r2((e.clientX - rect.left) / rect.width);\n p.ry = r2((e.clientY - rect.top) / rect.height);\n }\n return p;\n}\n\nconst selectors = new WeakMap<Element, string>();\nconst r1 = (n: number) => Math.round(Math.min(1, Math.max(0, n)) * 10) / 10;\n\n/**\n * Movement bin for a pointer sample: per element at 0.1 of the element box (selectors cached per\n * element), or a 16px page-grid cell for `html`/`body` and elements without a box or selector.\n */\nexport function movementBin(el: Element, e: MouseEvent): [string, HeatmapPoint] {\n const p: HeatmapPoint = { k: \"m\", x: Math.round(e.pageX ?? 0) || 0, y: Math.round(e.pageY ?? 0) || 0 };\n let s = /^(HTML|BODY)$/.test(el.tagName) ? \"\" : selectors.get(el);\n if (s === undefined) selectors.set(el, (s = elementSelector(el).slice(0, 120)));\n const rect = s ? el.getBoundingClientRect() : null;\n if (!rect || !(rect.width > 0 && rect.height > 0)) return [`${p.x >> 4},${p.y >> 4}`, p];\n p.s = s;\n p.rx = r1((e.clientX - rect.left) / rect.width);\n p.ry = r1((e.clientY - rect.top) / rect.height);\n return [`${s} ${p.rx},${p.ry}`, p];\n}\n\n/** Click positions and movement bins on the current page, sent as one `heatmap` event per batch. */\nexport class HeatmapBuffer {\n /** The page the buffered points belong to. */\n url = \"\";\n points: HeatmapPoint[] = [];\n private bins = new Map<string, HeatmapPoint>();\n private bytes = 0;\n\n /** Adds a click (`burst` > 0 marks it and the burst's previous clicks as rage); true when the batch is full. */\n add(url: string, point: HeatmapPoint, burst: number): boolean {\n this.url = url;\n for (let i = Math.max(0, this.points.length - burst + 1); i < this.points.length; i++) (this.points[i] as HeatmapPoint).k = \"r\";\n this.points.push(point);\n this.bytes += JSON.stringify(point).length + 1;\n return this.full();\n }\n\n /** Adds a movement sample to its bin (weight +1); true when the batch is full. */\n move(url: string, [key, point]: [string, HeatmapPoint]): boolean {\n this.url = url;\n const bin = this.bins.get(key);\n if (bin) bin.w = (bin.w ?? 1) + 1;\n else {\n this.bins.set(key, point);\n this.bytes += JSON.stringify(point).length + 8; // + room for \"w\"\n }\n return this.full();\n }\n\n private full(): boolean {\n return this.points.length >= HEATMAP_MAX_POINTS || this.bins.size > HEATMAP_MAX_BINS || this.bytes >= HEATMAP_MAX_BYTES;\n }\n\n /** Empties the buffer, returning what was in it (clicks first, then movement bins). */\n take(): { url: string; points: HeatmapPoint[] } | null {\n const points = [...this.points, ...this.bins.values()];\n this.points = [];\n this.bins = new Map();\n this.bytes = 0;\n return points.length ? { url: this.url, points } : null;\n }\n}\n","import { parseStack, type ExceptionProperties, type StackFrame } from \"@guidelytech/shared/runtime\";\n\n/** Byte budget for the `frames` property (the event's properties are capped at 8KB). */\nconst MAX_FRAMES_BYTES = 6000;\n\nfunction fitFrames(frames: StackFrame[]): StackFrame[] {\n const out = frames.slice(0, 30);\n while (out.length > 1 && JSON.stringify(out).length > MAX_FRAMES_BYTES) out.pop();\n return out;\n}\n\nfunction describe(value: unknown): string {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** Converts anything thrown into `exception` properties. */\nexport function exceptionFromError(error: unknown, source: string, handled: boolean, fallbackType = \"Error\"): ExceptionProperties {\n const isError = error instanceof Error || (!!error && typeof error === \"object\" && typeof (error as Error).message === \"string\" && typeof (error as Error).stack === \"string\");\n const e = error as Error;\n return {\n type: (isError && e.name) || fallbackType,\n message: (isError ? e.message : describe(error)).slice(0, 1000),\n frames: isError ? fitFrames(parseStack(e.stack)) : [],\n source,\n handled,\n };\n}\n\n/** `window` `error` event → exception; `null` for resource-load errors and opaque \"Script error.\" reports. */\nexport function errorEventToException(e: ErrorEvent): ExceptionProperties | null {\n const target = e.target as unknown;\n if (target && typeof Element !== \"undefined\" && target instanceof Element) return null;\n if (e.error != null) return exceptionFromError(e.error, \"onerror\", false);\n const message = e.message || \"\";\n if (!message || /^script error\\.?$/i.test(message.trim())) return null;\n const m = /^(?:Uncaught )?([A-Z]\\w*(?:Error|Exception)):\\s*([\\s\\S]*)$/.exec(message);\n return {\n type: m?.[1] ?? \"Error\",\n message: (m?.[2] ?? message).slice(0, 1000),\n frames: e.filename ? [{ file: e.filename.slice(0, 500), line: e.lineno || undefined, col: e.colno || undefined }] : [],\n source: \"onerror\",\n handled: false,\n };\n}\n\n/** `unhandledrejection` → exception (`UnhandledRejection` for non-Error reasons). */\nexport function rejectionToException(e: PromiseRejectionEvent): ExceptionProperties {\n return exceptionFromError(e.reason, \"unhandledrejection\", false, \"UnhandledRejection\");\n}\n\nconst GUIDELY_SCRIPT = /\\/guidely(-recorder)?(\\.min)?\\.js$/i;\n\n/** Errors raised by Guidely itself (\"[Guidely] …\" messages, or thrown from the script-tag bundle). */\nexport function isGuidelyException(props: ExceptionProperties): boolean {\n if (props.message.startsWith(\"[Guidely]\")) return true;\n const file = props.frames[0]?.file;\n if (!file) return false;\n try {\n return GUIDELY_SCRIPT.test(new URL(file).pathname);\n } catch {\n return GUIDELY_SCRIPT.test(file.replace(/[?#].*$/, \"\"));\n }\n}\n\n/** Per-page-load throttle: the same exception (type + message + top frame) at most `max` times. */\nexport class ExceptionThrottle {\n private seen = new Map<string, number>();\n\n constructor(private readonly max = 5) {}\n\n allow(props: ExceptionProperties): boolean {\n const top = props.frames[0];\n const key = `${props.type}|${props.message}|${top ? `${top.file}:${top.line}:${top.col}` : \"\"}`;\n const n = this.seen.get(key) ?? 0;\n if (n >= this.max) return false;\n if (this.seen.size > 500) this.seen.clear();\n this.seen.set(key, n + 1);\n return true;\n }\n}\n","type AnyFn = (...args: any[]) => void;\n\n/** Tiny typed event emitter. Listener errors are reported, never thrown into the caller. */\nexport class Emitter<Events extends { [K in keyof Events]: AnyFn }> {\n private listeners = new Map<keyof Events, Set<AnyFn>>();\n constructor(private readonly onError?: (err: unknown) => void) {}\n\n on<K extends keyof Events>(event: K, cb: Events[K]): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(cb);\n return () => this.off(event, cb);\n }\n\n off<K extends keyof Events>(event: K, cb: Events[K]): void {\n this.listeners.get(event)?.delete(cb);\n }\n\n emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const cb of Array.from(set)) {\n try {\n cb(...args);\n } catch (err) {\n this.onError?.(err);\n }\n }\n }\n\n clear(): void {\n this.listeners.clear();\n }\n}\n","import type { FrequencyConfig, GuideThrottlingSettings, PublishedGuide } from \"@guidelytech/shared\";\n\n/** Per-guide state kept locally and merged with the server's `IdentifyResponse.guideState`. */\nexport interface GuideLocalState {\n impressions: number;\n completedAt?: string | null;\n dismissedAt?: string | null;\n lastShownAt?: string | null;\n /** Last step reached in a multi-step flow (local only), so the messenger can offer to resume it. */\n lastStepId?: string | null;\n}\n\nconst HOUR = 3600 * 1000;\n\n/**\n * Pure frequency evaluation. `shownThisSession` comes from session storage.\n * - `once`: a single impression ever (unless `reshowAfterDismiss` and it was only dismissed).\n * - `once_per_session`: at most once per browser session.\n * - `every_time`: on every trigger (still blocked by completion/dismissal rules below).\n * - `interval`: at most once every `intervalHours`.\n * `maxImpressions` caps total impressions; dismissal blocks re-showing unless `reshowAfterDismiss`\n * (then `cooldownHours` must have elapsed); completion blocks unless mode is `every_time`.\n */\nexport function isFrequencyEligible(freq: FrequencyConfig, state: GuideLocalState | undefined, shownThisSession: boolean, now: number = Date.now()): boolean {\n const s = state ?? { impressions: 0 };\n if (freq.maxImpressions != null && s.impressions >= freq.maxImpressions) return false;\n if (s.completedAt && freq.mode !== \"every_time\") return false;\n if (s.dismissedAt) {\n if (!freq.reshowAfterDismiss) return false;\n if (freq.cooldownHours > 0 && now - Date.parse(s.dismissedAt) < freq.cooldownHours * HOUR) return false;\n }\n switch (freq.mode) {\n case \"once\":\n return s.impressions === 0 || (!!s.dismissedAt && freq.reshowAfterDismiss);\n case \"once_per_session\":\n return !shownThisSession;\n case \"interval\": {\n if (!s.lastShownAt) return true;\n const hours = freq.intervalHours ?? 24;\n return now - Date.parse(s.lastShownAt) >= hours * HOUR;\n }\n case \"every_time\":\n default:\n return true;\n }\n}\n\n/**\n * Exclusive guides (flows, modals, tooltips, announcements, surveys) run one at a time.\n * Banners, checklists and hotspot-only tooltips can coexist with an active flow.\n */\nexport function isExclusiveGuide(guide: PublishedGuide): boolean {\n if (guide.kind === \"banner\" || guide.kind === \"checklist\") return false;\n const steps = guide.config.steps;\n if (steps.length > 0 && steps.every((s) => s.type === \"hotspot\" || s.type === \"banner\")) return false;\n return true;\n}\n\n/** Is `a` mutually exclusive with `b` (by id or key, in either direction)? */\nexport function areMutuallyExclusive(a: PublishedGuide, b: PublishedGuide): boolean {\n const la = a.config.frequency.mutuallyExclusiveWith;\n const lb = b.config.frequency.mutuallyExclusiveWith;\n return la.includes(b.id) || la.includes(b.key) || lb.includes(a.id) || lb.includes(a.key);\n}\n\n/**\n * Scheduling window: the guide's `schedule` (any kind) and, for surveys, `survey.startAt` / `endAt`.\n * Unparsable dates are ignored.\n */\nexport function isWithinSchedule(guide: Pick<PublishedGuide, \"config\">, now: number = Date.now()): boolean {\n for (const w of [guide.config.schedule, guide.config.survey]) {\n if (!w) continue;\n if (w.startAt && now < Date.parse(w.startAt)) return false;\n if (w.endAt && now > Date.parse(w.endAt)) return false;\n }\n return true;\n}\n\nconst MINUTE = 60 * 1000;\n\n/**\n * Does showing this guide automatically count toward (and get limited by) the project's guide\n * throttling? Only exclusive guides (flows, modals, tooltips, announcements, surveys) interrupt;\n * banners, checklists and hotspot-only guides never count, nor does a guide set to ignore throttling.\n * Guides started by the visitor or the app (`startGuide`, buttons, Help) are never throttled.\n */\nexport function countsTowardThrottle(guide: PublishedGuide): boolean {\n return isExclusiveGuide(guide) && !guide.config.frequency.ignoreThrottling;\n}\n\n/**\n * Pure throttling check. `launches` = ISO times of this visitor's earlier automatic launches of\n * counted guides (any order). Disabled or missing settings never throttle.\n */\nexport function isThrottleEligible(settings: GuideThrottlingSettings | null | undefined, launches: readonly string[], now: number = Date.now()): boolean {\n if (!settings || !settings.enabled) return true;\n const times = launches.map((l) => Date.parse(l)).filter((t) => !Number.isNaN(t));\n const windowMs = Math.max(1, settings.windowHours) * HOUR;\n if (times.filter((t) => now - t < windowMs).length >= Math.max(1, settings.maxGuides)) return false;\n if (settings.minGapMinutes > 0 && times.some((t) => now - t < settings.minGapMinutes * MINUTE)) return false;\n return true;\n}\n\n/** Launch times worth keeping: those still inside the window or the minimum gap (at most 100). */\nexport function pruneLaunches(launches: readonly string[], settings: GuideThrottlingSettings | null | undefined, now: number = Date.now()): string[] {\n const keepMs = Math.max(settings?.windowHours ?? 24, 1) * HOUR + (settings?.minGapMinutes ?? 0) * MINUTE;\n return launches.filter((l) => { const t = Date.parse(l); return !Number.isNaN(t) && now - t < keepMs; }).slice(-100);\n}\n\n/**\n * A checklist's dismissal after merging server state. A local dismissal normally wins (it may not have\n * synced yet), but when the server reports a reset this device hasn't applied, the server's value wins:\n * null, or a dismissal made on another device after the reset. Compared as tokens, not times, so a\n * skewed device clock can't keep a reset dismissal.\n */\nexport function dismissedAfterMerge(local: { dismissedAt?: string | null; dismissResetAt?: string | null } | undefined, server: { dismissedAt?: string | null; dismissResetAt?: string | null }): string | null {\n if (server.dismissResetAt && server.dismissResetAt !== local?.dismissResetAt) return server.dismissedAt ?? null;\n return local?.dismissedAt ?? server.dismissedAt ?? null;\n}\n","import type {\n ConversationLookupResponse,\n FeedbackUpdatesResponse,\n FileComplaintResponse,\n PublicFeedbackList,\n PublicFeedbackRequest,\n PublicFeedbackRequestDetail,\n ConversationMessagesResponse,\n MessengerConversation,\n MessengerPageContent,\n MessengerMessage,\n ResourceCenterArticle,\n SdkArticlesResponse,\n SdkHowTo,\n SdkHowTosResponse,\n StartConversationResponse,\n} from \"@guidelytech/shared\";\nimport type { MessengerApi, MessengerStreamHandlers } from \"@guidelytech/guide-runtime/messenger\";\nimport type { Api } from \"./http\";\nimport { KEYS, readJson, writeJson, type KeyValueStore } from \"./storage\";\n\ninterface StoredConversation {\n id: string;\n token: string;\n}\n\nconst MAX_STORED = 50;\nconst TOKEN_HEADER = \"X-Guidely-Conversation\";\n\nexport interface MessengerTransportOptions {\n api: Api;\n store: KeyValueStore;\n projectId: string;\n anonymousId: () => string;\n userId: () => string | null;\n /** Page URL to attach to messages (omitted when URL collection is off). */\n pageUrl: () => string | undefined;\n /** The visitor's resource-center language when it isn't the default (articles are fetched in it). */\n locale?: () => string | null;\n}\n\n/** The path of a page URL (plus a `#/` route), without origin or query: all how-to matching needs. */\nexport function pagePath(url: string | undefined): string | undefined {\n if (!url) return undefined;\n try {\n const u = new URL(url);\n return (u.pathname + (/^#!?\\//.test(u.hash) ? u.hash.split(\"?\")[0] : \"\")).slice(0, 2000);\n } catch {\n return undefined;\n }\n}\n\n/** Conversation tokens this browser holds (the only way to read a conversation). */\nexport function storedConversations(store: KeyValueStore, projectId: string): StoredConversation[] {\n const list = readJson<StoredConversation[]>(store, KEYS.conversations(projectId), []);\n return Array.isArray(list) ? list.filter((c) => c && typeof c.id === \"string\" && typeof c.token === \"string\") : [];\n}\n\nexport function forgetConversations(store: KeyValueStore, projectId: string) {\n store.remove(KEYS.conversations(projectId));\n}\n\nclass HttpError extends Error {\n constructor(\n readonly status: number,\n message?: string,\n ) {\n super(message || `Request failed (${status})`);\n }\n}\n\n/** The server's message for a failed request (`{ error: { message } }`), when it sent one. */\nfunction serverMessage(data: unknown): string | undefined {\n const m = (data as { error?: { message?: unknown } } | null)?.error?.message;\n return typeof m === \"string\" && m !== \"Request validation failed\" ? m : undefined;\n}\n\n/** The messenger's server access over the public SDK API. */\nexport function createMessengerTransport(opts: MessengerTransportOptions): MessengerApi {\n const { api, store, projectId } = opts;\n const tokenFor = (id: string) => storedConversations(store, projectId).find((c) => c.id === id)?.token ?? \"\";\n const remember = (id: string, token: string) => {\n const rest = storedConversations(store, projectId).filter((c) => c.id !== id);\n writeJson(store, KEYS.conversations(projectId), [{ id, token }, ...rest].slice(0, MAX_STORED));\n };\n const forget = (id: string) => writeJson(store, KEYS.conversations(projectId), storedConversations(store, projectId).filter((c) => c.id !== id));\n\n /** Dispatches either SSE events or a JSON answer to the stream handlers. */\n async function exchange(path: string, body: unknown, headers: Record<string, string>, h: MessengerStreamHandlers, onStarted?: (r: StartConversationResponse) => void) {\n let finished = false;\n const res = await api.stream<StartConversationResponse | ConversationMessagesResponse>(\n path,\n body,\n (event, data) => {\n if (event === \"conversation\") {\n const d = data as StartConversationResponse;\n onStarted?.(d);\n h.onConversation?.(d.conversation);\n d.messages.forEach((m) => h.onMessage(m));\n } else if (event === \"message\") h.onMessage(data as MessengerMessage);\n else if (event === \"delta\") {\n const d = data as { messageId: string; text: string };\n h.onDelta(d.messageId, d.text);\n } else if (event === \"done\") {\n const d = data as { message: MessengerMessage | null; conversation: MessengerConversation };\n finished = true;\n h.onDone(d.message, d.conversation);\n } else if (event === \"error\") h.onError((data as { message?: string })?.message ?? \"Something went wrong\");\n },\n headers,\n );\n if (!res.ok) throw new HttpError(res.status);\n if (res.data) {\n // JSON answer (no Scout reply): the stored messages and the conversation.\n const d = res.data;\n if (\"token\" in d) {\n onStarted?.(d);\n h.onConversation?.(d.conversation);\n }\n d.messages.forEach((m) => h.onMessage(m));\n h.onDone(d.messages.at(-1) ?? null, d.conversation);\n } else if (!finished) h.onError(\"The reply was interrupted\");\n }\n\n /** A feedback (Ideas) call: the visitor goes in the body; failures carry the server's message. */\n async function feedback<T>(path: string, body: object, fallback: string): Promise<T> {\n const res = await api.post<T>(`/feedback${path}`, { ...body, anonymousId: opts.anonymousId(), userId: opts.userId() });\n if (!res.ok || !res.data) {\n if (res.status === 429) throw new HttpError(429, \"You're doing that a lot. Please try again in a minute.\");\n throw new HttpError(res.status, serverMessage(res.data) ?? fallback);\n }\n return res.data;\n }\n\n return {\n async listConversations() {\n const tokens = storedConversations(store, projectId).map((c) => c.token);\n if (!tokens.length) return [];\n const res = await api.post<ConversationLookupResponse>(\"/conversations/lookup\", { tokens });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n // Drop tokens the server no longer knows (deleted by retention).\n const known = new Set(res.data.conversations.map((c) => c.id));\n for (const c of storedConversations(store, projectId)) if (!known.has(c.id)) forget(c.id);\n return res.data.conversations.map(({ token: _token, ...c }) => c);\n },\n async loadMessages(id, since) {\n const res = await api.get<ConversationMessagesResponse>(`/conversations/${encodeURIComponent(id)}/messages`, { params: { since: since ?? undefined }, headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n start(text, h) {\n return exchange(\"/conversations\", { anonymousId: opts.anonymousId(), userId: opts.userId(), message: text, pageUrl: opts.pageUrl() }, {}, h, (r) => remember(r.conversation.id, r.token));\n },\n send(id, text, h) {\n return exchange(`/conversations/${encodeURIComponent(id)}/messages`, { message: text, pageUrl: opts.pageUrl() }, { [TOKEN_HEADER]: tokenFor(id) }, h);\n },\n async handoff(id) {\n const res = await api.post<ConversationMessagesResponse>(`/conversations/${encodeURIComponent(id)}/handoff`, {}, { headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async rate(id, rating) {\n const res = await api.post(`/conversations/${encodeURIComponent(id)}/rating`, { rating }, { headers: { [TOKEN_HEADER]: tokenFor(id) } });\n if (!res.ok) throw new HttpError(res.status);\n },\n async listArticles() {\n const res = await api.get<SdkArticlesResponse>(\"/articles\");\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async getArticle(id) {\n const locale = opts.locale?.();\n const res = await api.get<{ article: ResourceCenterArticle }>(`/articles/${encodeURIComponent(id)}`, locale ? { params: { locale } } : undefined);\n return res.ok && res.data ? res.data.article : null;\n },\n async fileComplaint(input) {\n const headers: Record<string, string> = input.conversationId ? { [TOKEN_HEADER]: tokenFor(input.conversationId) } : {};\n const res = await api.post<FileComplaintResponse>(\"/complaints\", { ...input, anonymousId: opts.anonymousId(), userId: opts.userId(), pageUrl: opts.pageUrl() }, { headers });\n if (!res.ok || !res.data || !(\"complaint\" in res.data)) {\n if (res.status === 429) throw new HttpError(429, \"You've filed several complaints just now. Please try again later.\");\n throw new HttpError(res.status, serverMessage(res.data) ?? \"Your complaint couldn't be sent. Please try again.\");\n }\n // A conversation started for the complaint: keep its token so the person can read the replies.\n if (res.data.token) remember(res.data.conversation.id, res.data.token);\n return res.data;\n },\n async pageContent(path) {\n // Only the path is sent (never the query or fragment) and nothing is stored: it picks what to suggest.\n const res = await api.post<MessengerPageContent>(\"/messenger/page\", { anonymousId: opts.anonymousId(), userId: opts.userId(), path: path.split(/[?#]/)[0] || \"/\" });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async searchArticles(q) {\n const res = await api.get<{ articles: ResourceCenterArticle[] }>(\"/resource-center/search\", { params: { q } });\n return res.ok && res.data ? res.data.articles : [];\n },\n async listHowTos() {\n const res = await api.get<SdkHowTosResponse>(\"/how-tos\", { params: { url: pagePath(opts.pageUrl()) } });\n if (!res.ok || !res.data) throw new HttpError(res.status);\n return res.data;\n },\n async getHowTo(id) {\n const res = await api.get<{ howTo: SdkHowTo }>(`/how-tos/${encodeURIComponent(id)}`);\n return res.ok && res.data ? res.data.howTo : null;\n },\n\n // Ideas (feature requests). The visitor's ids go in every body; the server decides what they may do.\n listIdeas: (query) => feedback<PublicFeedbackList>(\"/requests/query\", query, \"Ideas couldn't be loaded.\"),\n getIdea: (id) => feedback<PublicFeedbackRequestDetail>(`/requests/${encodeURIComponent(id)}/view`, {}, \"This idea couldn't be loaded.\"),\n submitIdea: (input) => feedback<PublicFeedbackRequestDetail>(\"/requests\", { ...input, pageUrl: opts.pageUrl() }, \"Your idea couldn't be sent. Please try again.\"),\n voteIdea: (id, vote) => feedback<PublicFeedbackRequest>(`/requests/${encodeURIComponent(id)}/vote`, vote, \"Your vote couldn't be saved.\"),\n unvoteIdea: (id) => feedback<PublicFeedbackRequest>(`/requests/${encodeURIComponent(id)}/unvote`, {}, \"Your vote couldn't be removed.\"),\n followIdea: (id, follow) => feedback<PublicFeedbackRequest>(`/requests/${encodeURIComponent(id)}/follow`, { follow }, \"That didn't work. Please try again.\"),\n commentIdea: (id, body) => feedback<PublicFeedbackRequestDetail>(`/requests/${encodeURIComponent(id)}/comments`, { body }, \"Your comment couldn't be posted.\"),\n similarIdeas: async (title) => (await feedback<{ requests: PublicFeedbackRequest[] }>(\"/similar\", { title }, \"Similar ideas couldn't be loaded.\")).requests ?? [],\n ideaUpdates: () => feedback<FeedbackUpdatesResponse>(\"/updates\", {}, \"Updates couldn't be loaded.\"),\n markIdeaUpdatesRead: (ids) => feedback<FeedbackUpdatesResponse>(\"/updates/read\", ids ? { ids } : {}, \"Updates couldn't be marked read.\"),\n ideaPortalLink: async () => (await feedback<{ url: string }>(\"/portal-link\", {}, \"The feedback portal couldn't be opened.\")).url,\n };\n}\n","import type { PublishedGuide } from \"@guidelytech/shared\";\nimport { firstNameFromTraits } from \"@guidelytech/shared/runtime\";\nimport { urlMatches } from \"@guidelytech/guide-runtime\";\nimport type { MessengerChecklistProgress, MessengerNewsItem, MessengerResumeGuide, MessengerVisitor } from \"@guidelytech/guide-runtime/messenger\";\nimport { isWithinSchedule } from \"./frequency\";\nimport type { PersistedState } from \"./types\";\n\n/** Guide kinds the messenger offers to start for a page (announcements go to News instead). */\nconst PAGE_GUIDE_KINDS = new Set([\"flow\", \"tooltip\", \"modal\"]);\n/** URL patterns that match every page say nothing about a page. */\nconst CATCH_ALL = new Set([\"\", \"*\", \"**\", \"/*\", \"/**\", \"/\"]);\nconst RESUME_WITHIN_MS = 14 * 86_400_000;\nconst NEWS_WITHIN_MS = 90 * 86_400_000;\nconst MAX_NEWS = 10;\n\nexport interface VisitorInput {\n guides: PublishedGuide[];\n state: PersistedState;\n traits: Record<string, unknown> | undefined;\n /** `location.href`. */\n url: string;\n /** Full targeting for the current page (URL patterns, schedule, rules). */\n isTargeted: (guide: PublishedGuide) => boolean;\n /** Schedule and rules only: for content that isn't tied to the current page (news, progress). */\n isAudienceTargeted: (guide: PublishedGuide) => boolean;\n /** Announcement ids already seen in the News tab. */\n newsSeen: readonly string[];\n now?: number;\n}\n\nfunction pathOf(url: string): string | null {\n try {\n return new URL(url, \"http://x.invalid\").pathname || \"/\";\n } catch {\n return null;\n }\n}\n\n/** True when the guide names this page explicitly (URL patterns, a URL trigger, or its first step's page). */\nexport function targetsPage(guide: PublishedGuide, url: string): boolean {\n const c = guide.config;\n const checks: string[] = [...c.urlPatterns, ...(c.trigger.urlPattern ? [c.trigger.urlPattern] : []), ...(c.trigger.type === \"url_match\" && c.trigger.value ? [c.trigger.value] : []), ...(c.steps[0]?.url ? [c.steps[0].url] : [])];\n const specific = checks.filter((p) => !CATCH_ALL.has(p.trim()));\n // Every page reference must match (they are all requirements), and at least one must be specific.\n return specific.length > 0 && checks.every((p) => urlMatches(p, url));\n}\n\n/** Rich text from a guide step as plain text for a news card. */\nexport function plainText(html: string, max = 280): string {\n const text = html\n .replace(/<(br|\\/p|\\/div|\\/li|\\/h[1-6])\\s*\\/?>/gi, \" \")\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&/g, \"&\")\n .replace(/\\s+/g, \" \")\n .trim();\n return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;\n}\n\n/** Everything the messenger personalises from: name, page guides, progress and announcements. */\nexport function buildMessengerVisitor(input: VisitorInput): MessengerVisitor {\n const now = input.now ?? Date.now();\n const { guides, state } = input;\n const done = (g: PublishedGuide) => !!state.guides[g.id]?.completedAt;\n\n const pageGuides = guides\n .filter((g) => PAGE_GUIDE_KINDS.has(g.kind) && g.config.steps.length > 0 && !done(g) && targetsPage(g, input.url) && input.isTargeted(g))\n .slice(0, 3)\n .map((g) => ({ id: g.id, key: g.key, name: g.name, kind: g.kind }));\n\n let resumeGuide: MessengerResumeGuide | null = null;\n let resumeAt = 0;\n for (const g of guides) {\n const s = state.guides[g.id];\n if (g.kind !== \"flow\" || !s?.lastStepId || s.completedAt || g.config.steps.length < 2) continue;\n const at = Date.parse(s.lastShownAt ?? \"\");\n if (!Number.isFinite(at) || now - at > RESUME_WITHIN_MS || at <= resumeAt) continue;\n const stepIndex = g.config.steps.findIndex((st) => st.id === s.lastStepId);\n // Only once they got past the first step; the step must still exist in the live version. Auto-show\n // targeting (\"first visit\") doesn't apply: they already started it, and resuming starts it by hand.\n if (stepIndex < 1 || !isWithinSchedule(g)) continue;\n resumeGuide = { id: g.id, name: g.name, stepId: s.lastStepId, stepIndex, stepCount: g.config.steps.length };\n resumeAt = at;\n }\n\n let checklist: MessengerChecklistProgress | null = null;\n for (const g of guides) {\n const tasks = g.config.checklist?.tasks;\n if (g.kind !== \"checklist\" || !tasks?.length) continue;\n const p = state.checklists[g.id];\n if (p?.completedAt || p?.dismissedAt || !input.isAudienceTargeted(g)) continue;\n const completed = new Set(p?.completedTaskIds ?? []);\n const doneCount = tasks.filter((t) => completed.has(t.id)).length;\n if (doneCount >= tasks.length) continue;\n checklist = { id: g.id, name: g.name, done: doneCount, total: tasks.length, nextTask: tasks.find((t) => !completed.has(t.id))?.title ?? null };\n break;\n }\n\n const seen = new Set(input.newsSeen);\n const news: MessengerNewsItem[] = guides\n .filter((g) => g.kind === \"announcement\" && g.config.steps.length > 0 && now - Date.parse(g.publishedAt) <= NEWS_WITHIN_MS && input.isAudienceTargeted(g))\n .sort((a, b) => b.publishedAt.localeCompare(a.publishedAt))\n .slice(0, MAX_NEWS)\n .map((g) => {\n const step = g.config.steps[0]!;\n return {\n id: g.id,\n key: g.key,\n title: step.title || g.name,\n body: plainText(step.body ?? \"\"),\n imageUrl: step.imageUrl || null,\n publishedAt: g.publishedAt,\n // Read once opened in the News tab, or once the announcement itself was shown.\n unread: !seen.has(g.id) && !(state.guides[g.id]?.impressions ?? 0),\n };\n });\n\n return { firstName: firstNameFromTraits(input.traits), path: pathOf(input.url), pageGuides, resumeGuide, checklist, news };\n}\n","type Listener = (url: string) => void;\n\ninterface PatchedHistory extends History {\n __guidelyPatched?: { count: number; pushState: History[\"pushState\"]; replaceState: History[\"replaceState\"] };\n}\n\n/**\n * Detects SPA navigation: patches `history.pushState`/`replaceState` (reference counted, restored\n * on the last unwatch), listens to `popstate` and `hashchange`, and debounces into one callback.\n */\nexport function watchNavigation(listener: Listener, debounceMs = 50): () => void {\n if (typeof window === \"undefined\") return () => {};\n const win = window;\n const hist = win.history as PatchedHistory;\n let last = win.location.href;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const check = () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const href = win.location.href;\n if (href !== last) {\n last = href;\n listener(href);\n }\n }, debounceMs);\n };\n if (!hist.__guidelyPatched) {\n const pushState = hist.pushState;\n const replaceState = hist.replaceState;\n hist.__guidelyPatched = { count: 0, pushState, replaceState };\n hist.pushState = function (this: History, ...args: Parameters<History[\"pushState\"]>) {\n const r = pushState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n hist.replaceState = function (this: History, ...args: Parameters<History[\"replaceState\"]>) {\n const r = replaceState.apply(this, args);\n win.dispatchEvent(new Event(\"guidely:navigate\"));\n return r;\n };\n }\n hist.__guidelyPatched.count += 1;\n win.addEventListener(\"guidely:navigate\", check);\n win.addEventListener(\"popstate\", check);\n win.addEventListener(\"hashchange\", check);\n return () => {\n if (timer) clearTimeout(timer);\n win.removeEventListener(\"guidely:navigate\", check);\n win.removeEventListener(\"popstate\", check);\n win.removeEventListener(\"hashchange\", check);\n const p = hist.__guidelyPatched;\n if (p) {\n p.count -= 1;\n if (p.count <= 0) {\n hist.pushState = p.pushState;\n hist.replaceState = p.replaceState;\n delete hist.__guidelyPatched;\n }\n }\n };\n}\n","/**\n * Page URLs for apps that are not served over http(s): Electron and other desktop shells load\n * `file:///…/index.html#/settings` or a custom protocol such as `app://bundle/index.html`. Raw, those\n * URLs make useless page paths (`/Users/ada/Applications/Acme.app/Contents/Resources/app.asar/index.html`)\n * that differ per machine, so guide URL patterns and page analytics could never match them.\n *\n * `normalizeAppUrl` maps them to stable app-relative URLs: `<scheme>://<host or \"app\"><route>` where the\n * route is the hash route when the app uses hash routing (`#/settings` → `/settings`), otherwise the\n * page file relative to the app (`index.html` → `/`, `settings.html` → `/settings`, a custom\n * protocol's own path otherwise). Query strings are kept. http(s) and unparseable URLs are unchanged.\n *\n * file:///C:/Acme/resources/app.asar/dist/index.html#/deals/42?tab=notes → file://app/deals/42?tab=notes\n * file:///Users/ada/Acme.app/Contents/Resources/app/settings.html → file://app/settings\n * app://bundle/index.html#!/inbox → app://bundle/inbox\n * app://bundle/deals/42 → app://bundle/deals/42\n */\nconst WEB_SCHEMES = new Set([\"http\", \"https\", \"about\", \"data\", \"blob\", \"javascript\"]);\n\nfunction appScheme(href: string): { u: URL; scheme: string } | null {\n let u: URL;\n try {\n u = new URL(href);\n } catch {\n return null;\n }\n const scheme = u.protocol.replace(/:$/, \"\").toLowerCase();\n return WEB_SCHEMES.has(scheme) ? null : { u, scheme };\n}\n\nexport function normalizeAppUrl(href: string): string {\n const app = appScheme(href);\n if (!app) return href;\n const { u, scheme } = app;\n const host = scheme === \"file\" ? \"app\" : u.host || \"app\";\n const hash = /^#!?(\\/.*)$/.exec(u.hash);\n if (hash) {\n // Hash routing: the route (with its own ?query) is the page.\n const route = hash[1]!;\n return `${scheme}://${host}${route.startsWith(\"/\") ? route : `/${route}`}`;\n }\n let path = safeDecode(u.pathname);\n if (scheme === \"file\" || /\\.html?$/i.test(path)) {\n // A page file: its name without the extension, `index` being the root.\n const file = path.split(\"/\").filter(Boolean).pop() ?? \"\";\n const name = file.replace(/\\.html?$/i, \"\");\n path = !name || name.toLowerCase() === \"index\" ? \"/\" : `/${name}`;\n }\n if (!path.startsWith(\"/\")) path = `/${path}`;\n return `${scheme}://${host}${path}${u.search}`;\n}\n\nfunction safeDecode(s: string): string {\n try {\n return decodeURI(s);\n } catch {\n return s;\n }\n}\n\n/** True for desktop-shell URLs (`file:`, custom protocols such as `app:`), which {@link normalizeAppUrl} makes app-relative. */\nexport function isAppUrl(href: string): boolean {\n return appScheme(href) !== null;\n}\n","/** What `page_leave` reports for the page being left. */\nexport interface PageLeaveInfo {\n url: string;\n /** Time the page was visible (pauses while `document.hidden`). */\n durationMs: number;\n /** Furthest point scrolled to, as a percentage (0–100) of the page height. */\n scrollDepth: number;\n}\n\n/** Current scroll depth (0–100): the bottom of the viewport relative to the page height. */\nexport function scrollDepth(): number {\n const de = document.documentElement;\n const height = Math.max(de?.scrollHeight || 0, document.body?.scrollHeight || 0);\n const view = window.innerHeight || de?.clientHeight || 0;\n if (height <= 0 || height <= view) return 100;\n const y = window.scrollY || de?.scrollTop || 0;\n return Math.max(0, Math.min(100, Math.round(((y + view) / height) * 100)));\n}\n\n/** Tracks visible time and maximum scroll depth of the current page (for `page_leave`). */\nexport class PageTracker {\n url = \"\";\n private visibleMs = 0;\n private visibleSince: number | null = null;\n private maxScroll = 0;\n\n /** Starts measuring a new page. */\n start(url: string, now = Date.now()): void {\n this.url = url;\n this.visibleMs = 0;\n this.visibleSince = typeof document !== \"undefined\" && document.visibilityState === \"hidden\" ? null : now;\n this.maxScroll = 0;\n this.measureScroll();\n }\n\n /** Pauses / resumes the visible-time clock. */\n setHidden(hidden: boolean, now = Date.now()): void {\n if (hidden && this.visibleSince !== null) {\n this.visibleMs += Math.max(0, now - this.visibleSince);\n this.visibleSince = null;\n } else if (!hidden && this.visibleSince === null) this.visibleSince = now;\n }\n\n measureScroll(): void {\n try {\n this.maxScroll = Math.max(this.maxScroll, scrollDepth());\n } catch {\n /* no layout */\n }\n }\n\n /** Final numbers for the current page. */\n leave(now = Date.now()): PageLeaveInfo {\n this.measureScroll();\n const running = this.visibleSince !== null ? Math.max(0, now - this.visibleSince) : 0;\n return { url: this.url, durationMs: Math.round(this.visibleMs + running), scrollDepth: this.maxScroll };\n }\n}\n","/**\n * In-app recruitment for Guidely prototype tests (Validate). A guide button that opens a Guidely test URL\n * (`<apiOrigin>/validate/<token>`, same origin as the SDK's API) shows the test in a full-screen overlay\n * iframe instead of navigating away. Attribution (public key, anonymous id, user id) goes in the URL\n * fragment, so it never reaches servers, proxies or logs; the test page reads and clears it.\n *\n * The overlay is a modal dialog: focus moves into it and is trapped between the close button and the\n * test frame, Escape closes it, and it closes when the test page posts `{ type: \"guidely:prototype:close\" }`.\n */\n\nexport const PROTOTYPE_CLOSE_MESSAGE = \"guidely:prototype:close\";\nconst TOKEN = /^[A-Za-z0-9_-]{16,64}$/;\nconst OVERLAY_ATTR = \"data-guidely-prototype-overlay\";\n\n/**\n * The test URL for a full test URL or a bare token, when it points at this Guidely deployment's\n * `/validate/<token>` page; null for anything else (other origins and paths keep their normal behaviour).\n */\nexport function matchPrototypeTestUrl(urlOrToken: string, apiUrl: string): URL | null {\n const value = (urlOrToken || \"\").trim();\n let api: URL;\n try {\n api = new URL(apiUrl);\n } catch {\n return null;\n }\n if (TOKEN.test(value)) return new URL(`/validate/${value}`, api.origin);\n let url: URL;\n try {\n url = new URL(value, typeof location !== \"undefined\" ? location.href : api.origin);\n } catch {\n return null;\n }\n if (url.origin !== api.origin) return null;\n const m = /^\\/validate\\/([^/]+)\\/?$/.exec(url.pathname);\n if (!m || !TOKEN.test(m[1]!)) return null;\n return new URL(`/validate/${m[1]}`, api.origin);\n}\n\nexport interface PrototypeOverlayOptions {\n /** Environment public key, so the test can attribute the session to the end user. */\n key: string;\n anonymousId?: string | null;\n userId?: string | null;\n zIndex?: number;\n onClose?: () => void;\n}\n\nexport interface PrototypeOverlay {\n element: HTMLElement;\n close: () => void;\n}\n\nlet current: PrototypeOverlay | null = null;\n\n/** Opens the test in a full-screen overlay (replacing one already open). */\nexport function openPrototypeOverlay(testUrl: URL, opts: PrototypeOverlayOptions): PrototypeOverlay {\n current?.close();\n const doc = document;\n const previous = doc.activeElement as HTMLElement | null;\n const src = new URL(testUrl.href);\n const hash = new URLSearchParams();\n hash.set(\"key\", opts.key);\n if (opts.anonymousId) hash.set(\"anon\", opts.anonymousId);\n if (opts.userId) hash.set(\"uid\", opts.userId);\n src.hash = hash.toString();\n\n const root = doc.createElement(\"div\");\n root.setAttribute(OVERLAY_ATTR, \"\");\n root.setAttribute(\"role\", \"dialog\");\n root.setAttribute(\"aria-modal\", \"true\");\n root.setAttribute(\"aria-label\", \"Prototype test\");\n root.style.cssText = `position:fixed;inset:0;z-index:${opts.zIndex ?? 2147483646};background:rgba(15,23,42,.55);display:flex;align-items:stretch;justify-content:center;padding:0;margin:0;`;\n\n const frame = doc.createElement(\"iframe\");\n frame.src = src.toString();\n frame.title = \"Prototype test\";\n frame.setAttribute(\"allow\", \"fullscreen\");\n frame.setAttribute(\"referrerpolicy\", \"no-referrer\");\n frame.style.cssText = \"border:0;width:100%;height:100%;background:#fff;display:block;\";\n\n const close = doc.createElement(\"button\");\n close.type = \"button\";\n close.setAttribute(\"aria-label\", \"Close prototype test\");\n close.textContent = \"×\";\n close.style.cssText =\n \"position:absolute;top:10px;right:10px;width:36px;height:36px;border-radius:999px;border:0;background:rgba(15,23,42,.75);color:#fff;font:600 22px/36px system-ui,sans-serif;text-align:center;cursor:pointer;padding:0;z-index:1;\";\n\n root.append(frame, close);\n const overflow = doc.documentElement.style.overflow;\n doc.documentElement.style.overflow = \"hidden\";\n\n let closed = false;\n const shut = () => {\n if (closed) return;\n closed = true;\n window.removeEventListener(\"message\", onMessage);\n doc.removeEventListener(\"keydown\", onKey, true);\n doc.removeEventListener(\"focusin\", onFocus, true);\n root.remove();\n doc.documentElement.style.overflow = overflow;\n if (current === overlay) current = null;\n try {\n previous?.focus?.();\n } catch {\n /* the element may be gone */\n }\n opts.onClose?.();\n };\n const onMessage = (e: MessageEvent) => {\n if (e.origin !== testUrl.origin || e.source !== frame.contentWindow) return;\n const data = e.data as { type?: unknown } | null;\n if (data && typeof data === \"object\" && data.type === PROTOTYPE_CLOSE_MESSAGE) shut();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n shut();\n } else if (e.key === \"Tab\") {\n // Two stops: the test frame and the close button.\n e.preventDefault();\n (doc.activeElement === close ? frame : close).focus();\n }\n };\n // Focus leaving the frame for the page behind (Tab out of the iframe) comes back to the dialog.\n const onFocus = (e: FocusEvent) => {\n if (!root.contains(e.target as Node)) close.focus();\n };\n close.addEventListener(\"click\", shut);\n window.addEventListener(\"message\", onMessage);\n doc.addEventListener(\"keydown\", onKey, true);\n doc.addEventListener(\"focusin\", onFocus, true);\n doc.body.appendChild(root);\n frame.focus();\n\n const overlay: PrototypeOverlay = { element: root, close: shut };\n current = overlay;\n return overlay;\n}\n","import type { SdkEvent } from \"@guidelytech/shared\";\nimport type { ServerHealth } from \"./health\";\nimport { backoffMs } from \"./http\";\nimport { readJson, writeJson, type KeyValueStore } from \"./storage\";\n\nexport interface EventQueueOptions {\n store: KeyValueStore;\n storageKey: string;\n /** Sends one batch. Resolve `{ ok: true }` on success, `{ ok: false, retry }` otherwise. */\n send: (events: SdkEvent[]) => Promise<{ ok: boolean; retry?: boolean }>;\n /** Synchronous best-effort send used on page hide. */\n beacon?: (events: SdkEvent[]) => boolean;\n /** Should events be flushed right now? (analytics enabled + consent granted). */\n enabled: () => boolean;\n /** API reachability: sends wait while its circuit is open, and beaconed events are only forgotten while it is reachable. */\n health?: ServerHealth;\n flushIntervalMs?: number;\n maxQueue?: number;\n batchSize?: number;\n maxAttempts?: number;\n onError?: (err: unknown) => void;\n}\n\n/**\n * Bounded, persisted event queue. Batches ≤50 events every 2s (or on demand), dedupes by\n * `eventId`, and keeps failed events (also across page loads) until the server takes them:\n * retries back off 1s→60s, wait while the API's circuit is open, and start again as soon as it\n * recovers. Drops the oldest events once the queue exceeds 500.\n */\nexport class EventQueue {\n private events: SdkEvent[] = [];\n private timer: ReturnType<typeof setTimeout> | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private inflight = false;\n private inflightIds = new Set<string>();\n private attempt = 0;\n private destroyed = false;\n private offRecover: (() => void) | null = null;\n private readonly flushIntervalMs: number;\n private readonly maxQueue: number;\n private readonly batchSize: number;\n private readonly maxAttempts: number;\n\n constructor(private readonly opts: EventQueueOptions) {\n this.flushIntervalMs = opts.flushIntervalMs ?? 2000;\n this.maxQueue = opts.maxQueue ?? 500;\n this.batchSize = opts.batchSize ?? 50;\n this.maxAttempts = opts.maxAttempts ?? 5;\n const persisted = readJson<SdkEvent[]>(opts.store, opts.storageKey, []);\n if (Array.isArray(persisted)) this.events = persisted.filter((e) => e && typeof e.eventId === \"string\").slice(-this.maxQueue);\n // Events left over from a previous page load are flushed on the next tick.\n if (this.events.length) this.schedule();\n this.offRecover = opts.health?.onRecover(() => this.retryNow()) ?? null;\n }\n\n /** The API is back: drop any pending backoff and send what is queued. */\n private retryNow(): void {\n if (this.destroyed) return;\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.retryTimer = null;\n this.attempt = 0;\n void this.flush();\n }\n\n private retryIn(ms: number): void {\n if (this.retryTimer || this.destroyed) return;\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n void this.flush();\n }, ms);\n }\n\n get size(): number {\n return this.events.length;\n }\n\n /** Pending events (read-only copy, for debugging). */\n peek(): SdkEvent[] {\n return this.events.slice();\n }\n\n enqueue(event: SdkEvent): void {\n if (this.destroyed) return;\n if (this.events.some((e) => e.eventId === event.eventId)) return;\n this.events.push(event);\n if (this.events.length > this.maxQueue) this.events.splice(0, this.events.length - this.maxQueue);\n this.persist();\n this.schedule();\n }\n\n private persist(): void {\n writeJson(this.opts.store, this.opts.storageKey, this.events);\n }\n\n private schedule(): void {\n if (this.timer || this.retryTimer || this.destroyed) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.flushIntervalMs);\n }\n\n /** Sends queued events now (one batch at a time). Safe to call at any time. */\n async flush(): Promise<void> {\n if (this.destroyed || this.inflight || !this.events.length || !this.opts.enabled()) return;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n const wait = this.opts.health?.waitMs() ?? 0;\n if (wait > 0) return this.retryIn(wait);\n this.inflight = true;\n const batch = this.events.slice(0, this.batchSize);\n this.inflightIds = new Set(batch.map((e) => e.eventId));\n let ok = false;\n let retry = true;\n try {\n const res = await this.opts.send(batch);\n ok = res.ok;\n retry = res.retry ?? !res.ok;\n } catch (err) {\n this.opts.onError?.(err);\n }\n this.inflight = false;\n this.inflightIds.clear();\n if (this.destroyed) return;\n if (ok || !retry) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n this.attempt = 0;\n this.persist();\n if (this.events.length) this.schedule();\n return;\n }\n // Fast retries first, then about once a minute until the server takes the events (or the\n // API's circuit says to wait longer); a recovery or the next page load sends them sooner.\n this.attempt = Math.min(this.attempt + 1, this.maxAttempts);\n const delay = this.attempt >= this.maxAttempts ? 60_000 : backoffMs(this.attempt - 1);\n this.retryIn(Math.max(delay, this.opts.health?.waitMs() ?? 0));\n }\n\n /** Best-effort synchronous flush on unload using `sendBeacon`. */\n flushSync(): void {\n if (this.destroyed || !this.opts.enabled() || !this.opts.beacon) return;\n // Events already in flight (fetch with keepalive) survive unload; only beacon the rest to avoid duplicate batches.\n const batch = this.events.filter((e) => !this.inflightIds.has(e.eventId)).slice(0, this.batchSize);\n if (!batch.length) return;\n // A beacon that was queued may still never arrive (the server is down), and nothing reports\n // back. Only forget its events while the API is answering; otherwise they stay persisted and the\n // next page load sends them again (the server drops events it already has, by eventId).\n if (this.opts.beacon(batch) && (this.opts.health?.reachable ?? true)) {\n const ids = new Set(batch.map((e) => e.eventId));\n this.events = this.events.filter((e) => !ids.has(e.eventId));\n }\n this.persist();\n }\n\n clear(): void {\n this.events = [];\n this.persist();\n }\n\n destroy(): void {\n this.destroyed = true;\n this.offRecover?.();\n if (this.timer) clearTimeout(this.timer);\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.timer = null;\n this.retryTimer = null;\n this.persist();\n }\n}\n","import type { RecorderApi } from \"./recorder-types\";\n\n/**\n * Loads the session-replay chunk on demand. The import is rewritten per build: `./recorder.js`\n * (npm; consumers' bundlers code-split it) or, in the script-tag build, a loader that injects\n * `guidely-recorder.js` and resolves `window.__guidelyRecorder` (`recorder` is a thenable there).\n */\nexport const loadRecorder = async (): Promise<RecorderApi> => (await import(\"./recorder\")).recorder;\n"],"mappings":"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","names":["import_runtime","import_guide_runtime","import_runtime","import_guide_runtime","attr","import_runtime","import_guide_runtime","attr","matches","import_runtime","import_runtime","import_runtime","import_guide_runtime","current","pathOf"]}
|