@guidelytech/shared 0.13.0 → 0.15.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/platform.ts","../src/widgets.ts","../src/targeting.ts","../src/targeting-eval.ts","../src/guide.ts","../src/contrast.ts","../src/events.ts","../src/events-util.ts","../src/errors.ts","../src/sdk-api.ts","../src/messenger.ts","../src/complaints.ts","../src/complaints-limits.ts","../src/agents.ts","../src/agents-limits.ts","../src/feedback.ts","../src/feedback-limits.ts","../src/capture.ts","../src/network.ts","../src/templates.ts","../src/media.ts","../src/resource-center.ts","../src/howto.ts","../src/howto-limits.ts","../src/page.ts","../src/tagging.ts","../src/snippet.ts","../src/localization.ts","../src/guide-experiments.ts","../src/custom-css.ts","../src/translation-files.ts"],"sourcesContent":["export * from \"./utils\";\nexport * from \"./platform\";\nexport * from \"./widgets\";\nexport * from \"./targeting\";\nexport * from \"./guide\";\nexport * from \"./events\";\nexport * from \"./sdk-api\";\nexport * from \"./messenger\";\nexport * from \"./complaints\";\nexport * from \"./agents\";\nexport * from \"./feedback\";\nexport * from \"./capture\";\nexport * from \"./network\";\nexport * from \"./templates\";\nexport * from \"./media\";\nexport * from \"./resource-center\";\nexport * from \"./howto\";\nexport * from \"./page\";\nexport * from \"./tagging\";\nexport * from \"./snippet\";\nexport * from \"./localization\";\nexport * from \"./guide-experiments\";\nexport * from \"./custom-css\";\nexport * from \"./contrast\";\nexport * from \"./translation-files\";\nexport const SDK_API_VERSION = \"v1\";\nexport const SHARED_VERSION = \"0.13.0\";\n","/** FNV-1a 32-bit hash; deterministic across SDK and server for rollout bucketing. */\nexport function fnv1a(input: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h >>> 0;\n}\n\n/** Deterministic 0-99 bucket for percentage rollouts. */\nexport function rolloutBucket(subject: string, salt: string): number {\n return fnv1a(`${salt}:${subject}`) % 100;\n}\n\nexport function slugify(input: string): string {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64) || \"untitled\";\n}\n\nconst ALPHABET = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n/** URL-safe random id. Uses crypto when available, falls back to Math.random (ids are not secrets). */\nexport function randomId(size = 16): string {\n const g: any = typeof globalThis !== \"undefined\" ? globalThis : {};\n let bytes: Uint8Array;\n if (g.crypto && typeof g.crypto.getRandomValues === \"function\") {\n bytes = new Uint8Array(size);\n g.crypto.getRandomValues(bytes);\n } else {\n bytes = new Uint8Array(size);\n for (let i = 0; i < size; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n let out = \"\";\n for (let i = 0; i < size; i++) out += ALPHABET[(bytes[i] as number) % ALPHABET.length];\n return out;\n}\n\nexport function isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Safe nested getter: get(obj, \"account.plan\") */\nexport function getPath(obj: unknown, path: string): unknown {\n if (!path) return obj;\n let cur: any = obj;\n for (const part of path.split(\".\")) {\n if (cur == null) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\nexport function clamp(n: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, n));\n}\n\n/** Glob-style URL pattern match: `*` matches any chars except `/`, `**` matches anything. */\nexport function matchUrlPattern(pattern: string, url: string): boolean {\n if (!pattern) return true;\n if (pattern === url) return true;\n const escaped = pattern\n .replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*\\*/g, \"__GLOBSTAR__\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/__GLOBSTAR__/g, \".*\");\n const re = new RegExp(`^${escaped}$`);\n return re.test(url) || re.test(stripOrigin(url));\n}\n\nexport function stripOrigin(url: string): string {\n try {\n const u = new URL(url);\n return u.pathname + u.search + u.hash;\n } catch {\n return url;\n }\n}\n\n/** Safe regexp construction with a length cap to limit ReDoS exposure. */\nexport function safeRegExp(source: string, flags = \"i\"): RegExp | null {\n if (!source || source.length > 200) return null;\n try {\n return new RegExp(source, flags);\n } catch {\n return null;\n }\n}\n","/**\n * Cross-platform helpers shared by the web SDK, the React Native SDK and (as a reference for) the\n * native iOS/Android SDKs. Zod-free so it can ship in runtime bundles.\n */\n\n/** Platforms a guide can be delivered to. */\nexport const PLATFORMS = [\"web\", \"ios\", \"android\"] as const;\nexport type Platform = (typeof PLATFORMS)[number];\n\n/** Guides published before platforms existed have no `platforms` field and are web-only. */\nexport const DEFAULT_PLATFORMS: Platform[] = [\"web\"];\n\n/** Platforms a guide config targets (missing field → web only). */\nexport function guidePlatforms(config: { platforms?: readonly string[] | null }): string[] {\n return Array.isArray(config.platforms) ? [...config.platforms] : [...DEFAULT_PLATFORMS];\n}\n\nexport function supportsPlatform(config: { platforms?: readonly string[] | null }, platform: string): boolean {\n return guidePlatforms(config).includes(platform);\n}\n\n/** Attribute web apps put on elements to share a target id with their mobile apps. */\nexport const GUIDELY_ID_ATTRIBUTE = \"data-guidely-id\";\n\n/**\n * Extracts a Guidely target id from a trigger / advance / checklist value so the same guide works on\n * web and mobile. Accepts a bare id (`new-deal`), `#new-deal`, or `[data-guidely-id=\"new-deal\"]`\n * (also `data-testid` / `data-tour`). Returns null for selectors that cannot name a single id.\n */\nexport function guidelyIdFromSelector(value: string | null | undefined): string | null {\n const v = (value ?? \"\").trim();\n if (!v) return null;\n if (/^[A-Za-z0-9_][A-Za-z0-9_\\-:.]*$/.test(v)) return v;\n const hash = v.match(/^#([A-Za-z0-9_][A-Za-z0-9_\\-:.]*)$/);\n if (hash) return hash[1] as string;\n const attr = v.match(/^(?:[a-z][a-z0-9]*)?\\[\\s*data-(?:guidely-id|testid|tour)\\s*=\\s*([\"']?)([^\"'\\]]+)\\1\\s*\\]$/i);\n if (attr) return (attr[2] as string).trim();\n return null;\n}\n\n/**\n * Mobile SDKs have screens instead of URLs. URL-based features (URL patterns, `url_match` triggers,\n * multi-page steps, `url_visited` checklist tasks) match against the screen path `/<ScreenName>`.\n */\nexport function screenPath(screen: string | null | undefined): string {\n const s = (screen ?? \"\").trim();\n if (!s) return \"/\";\n return s.startsWith(\"/\") ? s : `/${s}`;\n}\n\n/**\n * Compares dotted version strings numerically (`2.10.0` > `2.9.3`). Non-numeric parts compare as\n * strings; a missing part counts as 0 (`2.1` == `2.1.0`). Returns -1, 0 or 1, or null when either\n * side is empty.\n */\nexport function compareVersions(a: unknown, b: unknown): -1 | 0 | 1 | null {\n const sa = a == null ? \"\" : String(a).trim().replace(/^v/i, \"\");\n const sb = b == null ? \"\" : String(b).trim().replace(/^v/i, \"\");\n if (!sa || !sb) return null;\n const pa = sa.split(/[.+-]/);\n const pb = sb.split(/[.+-]/);\n const n = Math.max(pa.length, pb.length);\n for (let i = 0; i < n; i++) {\n const x = pa[i] ?? \"0\";\n const y = pb[i] ?? \"0\";\n const nx = /^\\d+$/.test(x) ? Number(x) : NaN;\n const ny = /^\\d+$/.test(y) ? Number(y) : NaN;\n if (!Number.isNaN(nx) && !Number.isNaN(ny)) {\n if (nx !== ny) return nx < ny ? -1 : 1;\n } else if (x !== y) {\n return x < y ? -1 : 1;\n }\n }\n return 0;\n}\n","/**\n * Pure checklist / survey logic shared by every renderer (web runtime, React Native, and the\n * reference for the native SDKs). Zod-free; uses structural types so it stays in the runtime entry.\n */\n\nexport type SurveyAnswer = string | number | boolean | string[];\nexport type SurveyAnswers = Record<string, SurveyAnswer>;\n\nexport interface ShowWhen {\n questionId: string;\n op: \"equals\" | \"lte\" | \"gte\" | \"in\";\n value: string | number | string[];\n}\n\n/** Evaluates a question's `showWhen` condition against current answers. */\nexport function isQuestionVisible(q: { showWhen?: ShowWhen }, answers: SurveyAnswers): boolean {\n if (!q.showWhen) return true;\n const actual = answers[q.showWhen.questionId];\n if (actual === undefined) return false;\n const expected = q.showWhen.value;\n switch (q.showWhen.op) {\n case \"equals\":\n return Array.isArray(actual) ? actual.includes(String(expected)) : String(actual) === String(expected);\n case \"lte\":\n return Number(actual) <= Number(expected);\n case \"gte\":\n return Number(actual) >= Number(expected);\n case \"in\": {\n const list = Array.isArray(expected) ? expected : [String(expected)];\n return Array.isArray(actual) ? actual.some((a) => list.includes(a)) : list.includes(String(actual));\n }\n default:\n return false;\n }\n}\n\n/** Are all required tasks done? */\nexport function isChecklistComplete(config: { tasks: Array<{ id: string; required: boolean }> }, progress: { completedTaskIds: string[] }): boolean {\n const done = new Set(progress.completedTaskIds);\n return config.tasks.filter((t) => t.required).every((t) => done.has(t.id));\n}\n","import { z } from \"zod\";\nimport { RULE_FIELDS, RULE_OPERATORS, type Rule, type RuleGroup } from \"./targeting-eval\";\n\nexport * from \"./targeting-eval\";\n\nexport const RuleSchema: z.ZodType<Rule> = z.object({\n id: z.string().min(1),\n field: z.enum(RULE_FIELDS),\n key: z.string().max(200).optional(),\n op: z.enum(RULE_OPERATORS),\n value: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]).optional(),\n negate: z.boolean().optional(),\n});\n\nexport const RuleGroupSchema: z.ZodType<RuleGroup> = z.lazy(() =>\n z.object({\n id: z.string().min(1),\n op: z.enum([\"and\", \"or\"]),\n rules: z.array(z.union([RuleSchema, RuleGroupSchema])).max(100),\n negate: z.boolean().optional(),\n }),\n);\n","/**\n * Zod-free targeting evaluation. Imported by the browser SDK via `@guidelytech/shared/runtime`\n * so the runtime bundle does not pull in zod. Schemas live in ./targeting.ts.\n */\nimport { compareVersions } from \"./platform\";\nimport { getPath, matchUrlPattern, rolloutBucket, safeRegExp } from \"./utils\";\n\nexport const RULE_OPERATORS = [\n \"equals\",\n \"not_equals\",\n \"contains\",\n \"not_contains\",\n \"starts_with\",\n \"ends_with\",\n \"exists\",\n \"not_exists\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"in\",\n \"not_in\",\n \"regex\",\n \"is_true\",\n \"is_false\",\n \"before\",\n \"after\",\n] as const;\nexport type RuleOperator = (typeof RULE_OPERATORS)[number];\n\nexport const RULE_FIELDS = [\n \"user.attribute\",\n \"account.attribute\",\n \"user.role\",\n \"user.plan\",\n \"user.identified\",\n \"url.path\",\n \"url.full\",\n \"url.query\",\n \"device.type\",\n \"device.browser\",\n \"device.os\",\n \"visitor.firstVisit\",\n \"visitor.returning\",\n \"event.seen\",\n \"guide.completed\",\n \"guide.dismissed\",\n \"guide.seen\",\n \"checklist.completed\",\n \"audience.member\",\n \"datetime.now\",\n \"datetime.dayOfWeek\",\n \"datetime.hour\",\n \"rollout.percentage\",\n /** Guide A/B tests: the visitor's 0-99 bucket for the salt in `key` (see guide-experiments.ts). */\n \"experiment.bucket\",\n \"environment\",\n \"locale\",\n \"app.platform\",\n \"app.screen\",\n \"app.version\",\n \"page.views\",\n \"feature.clicks\",\n] as const;\nexport type RuleField = (typeof RULE_FIELDS)[number];\n\nexport interface Rule {\n id: string;\n field: RuleField;\n /** For attribute/query/event fields: the attribute key, query param name, event name, guide id... */\n key?: string;\n op: RuleOperator;\n value?: string | number | boolean | string[];\n /** When true, the rule is negated (exclusion rule). */\n negate?: boolean;\n}\n\nexport type RuleGroup = {\n id: string;\n op: \"and\" | \"or\";\n rules: Array<Rule | RuleGroup>;\n negate?: boolean;\n};\n\nexport function isRuleGroup(r: Rule | RuleGroup): r is RuleGroup {\n return (r as RuleGroup).rules !== undefined;\n}\n\nexport function emptyRuleGroup(id = \"root\"): RuleGroup {\n return { id, op: \"and\", rules: [] };\n}\n\n/** Everything targeting evaluation can see. Built by the SDK (browser) or the server. */\nexport interface TargetingContext {\n userId?: string | null;\n anonymousId: string;\n userAttributes: Record<string, unknown>;\n accountAttributes: Record<string, unknown>;\n url: string;\n path: string;\n query: Record<string, string>;\n device: { type: \"desktop\" | \"tablet\" | \"mobile\"; browser?: string; os?: string };\n firstVisit: boolean;\n eventsSeen: Set<string> | string[];\n completedGuides: Set<string> | string[];\n dismissedGuides: Set<string> | string[];\n seenGuides: Set<string> | string[];\n completedChecklists: Set<string> | string[];\n audienceIds: Set<string> | string[];\n now: Date;\n environment: string;\n locale?: string;\n /** `web`, `ios` or `android`. Missing means web. */\n platform?: string;\n /** Current screen name (mobile SDKs; set via `screen()`). */\n screen?: string;\n /** Host app version (mobile SDKs), e.g. `2.4.1`. */\n appVersion?: string;\n /** Salt for rollout (guide id). Set per guide before evaluating. */\n rolloutSalt?: string;\n /**\n * Views of tagged pages / clicks on tagged features in the last 30 days, by tag id. Only the server\n * fills it (audience evaluation); in the browser `page.views` / `feature.clicks` read 0.\n */\n tagUsage?: Record<string, number>;\n}\n\nfunction has(set: Set<string> | string[] | undefined, v: string): boolean {\n if (!set) return false;\n return set instanceof Set ? set.has(v) : set.includes(v);\n}\n\nfunction resolveField(rule: Rule, ctx: TargetingContext): unknown {\n switch (rule.field) {\n case \"user.attribute\":\n return rule.key ? getPath(ctx.userAttributes, rule.key) : undefined;\n case \"account.attribute\":\n return rule.key ? getPath(ctx.accountAttributes, rule.key) : undefined;\n case \"user.role\":\n return ctx.userAttributes.role;\n case \"user.plan\":\n return ctx.userAttributes.plan ?? ctx.accountAttributes.plan;\n case \"user.identified\":\n return !!ctx.userId;\n case \"url.path\":\n return ctx.path;\n case \"url.full\":\n return ctx.url;\n case \"url.query\":\n return rule.key ? ctx.query[rule.key] : undefined;\n case \"device.type\":\n return ctx.device.type;\n case \"device.browser\":\n return ctx.device.browser;\n case \"device.os\":\n return ctx.device.os;\n case \"visitor.firstVisit\":\n return ctx.firstVisit;\n case \"visitor.returning\":\n return !ctx.firstVisit;\n case \"event.seen\":\n return rule.key ? has(ctx.eventsSeen, rule.key) : false;\n case \"guide.completed\":\n return rule.key ? has(ctx.completedGuides, rule.key) : false;\n case \"guide.dismissed\":\n return rule.key ? has(ctx.dismissedGuides, rule.key) : false;\n case \"guide.seen\":\n return rule.key ? has(ctx.seenGuides, rule.key) : false;\n case \"checklist.completed\":\n return rule.key ? has(ctx.completedChecklists, rule.key) : false;\n case \"audience.member\":\n return rule.key ? has(ctx.audienceIds, rule.key) : false;\n case \"datetime.now\":\n return ctx.now.toISOString();\n case \"datetime.dayOfWeek\":\n return ctx.now.getDay();\n case \"datetime.hour\":\n return ctx.now.getHours();\n case \"rollout.percentage\":\n return rolloutBucket(ctx.userId || ctx.anonymousId, ctx.rolloutSalt || \"guidely\");\n case \"experiment.bucket\":\n return rule.key ? rolloutBucket(ctx.userId || ctx.anonymousId, rule.key) : undefined;\n case \"environment\":\n return ctx.environment;\n case \"locale\":\n return ctx.locale;\n case \"app.platform\":\n return ctx.platform ?? \"web\";\n case \"app.screen\":\n return ctx.screen;\n case \"app.version\":\n return ctx.appVersion;\n case \"page.views\":\n case \"feature.clicks\":\n return rule.key ? (ctx.tagUsage?.[rule.key] ?? 0) : 0;\n default:\n return undefined;\n }\n}\n\nfunction toNumber(v: unknown): number | null {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\" && v.trim() !== \"\" && !Number.isNaN(Number(v))) return Number(v);\n if (v instanceof Date) return v.getTime();\n return null;\n}\n\nfunction toDateMs(v: unknown): number | null {\n if (v instanceof Date) return v.getTime();\n if (typeof v === \"string\") {\n const t = Date.parse(v);\n return Number.isNaN(t) ? null : t;\n }\n if (typeof v === \"number\") return v;\n return null;\n}\n\nexport function compare(op: RuleOperator, actual: unknown, expected: Rule[\"value\"]): boolean {\n switch (op) {\n case \"exists\":\n return actual !== undefined && actual !== null && actual !== \"\";\n case \"not_exists\":\n return actual === undefined || actual === null || actual === \"\";\n case \"is_true\":\n return actual === true || actual === \"true\";\n case \"is_false\":\n return actual === false || actual === \"false\";\n case \"equals\":\n if (typeof actual === \"boolean\") return String(actual) === String(expected);\n return String(actual ?? \"\") === String(expected ?? \"\");\n case \"not_equals\":\n return String(actual ?? \"\") !== String(expected ?? \"\");\n case \"contains\":\n return typeof actual === \"string\" && actual.toLowerCase().includes(String(expected ?? \"\").toLowerCase());\n case \"not_contains\":\n return !(typeof actual === \"string\" && actual.toLowerCase().includes(String(expected ?? \"\").toLowerCase()));\n case \"starts_with\":\n return typeof actual === \"string\" && actual.startsWith(String(expected ?? \"\"));\n case \"ends_with\":\n return typeof actual === \"string\" && actual.endsWith(String(expected ?? \"\"));\n case \"gt\":\n case \"gte\":\n case \"lt\":\n case \"lte\": {\n const a = toNumber(actual);\n const b = toNumber(expected);\n if (a === null || b === null) return false;\n return op === \"gt\" ? a > b : op === \"gte\" ? a >= b : op === \"lt\" ? a < b : a <= b;\n }\n case \"in\": {\n const list = Array.isArray(expected) ? expected : String(expected ?? \"\").split(\",\").map((s) => s.trim());\n return list.includes(String(actual ?? \"\"));\n }\n case \"not_in\": {\n const list = Array.isArray(expected) ? expected : String(expected ?? \"\").split(\",\").map((s) => s.trim());\n return !list.includes(String(actual ?? \"\"));\n }\n case \"regex\": {\n const re = safeRegExp(String(expected ?? \"\"));\n return !!re && typeof actual === \"string\" && re.test(actual);\n }\n case \"before\": {\n const a = toDateMs(actual);\n const b = toDateMs(expected);\n return a !== null && b !== null && a < b;\n }\n case \"after\": {\n const a = toDateMs(actual);\n const b = toDateMs(expected);\n return a !== null && b !== null && a > b;\n }\n default:\n return false;\n }\n}\n\nexport function evaluateRule(rule: Rule, ctx: TargetingContext): boolean {\n let result: boolean;\n if (rule.field === \"url.path\" || rule.field === \"url.full\" || rule.field === \"app.screen\") {\n const actual = String(resolveField(rule, ctx) ?? \"\");\n if (rule.op === \"equals\") result = matchUrlPattern(String(rule.value ?? \"\"), actual);\n else if (rule.op === \"not_equals\") result = !matchUrlPattern(String(rule.value ?? \"\"), actual);\n else result = compare(rule.op, actual, rule.value);\n } else if (rule.field === \"app.version\" && [\"equals\", \"not_equals\", \"gt\", \"gte\", \"lt\", \"lte\"].includes(rule.op)) {\n const c = compareVersions(resolveField(rule, ctx), rule.value);\n if (c === null) result = rule.op === \"not_equals\";\n else result = rule.op === \"equals\" ? c === 0 : rule.op === \"not_equals\" ? c !== 0 : rule.op === \"gt\" ? c > 0 : rule.op === \"gte\" ? c >= 0 : rule.op === \"lt\" ? c < 0 : c <= 0;\n } else {\n result = compare(rule.op, resolveField(rule, ctx), rule.value);\n }\n return rule.negate ? !result : result;\n}\n\n/** Evaluate a rule tree. An empty group matches everyone. */\nexport function evaluateRules(group: RuleGroup | null | undefined, ctx: TargetingContext): boolean {\n if (!group || group.rules.length === 0) return group?.negate ? false : true;\n const results = group.rules.map((r) => (isRuleGroup(r) ? evaluateRules(r, ctx) : evaluateRule(r, ctx)));\n const value = group.op === \"and\" ? results.every(Boolean) : results.some(Boolean);\n return group.negate ? !value : value;\n}\n\n/** Fields whose evaluation requires server-held data. Used by docs/UI to annotate rules. */\nexport const SERVER_ASSISTED_FIELDS: RuleField[] = [\"audience.member\", \"guide.completed\", \"guide.dismissed\", \"guide.seen\", \"checklist.completed\", \"page.views\", \"feature.clicks\"];\n\n/** Who a guide is shown to, before its targeting rules: everyone, only signed-in (identified) users, or only anonymous visitors. */\nexport const GUIDE_VISIBILITIES = [\"everyone\", \"identified\", \"anonymous\"] as const;\nexport type GuideVisibility = (typeof GUIDE_VISIBILITIES)[number];\n\n/**\n * Targeting with the visibility folded in as a `user.identified` rule. The server sends guides to SDKs\n * this way, so every SDK applies it through the rules it already evaluates (SDKs that predate the field\n * resolve it as undefined and show the guide to nobody rather than to everyone).\n */\nexport function withVisibility(targeting: RuleGroup, visibility: GuideVisibility | undefined): RuleGroup {\n if (!visibility || visibility === \"everyone\") return targeting;\n return { id: \"visibility\", op: \"and\", rules: [{ id: \"visibility-rule\", field: \"user.identified\", op: visibility === \"identified\" ? \"is_true\" : \"is_false\" }, targeting] };\n}\n\nexport function describeRule(rule: Rule): string {\n const subject = rule.key ? `${rule.field}[${rule.key}]` : rule.field;\n const v = Array.isArray(rule.value) ? rule.value.join(\", \") : rule.value === undefined ? \"\" : String(rule.value);\n return `${rule.negate ? \"NOT \" : \"\"}${subject} ${rule.op.replace(/_/g, \" \")}${v ? ` \"${v}\"` : \"\"}`;\n}\n","import { z } from \"zod\";\nimport { PLATFORMS } from \"./platform\";\nimport { GUIDE_VISIBILITIES, RuleGroupSchema, emptyRuleGroup, type RuleGroup } from \"./targeting\";\nimport { contrastIssues } from \"./contrast\";\n\nexport const GUIDE_KINDS = [\"flow\", \"modal\", \"tooltip\", \"banner\", \"checklist\", \"survey\", \"announcement\"] as const;\nexport type GuideKind = (typeof GUIDE_KINDS)[number];\n\nexport const GUIDE_STATUSES = [\"draft\", \"published\", \"paused\", \"archived\"] as const;\nexport type GuideStatus = (typeof GUIDE_STATUSES)[number];\n\nexport const STEP_TYPES = [\"modal\", \"tooltip\", \"popover\", \"spotlight\", \"hotspot\", \"banner\", \"slideout\", \"checklist\", \"custom\", \"survey\"] as const;\nexport type StepType = (typeof STEP_TYPES)[number];\n\nexport const PLACEMENTS = [\"top\", \"top-start\", \"top-end\", \"right\", \"right-start\", \"right-end\", \"bottom\", \"bottom-start\", \"bottom-end\", \"left\", \"left-start\", \"left-end\", \"auto\"] as const;\nexport type Placement = (typeof PLACEMENTS)[number];\n\n/** `guidely-id` is cross-platform: `data-guidely-id` on web, `GuidelyTarget` / `guidelyTarget()` on mobile. */\nexport const SELECTOR_KINDS = [\"css\", \"id\", \"data-attr\", \"aria\", \"text\", \"xpath\", \"guidely-id\"] as const;\nexport const SelectorStrategySchema = z.object({\n kind: z.enum(SELECTOR_KINDS),\n value: z.string().min(1).max(1000),\n /** Optional human-readable label captured at pick time. */\n label: z.string().max(200).optional(),\n});\nexport type SelectorStrategy = z.infer<typeof SelectorStrategySchema>;\n\nexport const TargetSchema = z.object({\n /** Ordered strategies; the first one resolving to exactly one element wins. */\n selectors: z.array(SelectorStrategySchema).max(10),\n /** How long to wait for the element before applying fallback. */\n waitMs: z.number().int().min(0).max(60000).default(5000),\n /** What to do when the element never shows up. */\n fallback: z.enum([\"skip\", \"show_as_modal\", \"end_guide\", \"wait\"]).default(\"skip\"),\n /** Scroll the element into view before positioning. */\n scrollIntoView: z.boolean().default(true),\n /** Text snapshot captured at pick time; used for authoring warnings. */\n textSnapshot: z.string().max(200).optional(),\n});\nexport type StepTarget = z.infer<typeof TargetSchema>;\n\nexport const BUTTON_ACTIONS = [\"next\", \"back\", \"dismiss\", \"complete\", \"skip\", \"url\", \"start_guide\", \"event\", \"open_resource_center\", \"none\"] as const;\nexport const ButtonSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1).max(80),\n action: z.enum(BUTTON_ACTIONS),\n variant: z.enum([\"primary\", \"secondary\", \"ghost\", \"link\"]).default(\"primary\"),\n /** url for `url`, guide id for `start_guide`, event name for `event`, step id for `next` branch override */\n value: z.string().max(2000).optional(),\n newTab: z.boolean().optional(),\n});\nexport type StepButton = z.infer<typeof ButtonSchema>;\n\nexport const StepBranchSchema = z.object({\n id: z.string(),\n /** Rule group evaluated against targeting context when leaving the step. */\n when: RuleGroupSchema,\n /** Step id to jump to. */\n goTo: z.string(),\n});\n\nexport const ADVANCE_ON = [\"button\", \"element_click\", \"element_visible\", \"event\", \"delay\", \"any\"] as const;\n\nexport const StepSchema = z.object({\n id: z.string().min(1).max(64),\n type: z.enum(STEP_TYPES),\n title: z.string().max(200).default(\"\"),\n /** Sanitized HTML body (links, images, lists, formatting). */\n body: z.string().max(20000).default(\"\"),\n imageUrl: z.string().url().max(2000).optional().or(z.literal(\"\")),\n /** Alternative text for `imageUrl` (screen readers); empty = decorative. */\n imageAlt: z.string().max(300).optional(),\n buttons: z.array(ButtonSchema).max(6).default([]),\n target: TargetSchema.optional(),\n placement: z.enum(PLACEMENTS).default(\"auto\"),\n /** Pixel offset between anchor and card. */\n offset: z.number().int().min(0).max(64).default(10),\n showOverlay: z.boolean().default(false),\n showProgress: z.boolean().default(true),\n showClose: z.boolean().default(true),\n dismissOnOutsideClick: z.boolean().default(false),\n /** Highlight padding for spotlight. */\n spotlightPadding: z.number().int().min(0).max(64).default(6),\n /** Banner/slideout position. */\n position: z.enum([\"top\", \"bottom\", \"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\", \"center\"]).default(\"bottom-right\"),\n /** URL pattern this step belongs to (for multi-page flows). */\n url: z.string().max(500).optional(),\n /** Automatic advancement. */\n advanceOn: z.enum(ADVANCE_ON).default(\"button\"),\n advanceValue: z.string().max(500).optional(),\n advanceDelayMs: z.number().int().min(0).max(600000).optional(),\n branches: z.array(StepBranchSchema).max(10).default([]),\n width: z.number().int().min(200).max(900).optional(),\n /** Step-level targeting: skip step when rules do not match. */\n targeting: RuleGroupSchema.optional(),\n /** Hotspot pulse dot settings. */\n hotspot: z.object({ size: z.number().int().min(8).max(40).default(14), pulse: z.boolean().default(true), openOn: z.enum([\"click\", \"hover\"]).default(\"click\") }).optional(),\n /** Custom step: arbitrary sanitized HTML with no chrome. */\n customHtml: z.string().max(50000).optional(),\n /**\n * Code block (custom steps only): JavaScript run on the web when the step shows, only while the\n * workspace allows code blocks (an admin setting, off by default). Mobile SDKs never receive it.\n */\n code: z.string().max(20000).optional(),\n});\nexport type GuideStep = z.infer<typeof StepSchema>;\nexport type GuideStepInput = z.input<typeof StepSchema>;\n\nexport const TRIGGER_TYPES = [\"page_load\", \"url_match\", \"event\", \"element_click\", \"element_visible\", \"manual\", \"delay\", \"after_guide\", \"segment_enter\"] as const;\nexport const TriggerSchema = z.object({\n type: z.enum(TRIGGER_TYPES).default(\"page_load\"),\n /** url pattern, event name, selector, guide id, audience id depending on type */\n value: z.string().max(1000).optional(),\n delayMs: z.number().int().min(0).max(600000).default(0),\n /** Also require URL to match this pattern (any trigger). */\n urlPattern: z.string().max(500).optional(),\n});\nexport type TriggerConfig = z.infer<typeof TriggerSchema>;\n\nexport const FrequencySchema = z.object({\n mode: z.enum([\"once\", \"once_per_session\", \"every_time\", \"interval\"]).default(\"once\"),\n intervalHours: z.number().int().min(1).max(8760).optional(),\n maxImpressions: z.number().int().min(1).max(1000).optional(),\n /** Hours to wait after dismissal before eligible again (when not `once`). */\n cooldownHours: z.number().int().min(0).max(8760).default(0),\n /** Lower number wins when multiple guides qualify. */\n priority: z.number().int().min(0).max(1000).default(100),\n /** Guide ids that must not be active at the same time. */\n mutuallyExclusiveWith: z.array(z.string()).max(50).default([]),\n /** Re-show if dismissed (otherwise dismissal counts as completion for frequency). */\n reshowAfterDismiss: z.boolean().default(false),\n /** Bypass the project's guide throttling (always eligible as far as throttling goes). */\n ignoreThrottling: z.boolean().optional(),\n});\nexport type FrequencyConfig = z.infer<typeof FrequencySchema>;\n\nexport const AppearanceSchema = z.object({\n theme: z.enum([\"light\", \"dark\", \"auto\"]).default(\"auto\"),\n primaryColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n backgroundColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n textColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n borderRadius: z.number().int().min(0).max(32).optional(),\n fontFamily: z.string().max(200).optional(),\n overlayOpacity: z.number().min(0).max(1).optional(),\n zIndex: z.number().int().min(1).max(2147483647).optional(),\n preset: z.string().max(50).optional(),\n animation: z.enum([\"fade\", \"slide\", \"none\"]).default(\"fade\"),\n /** Custom CSS scoped to this guide's container (sanitized; see custom-css.ts). Web only. */\n customCss: z.string().max(20000).optional(),\n});\nexport type Appearance = z.infer<typeof AppearanceSchema>;\n\nexport const ChecklistTaskSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1).max(200),\n description: z.string().max(2000).default(\"\"),\n /** How the task completes. */\n completion: z.enum([\"manual\", \"event\", \"guide_completed\", \"url_visited\", \"click\"]).default(\"manual\"),\n completionValue: z.string().max(500).optional(),\n /** Optional action when clicking the task. */\n action: z.enum([\"none\", \"start_guide\", \"url\", \"event\"]).default(\"none\"),\n actionValue: z.string().max(2000).optional(),\n required: z.boolean().default(true),\n});\nexport type ChecklistTask = z.infer<typeof ChecklistTaskSchema>;\n\nexport const ChecklistConfigSchema = z.object({\n tasks: z.array(ChecklistTaskSchema).min(1),\n ordered: z.boolean().default(false),\n launcherLabel: z.string().max(60).default(\"Getting started\"),\n position: z.enum([\"bottom-right\", \"bottom-left\"]).default(\"bottom-right\"),\n completionTitle: z.string().max(200).default(\"You're all set!\"),\n completionBody: z.string().max(2000).default(\"\"),\n autoOpen: z.boolean().default(true),\n dismissible: z.boolean().default(true),\n});\nexport type ChecklistConfig = z.infer<typeof ChecklistConfigSchema>;\n\nexport const SURVEY_QUESTION_TYPES = [\"nps\", \"csat\", \"thumbs\", \"single_choice\", \"multiple_choice\", \"text\", \"rating\"] as const;\nexport const SurveyQuestionSchema = z.object({\n id: z.string().min(1),\n type: z.enum(SURVEY_QUESTION_TYPES),\n title: z.string().min(1).max(500),\n description: z.string().max(1000).default(\"\"),\n required: z.boolean().default(true),\n options: z.array(z.object({ id: z.string(), label: z.string().max(200) })).max(20).default([]),\n scaleMax: z.number().int().min(2).max(10).optional(),\n lowLabel: z.string().max(60).optional(),\n highLabel: z.string().max(60).optional(),\n placeholder: z.string().max(200).optional(),\n /** Conditional follow-up: show only when a previous answer matches. */\n showWhen: z.object({ questionId: z.string(), op: z.enum([\"equals\", \"lte\", \"gte\", \"in\"]), value: z.union([z.string(), z.number(), z.array(z.string())]) }).optional(),\n});\nexport type SurveyQuestion = z.infer<typeof SurveyQuestionSchema>;\n\nexport const SurveyConfigSchema = z.object({\n questions: z.array(SurveyQuestionSchema).min(1).max(20),\n thankYouTitle: z.string().max(200).default(\"Thanks for your feedback!\"),\n thankYouBody: z.string().max(2000).default(\"\"),\n position: z.enum([\"bottom-right\", \"bottom-left\", \"center\"]).default(\"bottom-right\"),\n startAt: z.string().datetime().optional(),\n endAt: z.string().datetime().optional(),\n});\nexport type SurveyConfig = z.infer<typeof SurveyConfigSchema>;\n\n/**\n * When any guide may show: `startAt` / `endAt` are UTC instants; `timezone` (IANA, e.g.\n * `Europe/London`) is the zone they were entered in, kept for display only.\n */\nexport const GuideScheduleSchema = z.object({\n startAt: z.string().datetime().optional(),\n endAt: z.string().datetime().optional(),\n timezone: z.string().max(64).optional(),\n});\nexport type GuideSchedule = z.infer<typeof GuideScheduleSchema>;\n\n/** Locale codes: BCP 47 language tags such as `fr`, `pt-BR`, `zh-Hans`. */\nexport const LOCALE_PATTERN = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8}){0,2}$/;\nexport const LocaleSchema = z.string().regex(LOCALE_PATTERN, \"Use a language code such as fr or pt-BR\").max(20);\n\n/**\n * Translations of a guide's text: locale → translation key → text. Keys come from\n * `guideTextEntries` (e.g. `steps.<stepId>.title`); missing keys fall back to the default language.\n */\nexport const GuideLocalizationSchema = z.object({\n translations: z.record(LocaleSchema, z.record(z.string().max(200), z.string().max(50000))).default({}),\n});\nexport type GuideLocalization = z.infer<typeof GuideLocalizationSchema>;\n\n/** Project.settings.localization: the language guides are written in and the languages offered for translation. */\nexport const LocalizationSettingsSchema = z.object({\n defaultLocale: LocaleSchema.default(\"en\"),\n locales: z.array(LocaleSchema).max(50).default([]),\n /** Machine-translate new and changed text into every language automatically (needs an Anthropic key). */\n autoTranslate: z.boolean().optional(),\n /** Machine translations go live only once a teammate approves them; until then visitors see the default language. */\n requireReview: z.boolean().optional(),\n});\n\n/**\n * Project.settings.guideThrottling: limits automatically launched guides per visitor (guides\n * started by a button, a link, Help or `startGuide()` are never throttled; nor are banners,\n * checklists and hotspot-only guides, which don't interrupt).\n */\nexport const GuideThrottlingSchema = z.object({\n enabled: z.boolean().default(false),\n maxGuides: z.number().int().min(1).max(50).default(1),\n windowHours: z.number().int().min(1).max(720).default(24),\n minGapMinutes: z.number().int().min(0).max(10080).default(0),\n});\n\nexport const GuideConfigSchema = z.object({\n steps: z.array(StepSchema).max(50).default([]),\n /** Everyone, only identified (logged-in) users, or only anonymous visitors; applied on top of `targeting`. */\n visibility: z.enum(GUIDE_VISIBILITIES).default(\"everyone\"),\n targeting: RuleGroupSchema.default(() => emptyRuleGroup()),\n trigger: TriggerSchema.default({}),\n frequency: FrequencySchema.default({}),\n appearance: AppearanceSchema.default({}),\n checklist: ChecklistConfigSchema.optional(),\n survey: SurveyConfigSchema.optional(),\n /** Restrict guide to url pattern(s) (applied before trigger). On mobile these match the screen path `/<Screen>`. */\n urlPatterns: z.array(z.string().max(500)).max(20).default([]),\n /** Platforms that receive this guide. Guides created before mobile support are web-only. */\n platforms: z.array(z.enum(PLATFORMS)).max(PLATFORMS.length).default([\"web\"]),\n /** Start / end window for any guide kind (surveys also honour `survey.startAt` / `endAt`). */\n schedule: GuideScheduleSchema.optional(),\n /** Translations (see localization.ts). */\n localization: GuideLocalizationSchema.optional(),\n});\nexport type GuideConfig = z.infer<typeof GuideConfigSchema>;\nexport type GuideConfigInput = z.input<typeof GuideConfigSchema>;\n\nexport function defaultGuideConfig(kind: GuideKind): GuideConfig {\n return GuideConfigSchema.parse({\n steps: kind === \"checklist\" || kind === \"survey\" ? [] : [defaultStep(kind === \"flow\" ? \"tooltip\" : kind === \"banner\" ? \"banner\" : kind === \"tooltip\" ? \"tooltip\" : \"modal\")],\n checklist: kind === \"checklist\" ? { tasks: [{ id: \"task-1\", title: \"Complete your profile\" }] } : undefined,\n survey: kind === \"survey\" ? { questions: [{ id: \"q1\", type: \"nps\", title: \"How likely are you to recommend us to a friend?\" }] } : undefined,\n trigger: kind === \"checklist\" ? { type: \"page_load\" } : {},\n });\n}\n\nlet stepCounter = 0;\nexport function defaultStep(type: StepType, overrides: Partial<GuideStepInput> = {}): GuideStep {\n stepCounter += 1;\n const base: GuideStepInput = {\n id: `step-${Date.now().toString(36)}-${stepCounter}`,\n type,\n title: type === \"modal\" ? \"Welcome!\" : \"Step title\",\n body: \"<p>Describe what the user should do here.</p>\",\n buttons: [\n { id: \"btn-back\", label: \"Back\", action: \"back\", variant: \"ghost\" },\n { id: \"btn-next\", label: \"Next\", action: \"next\", variant: \"primary\" },\n ],\n placement: type === \"banner\" ? \"top\" : \"auto\",\n showOverlay: type === \"modal\" || type === \"spotlight\",\n ...overrides,\n };\n if ([\"tooltip\", \"popover\", \"spotlight\", \"hotspot\"].includes(type) && !base.target) {\n base.target = { selectors: [], waitMs: 5000, fallback: \"skip\", scrollIntoView: true };\n }\n return StepSchema.parse(base);\n}\n\n/** Buttons to show for a step; \"back\" buttons are hidden when there is no previous step to return to. */\nexport function visibleButtons(step: GuideStep, canGoBack: boolean): GuideStep[\"buttons\"] {\n return canGoBack ? step.buttons : step.buttons.filter((b) => b.action !== \"back\");\n}\n\n/** Validation beyond Zod shape: returns human-readable problems that block publishing. */\nexport interface ValidationIssue {\n level: \"error\" | \"warning\";\n stepId?: string;\n message: string;\n}\nexport function validateGuideConfig(kind: GuideKind, config: GuideConfig, theme?: Partial<Pick<ProjectTheme, \"primaryColor\" | \"backgroundColor\" | \"textColor\">>): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n if (kind === \"checklist\") {\n if (!config.checklist || config.checklist.tasks.length === 0) issues.push({ level: \"error\", message: \"Checklist needs at least one task.\" });\n } else if (kind === \"survey\") {\n if (!config.survey || config.survey.questions.length === 0) issues.push({ level: \"error\", message: \"Survey needs at least one question.\" });\n config.survey?.questions.forEach((q) => {\n if ((q.type === \"single_choice\" || q.type === \"multiple_choice\") && q.options.length < 2) issues.push({ level: \"error\", message: `Question \"${q.title}\" needs at least two options.` });\n });\n } else {\n if (config.steps.length === 0) issues.push({ level: \"error\", message: \"Add at least one step.\" });\n }\n if (config.platforms.length === 0) issues.push({ level: \"error\", message: \"Choose at least one platform (web, iOS or Android).\" });\n const mobile = config.platforms.some((p) => p !== \"web\");\n const ids = new Set<string>();\n config.steps.forEach((step, i) => {\n if (ids.has(step.id)) issues.push({ level: \"error\", stepId: step.id, message: `Duplicate step id \"${step.id}\".` });\n ids.add(step.id);\n const anchored = [\"tooltip\", \"popover\", \"spotlight\", \"hotspot\"].includes(step.type);\n if (anchored && (!step.target || step.target.selectors.length === 0)) issues.push({ level: \"error\", stepId: step.id, message: `Step ${i + 1} (${step.type}) needs a target element.` });\n if (mobile && anchored && step.target && step.target.selectors.length > 0 && !step.target.selectors.some((s) => s.kind === \"guidely-id\" || s.kind === \"id\"))\n issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} has no Guidely id or element id target, so mobile apps cannot find its element.` });\n if (mobile && step.type === \"custom\") issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} is a custom HTML step; mobile apps show it as a plain modal.` });\n if (!step.title && !step.body && step.type !== \"custom\") issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} has no title or body.` });\n if (step.buttons.length === 0 && step.advanceOn === \"button\" && step.type !== \"hotspot\" && step.type !== \"custom\") issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} has no buttons and advances on button; users can only close it.` });\n step.buttons.forEach((b) => {\n if (b.action === \"url\" && !/^https?:\\/\\//i.test(b.value || \"\") && !(b.value || \"\").startsWith(\"/\")) issues.push({ level: \"error\", stepId: step.id, message: `Button \"${b.label}\" needs an http(s) or relative URL.` });\n if (b.action === \"start_guide\" && !b.value) issues.push({ level: \"error\", stepId: step.id, message: `Button \"${b.label}\" needs a guide to start.` });\n });\n step.branches.forEach((br) => {\n if (!ids.has(br.goTo) && !config.steps.some((s) => s.id === br.goTo)) issues.push({ level: \"error\", stepId: step.id, message: `Branch points to unknown step \"${br.goTo}\".` });\n });\n });\n if (config.trigger.type === \"event\" && !config.trigger.value) issues.push({ level: \"error\", message: \"Event trigger needs an event name.\" });\n if (config.trigger.type === \"element_click\" && !config.trigger.value) issues.push({ level: \"error\", message: \"Element click trigger needs a selector.\" });\n if (config.trigger.type === \"url_match\" && !config.trigger.value) issues.push({ level: \"error\", message: \"URL trigger needs a pattern.\" });\n if (config.frequency.mode === \"interval\" && !config.frequency.intervalHours) issues.push({ level: \"error\", message: \"Interval frequency needs an interval in hours.\" });\n const sched = config.schedule;\n if (sched?.startAt && sched.endAt && Date.parse(sched.endAt) <= Date.parse(sched.startAt)) issues.push({ level: \"error\", message: \"The schedule ends before it starts.\" });\n if (sched?.endAt && Date.parse(sched.endAt) < Date.now()) issues.push({ level: \"warning\", message: \"The schedule has already ended, so nobody will see this guide.\" });\n config.steps.forEach((step, i) => {\n if (step.code && step.type !== \"custom\") issues.push({ level: \"error\", stepId: step.id, message: `Step ${i + 1}: code blocks can only run in custom steps.` });\n if (step.code && mobile) issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} runs a code block; mobile apps skip it.` });\n });\n const colors = { primaryColor: config.appearance.primaryColor ?? theme?.primaryColor, backgroundColor: config.appearance.backgroundColor ?? theme?.backgroundColor, textColor: config.appearance.textColor ?? theme?.textColor };\n for (const c of contrastIssues(colors)) issues.push({ level: \"warning\", message: `Low contrast: ${c.message}` });\n return issues;\n}\n\nexport interface ProjectTheme {\n primaryColor: string;\n backgroundColor: string;\n textColor: string;\n borderRadius: number;\n fontFamily: string;\n logoUrl?: string;\n brandName?: string;\n customCss?: string;\n}\nexport const ProjectThemeSchema = z.object({\n primaryColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default(\"#4f46e5\"),\n backgroundColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default(\"#ffffff\"),\n textColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default(\"#111827\"),\n borderRadius: z.number().int().min(0).max(32).default(12),\n fontFamily: z.string().max(200).default(\"Inter, system-ui, -apple-system, sans-serif\"),\n logoUrl: z.string().max(2000).optional(),\n brandName: z.string().max(100).optional(),\n /** Custom CSS applied to every guide's container (sanitized and scoped like guide CSS). Web only. */\n customCss: z.string().max(20000).optional(),\n});\n\nexport type { RuleGroup };\n","/**\n * WCAG 2.1 colour contrast (zod-free). The editor warns when a guide's colours fall below AA:\n * 4.5:1 for body text, 3:1 for large text and UI components (button outlines, the close icon).\n */\n\nexport const WCAG_AA_TEXT = 4.5;\nexport const WCAG_AA_LARGE = 3;\n\nfunction channel(c: number): number {\n const s = c / 255;\n return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n}\n\n/** `#rgb` / `#rrggbb` → [r, g, b]; null when not a hex colour. */\nexport function parseHexColor(hex: string | null | undefined): [number, number, number] | null {\n if (!hex) return null;\n const m = hex.trim().match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);\n if (!m) return null;\n const h = m[1]!.length === 3 ? m[1]!.split(\"\").map((c) => c + c).join(\"\") : m[1]!;\n return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];\n}\n\nexport function relativeLuminance(hex: string): number | null {\n const rgb = parseHexColor(hex);\n if (!rgb) return null;\n return 0.2126 * channel(rgb[0]) + 0.7152 * channel(rgb[1]) + 0.0722 * channel(rgb[2]);\n}\n\n/** Contrast ratio 1–21 between two hex colours, or null when either is not a hex colour. */\nexport function contrastRatio(a: string, b: string): number | null {\n const la = relativeLuminance(a);\n const lb = relativeLuminance(b);\n if (la === null || lb === null) return null;\n const [hi, lo] = la > lb ? [la, lb] : [lb, la];\n return Math.round(((hi + 0.05) / (lo + 0.05)) * 100) / 100;\n}\n\n/** Text colour (black or white) with the better contrast on `background`. */\nexport function readableTextOn(background: string): \"#ffffff\" | \"#111827\" {\n const white = contrastRatio(background, \"#ffffff\") ?? 0;\n const dark = contrastRatio(background, \"#111827\") ?? 0;\n return white >= dark ? \"#ffffff\" : \"#111827\";\n}\n\nexport interface ContrastIssue {\n /** What is hard to read. */\n pair: \"text\" | \"button\" | \"link\";\n ratio: number;\n required: number;\n message: string;\n}\n\n/**\n * Contrast problems of a guide's effective colours (guide appearance over the project theme).\n * Buttons use white or dark text, whichever reads better, so only a mid-tone primary colour fails.\n */\nexport function contrastIssues(colors: { primaryColor?: string; backgroundColor?: string; textColor?: string }): ContrastIssue[] {\n const issues: ContrastIssue[] = [];\n const { primaryColor, backgroundColor, textColor } = colors;\n if (textColor && backgroundColor) {\n const r = contrastRatio(textColor, backgroundColor);\n if (r !== null && r < WCAG_AA_TEXT) issues.push({ pair: \"text\", ratio: r, required: WCAG_AA_TEXT, message: `Text on the background has a contrast of ${r}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });\n }\n if (primaryColor) {\n const label = contrastRatio(primaryColor, readableTextOn(primaryColor));\n if (label !== null && label < WCAG_AA_TEXT) issues.push({ pair: \"button\", ratio: label, required: WCAG_AA_TEXT, message: `Button labels on the primary colour have a contrast of ${label}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });\n if (backgroundColor) {\n const link = contrastRatio(primaryColor, backgroundColor);\n if (link !== null && link < WCAG_AA_LARGE) issues.push({ pair: \"link\", ratio: link, required: WCAG_AA_LARGE, message: `The primary colour on the background (links, outlined buttons) has a contrast of ${link}:1; WCAG AA needs ${WCAG_AA_LARGE}:1.` });\n }\n }\n return issues;\n}\n","import { z } from \"zod\";\n\nexport const EVENT_NAMES = [\n \"guide_viewed\",\n \"guide_started\",\n \"step_viewed\",\n \"step_completed\",\n \"guide_completed\",\n \"guide_skipped\",\n \"guide_dismissed\",\n \"guide_abandoned\",\n \"checklist_task_completed\",\n \"checklist_completed\",\n \"checklist_dismissed\",\n \"survey_displayed\",\n \"survey_submitted\",\n \"survey_dismissed\",\n \"resource_center_opened\",\n \"article_viewed\",\n \"messenger_opened\",\n \"conversation_started\",\n \"conversation_handed_off\",\n \"scout_answered\",\n \"custom\",\n \"page_view\",\n \"identify\",\n // Product analytics (autocapture + error tracking)\n \"page_leave\",\n \"click\",\n \"rage_click\",\n \"exception\",\n \"heatmap\",\n // Feature flags: a user was bucketed into an experiment variation (properties: experimentKey, variationId, flagKey).\n \"experiment_viewed\",\n // Mobile app lifecycle (mobile/SPEC.md \"Product analytics\"): installs, updates, opens and backgrounding.\n \"app_install\",\n \"app_update\",\n \"app_open\",\n \"app_background\",\n] as const;\nexport type EventName = (typeof EVENT_NAMES)[number];\n\n/** Events the SDK records on its own (page analytics, click autocapture, error tracking). */\nexport const AUTOCAPTURE_EVENTS = [\"page_view\", \"page_leave\", \"click\", \"rage_click\", \"exception\", \"heatmap\", \"app_install\", \"app_update\", \"app_open\", \"app_background\"] as const;\n\n/** Mobile app lifecycle events (`autocapture.appLifecycle`). */\nexport const APP_LIFECYCLE_EVENTS = [\"app_install\", \"app_update\", \"app_open\", \"app_background\"] as const;\n\nexport const GUIDE_LIFECYCLE_EVENTS = [\"guide_viewed\", \"guide_started\", \"step_viewed\", \"step_completed\", \"guide_completed\", \"guide_skipped\", \"guide_dismissed\", \"guide_abandoned\"] as const;\n\n/** Event as produced by the SDK and accepted by POST /api/v1/sdk/events */\nexport const SdkEventSchema = z.object({\n eventId: z.string().min(8).max(64),\n name: z.enum(EVENT_NAMES),\n /** For `custom` events: the application-defined name. */\n customName: z.string().min(1).max(120).optional(),\n occurredAt: z.string().datetime({ offset: true }),\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n accountId: z.string().max(256).optional().nullable(),\n sessionId: z.string().max(128).optional(),\n guideId: z.string().max(64).optional(),\n guideVersion: z.number().int().optional(),\n stepId: z.string().max(64).optional(),\n stepIndex: z.number().int().min(0).optional(),\n url: z.string().max(2000).optional(),\n properties: z.record(z.unknown()).optional(),\n});\nexport type SdkEvent = z.infer<typeof SdkEventSchema>;\n\nexport const EventBatchSchema = z.object({\n events: z.array(SdkEventSchema).min(1).max(50),\n sentAt: z.string().datetime({ offset: true }).optional(),\n sdk: z.object({ name: z.string().max(60), version: z.string().max(30) }).optional(),\n});\nexport type EventBatch = z.infer<typeof EventBatchSchema>;\n\nexport * from \"./events-util\";\nexport * from \"./errors\";\n","/** Reserved property names that are stripped from `properties` to avoid collecting sensitive data. */\nexport const SENSITIVE_PROPERTY_PATTERN = /(password|passwd|secret|token|credit|card|cvv|ssn|iban)/i;\n\nexport const MAX_PROPERTY_BYTES = 8 * 1024;\n\nexport function sanitizeProperties(props: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!props) return {};\n const out: Record<string, unknown> = {};\n let size = 0;\n for (const [k, v] of Object.entries(props)) {\n if (SENSITIVE_PROPERTY_PATTERN.test(k)) continue;\n if (typeof v === \"function\" || typeof v === \"symbol\") continue;\n const str = typeof v === \"string\" ? v : JSON.stringify(v ?? null);\n size += k.length + (str?.length ?? 0);\n if (size > MAX_PROPERTY_BYTES) break;\n out[k.slice(0, 100)] = typeof v === \"string\" ? v.slice(0, 1000) : v;\n }\n return out;\n}\n","import { fnv1a } from \"./utils\";\n\n/** One parsed stack frame. `file` is the script URL (or path) as the browser reported it. */\nexport interface StackFrame {\n fn?: string;\n file?: string;\n line?: number;\n col?: number;\n}\n\n/** Properties carried by an `exception` event (see `docs/product-analytics.md`). */\nexport interface ExceptionProperties {\n type: string;\n message: string;\n frames: StackFrame[];\n /** `onerror` | `unhandledrejection` | `manual` (captureException) | `console`. */\n source?: string;\n handled?: boolean;\n /** App version or commit (SDK option `release`); selects the matching uploaded source maps. */\n release?: string;\n /** Set by the server at ingestion; groups occurrences into an issue. */\n fingerprint?: string;\n}\n\nexport const MAX_STACK_FRAMES = 30;\n\n// Chrome / Edge / Node: \" at fn (https://x/app.js:1:2)\" or \" at https://x/app.js:1:2\"\nconst V8 = /^\\s*at (?:(.+?) \\()?((?:[a-z][\\w+.-]*:)?[^\\s()]+?):(\\d+):(\\d+)\\)?\\s*$/i;\n// Firefox / Safari: \"fn@https://x/app.js:1:2\" or \"@https://x/app.js:1:2\"\nconst GECKO = /^\\s*(.*?)@(.+?):(\\d+):(\\d+)\\s*$/;\n\n/** Parses `Error.stack` from V8, SpiderMonkey and JavaScriptCore into frames (innermost first). */\nexport function parseStack(stack: string | undefined | null, max = MAX_STACK_FRAMES): StackFrame[] {\n if (!stack || typeof stack !== \"string\") return [];\n const frames: StackFrame[] = [];\n for (const raw of stack.split(\"\\n\")) {\n if (frames.length >= max) break;\n const line = raw.slice(0, 1000);\n const m = V8.exec(line) ?? GECKO.exec(line);\n if (!m) continue;\n const fn = (m[1] || \"\").trim();\n frames.push({ fn: fn ? fn.slice(0, 200) : undefined, file: m[2]?.slice(0, 500), line: Number(m[3]), col: Number(m[4]) });\n }\n return frames;\n}\n\n/** Replaces volatile parts of a message (numbers, ids, quoted values) so repeats group together. */\nexport function normalizeErrorMessage(message: string): string {\n return (message || \"\")\n .slice(0, 500)\n .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, \"<uuid>\")\n .replace(/([\"'`]).*?\\1/g, \"<str>\")\n .replace(/\\b0x[0-9a-f]+\\b/gi, \"<hex>\")\n .replace(/\\d+(\\.\\d+)?/g, \"<n>\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/** Strips origin, query, hash and build hashes (`main.3f2a1b9c.js` → `main.js`) from a script URL. */\nexport function normalizeFrameFile(file: string | undefined): string {\n if (!file) return \"\";\n let path = file;\n try {\n path = new URL(file).pathname;\n } catch {\n path = file.replace(/[?#].*$/, \"\");\n }\n return path.replace(/[.-][0-9a-f]{6,}(?=\\.\\w+$)/i, \"\").replace(/\\/\\d+\\//g, \"/<n>/\");\n}\n\n/** Source map upload limits (`POST /api/v1/sourcemaps/upload`). */\n/** Per map, uncompressed (the CLI uploads maps gzipped). */\nexport const SOURCEMAP_MAX_FILE_BYTES = 100 * 1024 * 1024;\nexport const SOURCEMAP_MAX_FILES_PER_UPLOAD = 200;\n\n/**\n * Stable issue key for an exception: error type + normalised message + the innermost frame that\n * has a file (path without build hash + function name, or its original source + name when a source\n * map resolved it). Line/column numbers are left out because they change with every deploy of a\n * minified bundle.\n */\nexport function fingerprintError(input: { type?: string; message?: string; frames?: StackFrame[]; original?: { source: string; name?: string | null } | null }): string {\n const top = (input.frames ?? []).find((f) => f.file);\n // With a source map the original file and function name identify the frame across deploys, even\n // when a minifier renames functions between builds.\n const frameKey = input.original ? `src:${input.original.source}:${input.original.name || \"?\"}` : top ? `${normalizeFrameFile(top.file)}:${top.fn || \"?\"}` : \"\";\n const key = [input.type || \"Error\", normalizeErrorMessage(input.message || \"\"), frameKey].join(\"|\");\n const a = fnv1a(key).toString(16).padStart(8, \"0\");\n const b = fnv1a(`guidely:${key}`).toString(16).padStart(8, \"0\");\n return a + b;\n}\n","import { z } from \"zod\";\nimport { GuideConfigSchema, ProjectThemeSchema, type GuideKind, type GuideConfig } from \"./guide\";\nimport type { RuleGroup } from \"./targeting-eval\";\nimport type { ResourceCenterModuleId } from \"./resource-center\";\nimport type { MessengerConfig } from \"./messenger\";\nimport type { AutocaptureSettings, ErrorTrackingSettings, ReplaySettings } from \"./capture\";\nimport type { TaggingSdkConfig } from \"./tagging\";\n\n/** A published guide as delivered to the SDK. Draft-only data (author, notes) is never included. */\nexport interface PublishedGuide {\n id: string;\n key: string;\n name: string;\n kind: GuideKind;\n version: number;\n config: GuideConfig;\n publishedAt: string;\n /**\n * Set while the guide is a variant of a running guide A/B test. Its targeting already carries the\n * variant's `experiment.bucket` range; SDKs record an `experiment_viewed` exposure\n * (`{ guideExperimentId, variantId, guideId }`) when it shows.\n */\n experiment?: { id: string; variantId: string };\n}\n\n/**\n * The control group of a running guide A/B test: the base guide's targeting, trigger and frequency\n * restricted to the control bucket. SDKs evaluate it like a guide but never render it; when it would\n * show they record the `experiment_viewed` exposure (variant `control`) and its local impression.\n * SDKs that don't know `guideHoldouts` ignore it (control visitors then simply see nothing).\n */\nexport interface GuideHoldout {\n experimentId: string;\n variantId: string;\n guide: PublishedGuide;\n}\n\n/** Project-wide limit on automatically shown guides (Project.settings.guideThrottling). */\nexport interface GuideThrottlingSettings {\n enabled: boolean;\n /** At most this many auto-launched guides per visitor within `windowHours`. */\n maxGuides: number;\n windowHours: number;\n /** Minimum minutes between two auto-launched guides. */\n minGapMinutes: number;\n}\n\nexport interface ResourceCenterArticle {\n id: string;\n slug: string;\n title: string;\n summary: string;\n body: string;\n /** True when `body` was left out of the config to keep it small; fetch it from `GET /sdk/articles/:id`. */\n bodyOmitted?: boolean;\n collectionId?: string | null;\n externalUrl?: string | null;\n /** Listed only for members of any of these audiences (absent = everyone). Not access control. */\n audienceIds?: string[];\n /** Guide keys of the article's \"Show me\" prompts (absent = none); the first one is offered in Help results. */\n walkthroughs?: string[];\n /** The article plays a video. */\n hasVideo?: boolean;\n updatedAt: string;\n /** Translations by locale; a `bodyOmitted` translation is fetched with `GET /sdk/articles/:id?locale=`. */\n translations?: Record<string, { title?: string; summary?: string; body?: string; bodyOmitted?: boolean }>;\n}\n\n/** A \"What's new\" entry in the resource center. */\nexport interface ResourceCenterAnnouncement {\n id: string;\n title: string;\n /** Sanitized HTML. */\n body: string;\n publishedAt: string;\n /** Guide id or key started by its \"Show me\" button. */\n guideId?: string | null;\n articleId?: string | null;\n url?: string | null;\n linkLabel?: string | null;\n /** Listed only for members of any of these audiences (absent = everyone). */\n audienceIds?: string[];\n translations?: Record<string, { title?: string; body?: string }>;\n}\n\n/** A section of the resource center, in display order; hidden when disabled or its targeting doesn't match. */\nexport interface ResourceCenterModule {\n id: ResourceCenterModuleId;\n enabled: boolean;\n /** Evaluated by the SDK like guide targeting (absent = everyone). */\n targeting?: RuleGroup | null;\n}\n\nexport interface ResourceCenterCollection {\n id: string;\n name: string;\n description: string;\n order: number;\n /** Parent collection for nested collections (absent/null = top level). */\n parentId?: string | null;\n /** Listed only for members of any of these audiences, with everything inside it (absent = everyone). */\n audienceIds?: string[];\n}\n\nexport interface ResourceCenterConfig {\n enabled: boolean;\n title: string;\n launcher: { position: \"bottom-right\" | \"bottom-left\"; label: string; showIcon: boolean };\n collections: ResourceCenterCollection[];\n articles: ResourceCenterArticle[];\n recommendedGuideIds: string[];\n checklistGuideIds: string[];\n links: Array<{ id: string; label: string; url: string }>;\n faqs: Array<{ id: string; question: string; answer: string }>;\n /** \"What's new\" (newest first). Absent from servers that predate it. */\n announcements?: ResourceCenterAnnouncement[];\n /** Section order and targeting; absent = every section in the default order. */\n modules?: ResourceCenterModule[];\n /** Translations of the strings above (see `resourceCenterTextEntries`), by locale. */\n translations?: Record<string, Record<string, string>>;\n}\n\nexport interface SdkConfigResponse {\n projectId: string;\n environment: string;\n configVersion: number;\n theme: z.infer<typeof ProjectThemeSchema>;\n guides: PublishedGuide[];\n /** Control groups of running guide A/B tests (see GuideHoldout); absent from older servers. */\n guideHoldouts?: GuideHoldout[];\n resourceCenter: ResourceCenterConfig | null;\n /** Scout messenger; absent from servers that predate it. */\n messenger?: MessengerConfig | null;\n settings: {\n analyticsEnabled: boolean;\n collectUrls: boolean;\n maskSelectors: string[];\n sessionTimeoutMinutes: number;\n /** Product analytics; absent from servers that predate it (the SDK then captures nothing extra). */\n autocapture?: AutocaptureSettings;\n errorTracking?: ErrorTrackingSettings;\n /** `retentionDays` is server-side only and not sent. */\n replay?: Omit<ReplaySettings, \"retentionDays\">;\n /** Project-wide guide throttling; absent or disabled = no limit. */\n throttling?: GuideThrottlingSettings;\n /** The language guides are written in, and the languages they may be translated into. */\n localization?: { defaultLocale: string; locales: string[] };\n };\n /** Tagged pages and features: the feature attribute and DOM event properties; absent from servers that predate them. */\n tagging?: TaggingSdkConfig;\n generatedAt: string;\n}\n\nexport const IdentifyRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().min(1).max(256).optional().nullable(),\n traits: z.record(z.unknown()).optional(),\n account: z\n .object({ id: z.string().min(1).max(256), traits: z.record(z.unknown()).optional() })\n .optional()\n .nullable(),\n sessionId: z.string().max(128).optional(),\n url: z.string().max(2000).optional(),\n});\nexport type IdentifyRequest = z.infer<typeof IdentifyRequestSchema>;\n\n/** Server-held state the SDK needs for targeting & frequency. */\nexport interface IdentifyResponse {\n endUserId: string;\n audienceIds: string[];\n guideState: Record<\n string,\n { impressions: number; completedAt?: string | null; dismissedAt?: string | null; lastShownAt?: string | null }\n >;\n /** `dismissResetAt` changes when a teammate resets the user's dismissal; SDKs then drop their cached `dismissedAt`. */\n checklistProgress: Record<string, { completedTaskIds: string[]; completedAt?: string | null; dismissedAt?: string | null; dismissResetAt?: string | null }>;\n surveysSubmitted: string[];\n firstSeenAt: string;\n}\n\nexport const ChecklistProgressRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n guideVersion: z.number().int().optional(),\n completedTaskIds: z.array(z.string().max(64)).max(100),\n dismissed: z.boolean().optional(),\n completed: z.boolean().optional(),\n});\nexport type ChecklistProgressRequest = z.infer<typeof ChecklistProgressRequestSchema>;\n\nexport const SurveyResponseRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n accountId: z.string().max(256).optional().nullable(),\n guideVersion: z.number().int(),\n answers: z.record(z.union([z.string().max(5000), z.number(), z.boolean(), z.array(z.string().max(500)).max(50)])),\n responseId: z.string().min(8).max(64),\n});\nexport type SurveyResponseRequest = z.infer<typeof SurveyResponseRequestSchema>;\n\nexport const GuideStateUpdateSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n updates: z\n .array(\n z.object({\n guideId: z.string(),\n impression: z.boolean().optional(),\n completed: z.boolean().optional(),\n dismissed: z.boolean().optional(),\n }),\n )\n .max(50),\n});\n\nexport const AuthoringPickSchema = z.object({\n stepId: z.string().max(64).optional(),\n selectors: z.array(z.object({ kind: z.string(), value: z.string().max(1000), label: z.string().max(200).optional() })).max(10),\n textSnapshot: z.string().max(200).optional(),\n url: z.string().max(2000).optional(),\n rect: z.object({ x: z.number(), y: z.number(), width: z.number(), height: z.number() }).optional(),\n /** Compact snapshot of the picked element (tag mode: feature rules are proposed from it). */\n elementSnapshot: z.record(z.unknown()).optional(),\n});\nexport type AuthoringPick = z.infer<typeof AuthoringPickSchema>;\n\n/**\n * Static, script-free copy of the page an authoring session is connected to. The SDK posts it to\n * the dashboard (never to the API) so the editor canvas can show the customer's real app.\n */\nexport interface AppSnapshot {\n /** Full HTML document (doctype included) with scripts and Guidely UI removed and a `<base>` pointing at `url`. */\n html: string;\n url: string;\n title: string;\n /** Viewport the snapshot was taken at, in CSS pixels. */\n width: number;\n height: number;\n capturedAt: string;\n}\n\nexport interface AuthoringSessionInfo {\n id: string;\n projectId: string;\n environment: string;\n guideId: string | null;\n dashboardOrigin: string;\n expiresAt: string;\n /** `tag`: the session tags pages and features (no guide); absent or `guide` for the guide editor. */\n purpose?: \"guide\" | \"tag\";\n /** Draft guide config to preview while authoring (not published). */\n draft: { id: string; key: string; name: string; kind: GuideKind; config: GuideConfig } | null;\n}\n\nexport const PublishedGuideSchema = z.object({\n id: z.string(),\n key: z.string(),\n name: z.string(),\n kind: z.string(),\n version: z.number(),\n config: GuideConfigSchema,\n publishedAt: z.string(),\n});\n\nexport interface ApiError {\n error: { code: string; message: string; details?: unknown };\n}\n","import { z } from \"zod\";\nimport type { HowToStepKind, NormalizedRect } from \"./howto\";\nimport type { ResourceCenterCollection } from \"./sdk-api\";\nimport type { MessengerComplaint, MessengerComplaintOffer, MessengerComplaintsConfig } from \"./complaints-limits\";\nimport type { MessengerIdeaOffer, MessengerIdeasConfig } from \"./feedback-limits\";\n\n/** How quickly the team usually replies, shown on the messenger home screen. */\nexport const REPLY_TIMES = [\"minutes\", \"hour\", \"hours\", \"day\"] as const;\nexport type ReplyTime = (typeof REPLY_TIMES)[number];\n\n/** Levels of the status card on the messenger home screen. */\nexport const STATUS_LEVELS = [\"operational\", \"degraded\", \"outage\", \"maintenance\"] as const;\nexport type StatusLevel = (typeof STATUS_LEVELS)[number];\n\n/** A teammate shown on the messenger home screen (first name only). */\nexport interface MessengerTeammate {\n name: string;\n avatarUrl: string | null;\n}\n\nexport interface MessengerStatus {\n level: StatusLevel;\n message: string;\n updatedAt: string;\n}\n\n/** Which personalised cards the messenger home screen shows. */\nexport interface MessengerHomeCards {\n /** Guides, how-tos, articles and common questions for the page the user is on. */\n suggestions: boolean;\n /** A guide the user started and didn't finish, and checklist progress. */\n progress: boolean;\n /** Live announcements (also the News tab). */\n news: boolean;\n}\n\n/** Messenger settings delivered to the SDK in `SdkConfigResponse.messenger`. */\nexport interface MessengerConfig {\n enabled: boolean;\n /** Display name of the AI agent (\"Scout\"). */\n name: string;\n greeting: string;\n /** Scout answers with AI; when false every conversation goes to the team inbox. */\n aiAvailable: boolean;\n handoffEnabled: boolean;\n launcher: { position: \"bottom-right\" | \"bottom-left\" };\n /** Absent from servers before the personalised home screen; SDKs fall back to their defaults. */\n replyTime?: ReplyTime | null;\n team?: MessengerTeammate[];\n status?: MessengerStatus | null;\n home?: MessengerHomeCards;\n /** Complaint categories when the project takes complaints in the messenger (absent from older servers). */\n complaints?: MessengerComplaintsConfig | null;\n /** The Ideas tab (feature requests) when the project turned it on (absent from older servers). */\n ideas?: MessengerIdeasConfig | null;\n}\n\n/** Page-matched content for the messenger, from `POST /sdk/messenger/page`. */\nexport type MessengerPageSuggestion =\n | { type: \"article\"; articleId: string; title: string; summary: string }\n /** A how-to recorded on this page, opened as its help article. */\n | { type: \"howto\"; articleId: string; title: string; steps: number };\n\nexport interface MessengerPageContent {\n /** The page as matched: its path with ids folded (`/invoices/:id`). */\n path: string;\n label: string | null;\n suggestions: MessengerPageSuggestion[];\n /** Questions people ask on this page (FAQs and learned answers); tapping one asks Scout. */\n questions: string[];\n}\n\nexport const MessengerPageRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n /** Pathname only: query strings and fragments are never sent. */\n path: z.string().min(1).max(1000),\n});\nexport type MessengerPageRequest = z.infer<typeof MessengerPageRequestSchema>;\n\nexport const MESSAGE_AUTHORS = [\"user\", \"scout\", \"agent\", \"system\"] as const;\nexport type MessageAuthor = (typeof MESSAGE_AUTHORS)[number];\nexport type ConversationStatus = \"bot\" | \"open\" | \"closed\";\n\nexport interface MessengerCitation {\n articleId: string;\n title: string;\n}\n\nexport interface MessengerSuggestedGuide {\n key: string;\n name: string;\n}\n\n/** A how-to Scout relied on; the messenger opens it in place (`GET /sdk/how-tos/:id`). */\nexport interface MessengerHowToCitation {\n howToId: string;\n title: string;\n}\n\nexport interface MessengerMessage {\n id: string;\n author: MessageAuthor;\n /** Team member name for `agent` messages. */\n authorName?: string | null;\n body: string;\n citations: MessengerCitation[];\n suggestedGuides: MessengerSuggestedGuide[];\n /** How-tos Scout cited (absent when none; SDKs before how-to support ignore it). */\n howTos?: MessengerHowToCitation[];\n /** Scout offered the complaint form (absent otherwise). */\n complaintOffer?: MessengerComplaintOffer;\n /** Scout offered to file or upvote a feature request (absent otherwise). */\n ideaOffer?: MessengerIdeaOffer;\n status: \"pending\" | \"complete\" | \"failed\";\n createdAt: string;\n}\n\nexport interface MessengerConversation {\n id: string;\n status: ConversationStatus;\n subject: string;\n lastMessageAt: string;\n lastMessagePreview: string;\n unread: number;\n rating: number | null;\n /** The complaint filed in this conversation, latest first (absent when none). */\n complaint?: MessengerComplaint;\n}\n\nexport const MAX_MESSAGE_LENGTH = 4000;\nconst messageText = z.string().trim().min(1).max(MAX_MESSAGE_LENGTH);\n\nexport const StartConversationSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n message: messageText,\n pageUrl: z.string().max(2000).optional(),\n});\nexport type StartConversationRequest = z.infer<typeof StartConversationSchema>;\n\nexport interface StartConversationResponse {\n conversation: MessengerConversation;\n /** Secret that authorises this browser to read and post in the conversation. Store it; it is not shown again. */\n token: string;\n messages: MessengerMessage[];\n}\n\nexport const ConversationLookupSchema = z.object({\n tokens: z.array(z.string().min(16).max(128)).max(50),\n});\n\nexport interface ConversationLookupResponse {\n conversations: Array<MessengerConversation & { token: string }>;\n}\n\nexport const PostMessageSchema = z.object({\n message: messageText,\n /** The page the user is on now (omitted when URL collection is off and by older SDKs), so Scout answers for that page. */\n pageUrl: z.string().max(2000).optional(),\n});\n\nexport const ConversationRatingSchema = z.object({\n rating: z.number().int().min(1).max(5),\n comment: z.string().max(1000).optional(),\n});\n\nexport interface FileComplaintResponse {\n complaint: MessengerComplaint;\n conversation: MessengerConversation;\n /** Token of the conversation started for it (absent when it was filed in an existing one). */\n token?: string;\n}\n\nexport interface ConversationMessagesResponse {\n conversation: MessengerConversation;\n messages: MessengerMessage[];\n}\n\n/**\n * Server-sent events streamed by `POST /sdk/conversations` and `POST /sdk/conversations/:id/messages`\n * while Scout replies. `conversation` (start only) carries the new conversation and its token, `message`\n * each stored message, `delta` reply text as it is generated, and `done` the final stored message.\n */\nexport type ScoutStreamEvent =\n | { event: \"conversation\"; data: StartConversationResponse }\n | { event: \"message\"; data: MessengerMessage }\n | { event: \"delta\"; data: { messageId: string; text: string } }\n | { event: \"done\"; data: { message: MessengerMessage; conversation: MessengerConversation } }\n | { event: \"error\"; data: { message: string } };\n\n/** Article list entry for the messenger Help tab (bodies are fetched on demand). */\nexport interface SdkArticleSummary {\n id: string;\n slug: string;\n title: string;\n summary: string;\n collectionId: string | null;\n externalUrl: string | null;\n /** Listed only for members of these audiences (absent = everyone). */\n audienceIds?: string[];\n /** Guide keys of the article's \"Show me\" prompts (absent = none). */\n walkthroughs?: string[];\n hasVideo?: boolean;\n updatedAt: string;\n}\n\nexport interface SdkArticlesResponse {\n collections: ResourceCenterCollection[];\n articles: SdkArticleSummary[];\n}\n\n/** A how-to the team made available in the app (`GET /sdk/how-tos`). */\nexport interface SdkHowToSummary {\n id: string;\n title: string;\n description: string;\n /** Numbered (recorded) steps. */\n stepCount: number;\n /** Key of the interactive tour made from it, when that tour is live in this environment (\"Show me\"). */\n guideKey?: string;\n /** The how-to has a video. */\n hasVideo?: boolean;\n updatedAt: string;\n}\n\nexport interface SdkHowTosResponse {\n /** Every how-to available in the app, by title (at most 200). */\n howTos: SdkHowToSummary[];\n /** Ids of the ones recorded on the page in `?url=`, best match first (at most 5). */\n forPage: string[];\n}\n\n/** One step as the messenger renders it: text only, plus a screenshot with the element's highlight. */\nexport interface SdkHowToStep {\n id: string;\n kind: HowToStepKind;\n title: string;\n body: string;\n image?: {\n url: string;\n /** Show only this part of the screenshot (zoomed in on the element). */\n crop?: NormalizedRect;\n /** The element, in the coordinates of the (cropped) image. */\n highlight?: NormalizedRect;\n };\n}\n\n/** `GET /sdk/how-tos/:id`: an available how-to with its steps. */\nexport interface SdkHowTo {\n id: string;\n title: string;\n description: string;\n updatedAt: string;\n steps: SdkHowToStep[];\n /** Key of the interactive tour made from it, when that tour is live in this environment (\"Show me\"). */\n guideKey?: string;\n /** Video made from the how-to (WebM), played above the steps. */\n video?: { url: string };\n}\n","import { z } from \"zod\";\nimport { MAX_COMPLAINT_ANSWER_LENGTH, MAX_COMPLAINT_ATTACHMENT_BYTES, MAX_COMPLAINT_LENGTH } from \"./complaints-limits\";\n\nexport * from \"./complaints-limits\";\n\nexport const FileComplaintSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n categoryId: z.string().min(1).max(64),\n description: z.string().trim().min(1).max(MAX_COMPLAINT_LENGTH),\n /** Answers to the category's extra questions, by field id. */\n answers: z.record(z.string().max(64), z.string().trim().max(MAX_COMPLAINT_ANSWER_LENGTH)).default({}),\n /** Required from visitors the app hasn't identified. */\n email: z.string().trim().toLowerCase().email().max(254).optional().nullable(),\n pageUrl: z.string().max(2000).optional(),\n /** File it in this conversation (send its token in `X-Guidely-Conversation`); otherwise a new one is started. */\n conversationId: z.string().min(1).max(64).optional().nullable(),\n /** One screenshot, base64-encoded (png, jpeg, webp or gif). */\n attachment: z\n .object({\n fileName: z.string().trim().min(1).max(200),\n data: z.string().max(Math.ceil((MAX_COMPLAINT_ATTACHMENT_BYTES * 4) / 3) + 4),\n })\n .optional()\n .nullable(),\n});\nexport type FileComplaintRequest = z.infer<typeof FileComplaintSchema>;\n","/** Complaint types and limits shared by the server and the messenger runtime (zod-free). */\n\n/** Where a complaint is in its handling; the messenger shows it as Received → In review → Resolved. */\nexport const COMPLAINT_STATUSES = [\"open\", \"in_review\", \"resolved\"] as const;\nexport type ComplaintStatus = (typeof COMPLAINT_STATUSES)[number];\n\n/** Events a complaint webhook can fire on. */\nexport const COMPLAINT_EVENTS = [\"complaint.filed\", \"complaint.status_changed\", \"complaint.replied\", \"complaint.resolved\"] as const;\nexport type ComplaintEvent = (typeof COMPLAINT_EVENTS)[number];\n\n/** Extra questions a category asks for. */\nexport const COMPLAINT_FIELD_TYPES = [\"text\", \"choice\"] as const;\nexport type ComplaintFieldType = (typeof COMPLAINT_FIELD_TYPES)[number];\n\nexport const MAX_COMPLAINT_FIELDS = 8;\nexport const MAX_COMPLAINT_CHOICES = 12;\nexport const MAX_COMPLAINT_LENGTH = 4000;\nexport const MAX_COMPLAINT_ANSWER_LENGTH = 500;\n/** Largest screenshot the messenger may attach (after it scales the image down). */\nexport const MAX_COMPLAINT_ATTACHMENT_BYTES = 2 * 1024 * 1024;\n\nexport interface ComplaintField {\n /** Stable id (`invoice_number`), used as the answer's key in webhook payloads. */\n id: string;\n label: string;\n type: ComplaintFieldType;\n /** Choices for `choice` questions. */\n options?: string[];\n required: boolean;\n}\n\n/** \"CMP-1042\" for complaint number 1042. */\nexport const complaintReference = (number: number) => `CMP-${number}`;\n\n/** A category as the messenger offers it. */\nexport interface MessengerComplaintCategory {\n id: string;\n name: string;\n description: string;\n color: string;\n fields: ComplaintField[];\n}\n\n/** Complaints block of `MessengerConfig`; absent when the project doesn't take complaints. */\nexport interface MessengerComplaintsConfig {\n categories: MessengerComplaintCategory[];\n /** Visitors the app hasn't identified may file one (with an email address). */\n anonymous: boolean;\n}\n\n/** A complaint as the person who filed it sees it (on its conversation). */\nexport interface MessengerComplaint {\n id: string;\n reference: string;\n status: ComplaintStatus;\n categoryName: string;\n createdAt: string;\n}\n\n/** Scout offered the complaint form in a reply, with this category picked. */\nexport interface MessengerComplaintOffer {\n categoryId: string;\n name: string;\n}\n","import { z } from \"zod\";\nimport {\n AGENT_METADATA_MAX_BYTES,\n AGENT_METADATA_MAX_KEYS,\n AGENT_OUTCOMES,\n AGENT_TOOL_CALLS_PER_TURN,\n AGENT_TOOL_STATUSES,\n AGENT_TURN_MAX_TEXT,\n AGENT_TURN_ROLES,\n AGENT_TURNS_PER_BATCH,\n SCOUT_AGENT_ID,\n} from \"./agents-limits\";\nimport { SENSITIVE_PROPERTY_PATTERN } from \"./events-util\";\n\nexport * from \"./agents-limits\";\n\nconst ENVIRONMENTS = [\"development\", \"staging\", \"production\"] as const;\n\n/** A tool call: name, status and latency only. Anything else (arguments, results) is dropped, never stored. */\nexport const AgentToolCallSchema = z\n .object({\n name: z.string().trim().min(1).max(100),\n status: z.enum(AGENT_TOOL_STATUSES).optional(),\n latencyMs: z.number().int().min(0).max(3_600_000).optional(),\n })\n .strip();\n\n/**\n * Flat metadata: string, number, boolean or null values (others, such as nested objects, are dropped).\n * Keys starting with `$` (reserved) and keys that look sensitive (password, token, card…) are dropped;\n * strings are cut to 500 characters, and keys past the count or size limit are left out.\n */\nexport const AgentMetadataSchema = z\n .record(z.string().max(100), z.unknown())\n .transform((m) => {\n const out: Record<string, string | number | boolean | null> = {};\n let size = 0;\n for (const [k, v] of Object.entries(m)) {\n const key = k.trim();\n if (!key || key.startsWith(\"$\") || SENSITIVE_PROPERTY_PATTERN.test(key)) continue;\n if (!(typeof v === \"string\" || typeof v === \"boolean\" || v === null || (typeof v === \"number\" && Number.isFinite(v)))) continue;\n const value = typeof v === \"string\" ? v.slice(0, 500) : v;\n size += key.length + String(value).length;\n if (size > AGENT_METADATA_MAX_BYTES || Object.keys(out).length >= AGENT_METADATA_MAX_KEYS) break;\n out[key] = value;\n }\n return out;\n });\n\nconst id = (max: number) => z.string().trim().min(1).max(max);\nconst optionalId = (max: number) => z.string().trim().max(max).optional().nullable().transform((v) => v || null);\n\nexport const AgentTurnInputSchema = z.object({\n type: z.literal(\"agent.conversation\").optional(),\n conversationId: id(128),\n agentId: id(64).refine((v) => v.toLowerCase() !== SCOUT_AGENT_ID, { message: `\"${SCOUT_AGENT_ID}\" is reserved for Guidely's built-in Scout agent` }),\n agentName: z.string().trim().max(100).optional(),\n turnId: z.string().trim().min(1).max(128).optional(),\n role: z.enum(AGENT_TURN_ROLES),\n text: z.string().max(AGENT_TURN_MAX_TEXT).default(\"\"),\n toolCalls: z.array(AgentToolCallSchema).max(AGENT_TOOL_CALLS_PER_TURN).default([]),\n latencyMs: z.number().int().min(0).max(3_600_000).optional(),\n outcome: z.enum(AGENT_OUTCOMES).optional(),\n taskSuccess: z.boolean().optional(),\n occurredAt: z.string().datetime({ offset: true }).optional(),\n userId: optionalId(256),\n anonymousId: optionalId(128),\n accountId: optionalId(256),\n sessionId: optionalId(128),\n metadata: AgentMetadataSchema.default({}),\n});\nexport type AgentTurn = z.output<typeof AgentTurnInputSchema>;\n\nconst turns = z.array(AgentTurnInputSchema).min(1).max(AGENT_TURNS_PER_BATCH);\nconst sdkInfo = z.object({ name: z.string().max(60), version: z.string().max(30) }).optional();\n\n/** Body of `POST /api/v1/sdk/agent-events` (browser SDK, public key). */\nexport const SdkAgentEventsSchema = z.object({ turns, sdk: sdkInfo });\nexport type SdkAgentEvents = z.output<typeof SdkAgentEventsSchema>;\n\n/**\n * Body of `POST /api/v1/agent-events` (server to server, secret key): `{ turns: [...], environment? }`,\n * a bare array of turns, or a single turn (with `environment` beside its fields).\n */\nexport const AgentEventsRequestSchema = z.preprocess(\n (v) => {\n if (Array.isArray(v)) return { turns: v };\n if (v && typeof v === \"object\" && !(\"turns\" in v)) {\n const { environment, ...turn } = v as Record<string, unknown>;\n return { turns: [turn], environment };\n }\n return v;\n },\n z.object({ turns, environment: z.enum(ENVIRONMENTS).default(\"production\"), sdk: sdkInfo }),\n);\nexport type AgentEventsRequest = z.output<typeof AgentEventsRequestSchema>;\n","/**\n * Agent Analytics: the `agent.conversation` turn the customer's own AI agents send (zod-free, so the\n * browser SDK can use the types and limits without bundling the schema). The schema is in agents.ts.\n */\n\nexport const AGENT_TURN_ROLES = [\"user\", \"assistant\", \"tool\", \"system\"] as const;\nexport type AgentTurnRole = (typeof AGENT_TURN_ROLES)[number];\n\n/** How a conversation ended, as the agent reports it. */\nexport const AGENT_OUTCOMES = [\"success\", \"failure\", \"escalated\", \"abandoned\"] as const;\nexport type AgentOutcome = (typeof AGENT_OUTCOMES)[number];\n\nexport const AGENT_TOOL_STATUSES = [\"ok\", \"error\"] as const;\nexport type AgentToolStatus = (typeof AGENT_TOOL_STATUSES)[number];\n\n/** Longest turn text accepted (characters). */\nexport const AGENT_TURN_MAX_TEXT = 20_000;\n/** Most turns in one request. */\nexport const AGENT_TURNS_PER_BATCH = 100;\n/** Most tool calls on one turn. */\nexport const AGENT_TOOL_CALLS_PER_TURN = 50;\n/** Metadata: at most this many keys, string values up to 500 characters, 4 KB in all. */\nexport const AGENT_METADATA_MAX_KEYS = 30;\nexport const AGENT_METADATA_MAX_BYTES = 4096;\n/** The built-in Scout agent's id; customer agents can't use it. */\nexport const SCOUT_AGENT_ID = \"scout\";\n\n/** One tool the agent called in a turn. Arguments and results are never sent or stored. */\nexport interface AgentToolCallInput {\n name: string;\n status?: AgentToolStatus;\n latencyMs?: number;\n}\n\n/** One `agent.conversation` turn. */\nexport interface AgentTurnInput {\n type?: \"agent.conversation\";\n /** Your conversation (thread) id. */\n conversationId: string;\n /** Your agent's id, e.g. \"support-bot\". The agent is created on its first turn. */\n agentId: string;\n /** Display name for a new agent (defaults to agentId). */\n agentName?: string;\n /** Idempotency key: a turn sent twice with the same id is stored once. */\n turnId?: string;\n role: AgentTurnRole;\n text?: string;\n toolCalls?: AgentToolCallInput[];\n /** How long the agent took to produce this turn (assistant turns). */\n latencyMs?: number;\n /** How the conversation ended, when this turn ends it (the latest reported outcome wins). */\n outcome?: AgentOutcome;\n /** Whether the person got what they came for, when the agent knows. */\n taskSuccess?: boolean;\n /** ISO 8601 time of the turn (default: when Guidely receives it). */\n occurredAt?: string;\n userId?: string | null;\n anonymousId?: string | null;\n accountId?: string | null;\n sessionId?: string | null;\n /** Flat key/value pairs (strings, numbers, booleans), e.g. { model: \"gpt-4.1\" }. */\n metadata?: Record<string, string | number | boolean | null>;\n}\n\n/** Response of both ingestion endpoints. */\nexport interface AgentEventsResponse {\n accepted: number;\n duplicates: number;\n /** Turns refused (an agent past the per-project limit, or a conversation past its turn limit). */\n rejected?: number;\n /** Turns dropped because this month's product analytics allowance is used up. */\n overLimit?: number;\n}\n","import { z } from \"zod\";\nimport { FEEDBACK_PRIORITIES, FEEDBACK_STATUSES, MAX_FEEDBACK_COMMENT, MAX_FEEDBACK_DESCRIPTION, MAX_FEEDBACK_NOTE, MAX_FEEDBACK_TITLE } from \"./feedback-limits\";\n\nexport * from \"./feedback-limits\";\n\n/** Who is asking, as the SDK (or the portal session) knows them. Unverified unless it came from a signed link. */\nconst visitor = {\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n};\n\nexport const FeedbackListRequestSchema = z.object({\n ...visitor,\n q: z.string().trim().max(200).optional(),\n sort: z.enum([\"top\", \"new\", \"trending\"]).default(\"top\"),\n status: z.enum(FEEDBACK_STATUSES).optional(),\n /** \"open\" = not released or declined. */\n filter: z.enum([\"open\", \"all\", \"mine\", \"following\"]).default(\"open\"),\n productArea: z.string().trim().max(60).optional(),\n page: z.number().int().min(1).max(100).default(1),\n});\nexport type FeedbackListRequest = z.infer<typeof FeedbackListRequestSchema>;\n\nexport const FeedbackVisitorSchema = z.object(visitor);\nexport type FeedbackVisitorRequest = z.infer<typeof FeedbackVisitorSchema>;\n\nexport const SubmitFeedbackSchema = z.object({\n ...visitor,\n title: z.string().trim().min(3, \"Give your idea a short title\").max(MAX_FEEDBACK_TITLE),\n description: z.string().trim().max(MAX_FEEDBACK_DESCRIPTION).default(\"\"),\n productArea: z.string().trim().max(60).optional().nullable(),\n priority: z.enum(FEEDBACK_PRIORITIES).default(\"nice_to_have\"),\n /** Filed from this Scout conversation (Scout offered it). */\n conversationId: z.string().min(1).max(64).optional().nullable(),\n pageUrl: z.string().max(2000).optional(),\n});\nexport type SubmitFeedbackRequest = z.infer<typeof SubmitFeedbackSchema>;\n\nexport const FeedbackVoteSchema = z.object({\n ...visitor,\n priority: z.enum(FEEDBACK_PRIORITIES).default(\"nice_to_have\"),\n note: z.string().trim().max(MAX_FEEDBACK_NOTE).optional(),\n conversationId: z.string().min(1).max(64).optional().nullable(),\n});\nexport type FeedbackVoteRequest = z.infer<typeof FeedbackVoteSchema>;\n\nexport const FeedbackFollowSchema = z.object({ ...visitor, follow: z.boolean() });\nexport const FeedbackCommentSchema = z.object({ ...visitor, body: z.string().trim().min(1).max(MAX_FEEDBACK_COMMENT) });\nexport const FeedbackSimilarSchema = z.object({ ...visitor, title: z.string().trim().min(3).max(MAX_FEEDBACK_TITLE) });\nexport const FeedbackUpdatesReadSchema = z.object({ ...visitor, ids: z.array(z.string().min(1).max(64)).max(100).optional() });\n","/** Feedback (feature requests) types and limits shared by the server, the portal and the messenger runtime (zod-free). */\n\n/** Where a request is: shown to end users with FEEDBACK_STATUS_LABEL. */\nexport const FEEDBACK_STATUSES = [\"new\", \"under_review\", \"planned\", \"in_progress\", \"released\", \"declined\"] as const;\nexport type FeedbackStatus = (typeof FEEDBACK_STATUSES)[number];\n\nexport const FEEDBACK_STATUS_LABEL: Record<FeedbackStatus, string> = {\n new: \"New\",\n under_review: \"Under review\",\n planned: \"Planned\",\n in_progress: \"In progress\",\n released: \"Released\",\n declined: \"Declined\",\n};\n\n/** How much a voter needs it; weights 1 / 2 / 3 in the priority score. */\nexport const FEEDBACK_PRIORITIES = [\"nice_to_have\", \"important\", \"critical\"] as const;\nexport type FeedbackPriority = (typeof FEEDBACK_PRIORITIES)[number];\n\nexport const FEEDBACK_PRIORITY_LABEL: Record<FeedbackPriority, string> = { nice_to_have: \"Nice to have\", important: \"Important\", critical: \"Critical\" };\nexport const FEEDBACK_PRIORITY_WEIGHT: Record<FeedbackPriority, number> = { nice_to_have: 1, important: 2, critical: 3 };\n\n/** Events feedback integrations (Slack, webhooks) can get. */\nexport const FEEDBACK_EVENTS = [\"request.created\", \"request.status_changed\", \"request.voted\"] as const;\nexport type FeedbackEvent = (typeof FEEDBACK_EVENTS)[number];\n\nexport const MAX_FEEDBACK_TITLE = 140;\nexport const MAX_FEEDBACK_DESCRIPTION = 4000;\nexport const MAX_FEEDBACK_COMMENT = 2000;\nexport const MAX_FEEDBACK_NOTE = 500;\n\n/** \"#42\" for request number 42. */\nexport const feedbackReference = (number: number) => `#${number}`;\n\n/** A request as end users see it (messenger Ideas tab, portal). */\nexport interface PublicFeedbackRequest {\n id: string;\n number: number;\n title: string;\n description: string;\n status: FeedbackStatus;\n /** Public note shown with the status, when the team wrote one. */\n statusNote: string;\n productArea: string | null;\n votes: number;\n comments: number;\n /** This visitor's vote, if any. */\n myVote: { priority: FeedbackPriority } | null;\n following: boolean;\n /** The visitor submitted it. */\n mine: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PublicFeedbackComment {\n id: string;\n authorName: string;\n /** \"team\" replies are shown with a badge. */\n authorType: \"user\" | \"team\";\n body: string;\n createdAt: string;\n}\n\nexport interface PublicFeedbackRequestDetail extends PublicFeedbackRequest {\n thread: PublicFeedbackComment[];\n}\n\nexport interface PublicFeedbackList {\n requests: PublicFeedbackRequest[];\n hasMore: boolean;\n}\n\n/** An update about a request the visitor follows (status changed, merged). */\nexport interface FeedbackUpdate {\n id: string;\n requestId: string | null;\n kind: \"status\" | \"merged\" | \"comment\";\n title: string;\n body: string;\n read: boolean;\n createdAt: string;\n}\n\nexport interface FeedbackUpdatesResponse {\n updates: FeedbackUpdate[];\n unread: number;\n}\n\n/** Ideas block of `MessengerConfig`; absent when the project hasn't turned on the Ideas tab. */\nexport interface MessengerIdeasConfig {\n /** Tab and heading title. */\n title: string;\n /** Visitors the app hasn't identified may vote and submit (otherwise they can only browse). */\n anonymous: boolean;\n /** Votes and new ideas need a signed identity: the messenger only browses and links to the portal. */\n readOnly: boolean;\n /** Product areas people may tag new ideas with. */\n productAreas: string[];\n /** The hosted portal is on (the messenger offers \"Open the portal\"). */\n portal: boolean;\n}\n\n/** Scout offered to file or upvote a feature request in a reply. */\nexport interface MessengerIdeaOffer {\n /** The matching request to upvote, or null to suggest a new one. */\n requestId: string | null;\n title: string;\n /** Prefilled description for a new idea (the person's words, summarised). */\n description: string;\n votes?: number;\n}\n","import { z } from \"zod\";\n\n/**\n * Product-analytics capture settings. Stored on `Project.settings` (keys `autocapture`,\n * `errorTracking`, `replay`) and delivered to the SDK in `SdkConfigResponse.settings`. The project\n * setting turns a capability on; SDK options can only turn it off for one installation.\n */\nexport interface AutocaptureSettings {\n /** `page_view` on load and on every SPA navigation. */\n pageviews: boolean;\n /** `page_leave` with visible time on page and scroll depth. */\n pageLeave: boolean;\n /** `click` on buttons, links and other interactive elements. */\n clicks: boolean;\n /** `rage_click` when the same spot is clicked 3+ times within a second. */\n rageClicks: boolean;\n /** Batched click positions on every element (`heatmap` events) for click heatmaps. */\n heatmaps: boolean;\n /** Mouse-movement heatmaps: pointer position sampled while it moves, aggregated in the browser into `heatmap` events. */\n mouseMovement: boolean;\n /**\n * Mobile SDKs: `app_install`, `app_update`, `app_open` and `app_background` events (ignored on the web).\n * Optional in the type for older stored settings; `resolveCaptureSettings` always fills it.\n */\n appLifecycle?: boolean;\n}\n\nexport interface ErrorTrackingSettings {\n /** Uncaught errors and unhandled promise rejections become `exception` events. */\n enabled: boolean;\n}\n\nexport interface ReplaySettings {\n enabled: boolean;\n /** Percentage of sessions recorded (0–100), decided once per session. */\n sampleRate: number;\n /** Record console.log/warn/error output into the recording. */\n recordConsole: boolean;\n /** Record network requests (method, URL with sensitive query values redacted, status, timing, size). */\n recordNetwork: boolean;\n /** Also record request/response headers and text/JSON bodies (redacted, ≤10KB each). Off by default. */\n recordNetworkPayloads: boolean;\n /** Mask every text node (inputs are always masked). */\n maskAllText: boolean;\n /** Elements replaced by a placeholder box in recordings (in addition to `[data-guidely-block]`). */\n blockSelectors: string[];\n /** Days recordings are kept before the worker deletes them. */\n retentionDays: number;\n}\n\nexport interface CaptureSettings {\n autocapture: AutocaptureSettings;\n errorTracking: ErrorTrackingSettings;\n replay: ReplaySettings;\n}\n\nexport const AutocaptureSettingsSchema = z.object({ pageviews: z.boolean(), pageLeave: z.boolean(), clicks: z.boolean(), rageClicks: z.boolean(), heatmaps: z.boolean(), mouseMovement: z.boolean(), appLifecycle: z.boolean() }).partial();\nexport const ErrorTrackingSettingsSchema = z.object({ enabled: z.boolean() }).partial();\nexport const ReplaySettingsSchema = z\n .object({\n enabled: z.boolean(),\n sampleRate: z.number().int().min(0).max(100),\n recordConsole: z.boolean(),\n recordNetwork: z.boolean(),\n recordNetworkPayloads: z.boolean(),\n maskAllText: z.boolean(),\n blockSelectors: z.array(z.string().min(1).max(200)).max(50),\n retentionDays: z.number().int().min(1).max(365),\n })\n .partial();\n\nexport const DEFAULT_CAPTURE_SETTINGS: CaptureSettings = {\n autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true, appLifecycle: true },\n errorTracking: { enabled: true },\n replay: { enabled: false, sampleRate: 100, recordConsole: true, recordNetwork: true, recordNetworkPayloads: false, maskAllText: false, blockSelectors: [], retentionDays: 30 },\n};\n\n/** Fills defaults for whatever a project's stored settings leave out. */\nexport function resolveCaptureSettings(settings: unknown): CaptureSettings {\n const s = (settings && typeof settings === \"object\" ? settings : {}) as Record<string, unknown>;\n const obj = (v: unknown) => (v && typeof v === \"object\" && !Array.isArray(v) ? (v as Record<string, unknown>) : {});\n const d = DEFAULT_CAPTURE_SETTINGS;\n const a = AutocaptureSettingsSchema.safeParse(obj(s.autocapture));\n const e = ErrorTrackingSettingsSchema.safeParse(obj(s.errorTracking));\n const r = ReplaySettingsSchema.safeParse(obj(s.replay));\n return {\n autocapture: { ...d.autocapture, ...(a.success ? a.data : {}) },\n errorTracking: { ...d.errorTracking, ...(e.success ? e.data : {}) },\n replay: { ...d.replay, ...(r.success ? r.data : {}) },\n };\n}\n\n/**\n * One position in a `heatmap` event (`properties.points`). `x`/`y` are page coordinates in CSS\n * pixels; `s` is a stable selector for the element and `rx`/`ry` the position inside it (0–1), which\n * lets the dashboard place the point on the element even when layouts differ.\n *\n * Mouse movement (`k: \"m\"`) is sampled at most every 200ms while the pointer moves and binned in the\n * browser (per element at 0.1 of `rx`/`ry`, else on a 16px page grid); `w` is the number of samples\n * in the bin, so a minute of movement costs a few dozen points rather than thousands.\n */\nexport interface HeatmapPoint {\n /** `c` click, `r` part of a rage-click burst, `m` mouse movement. */\n k: \"c\" | \"r\" | \"m\";\n x: number;\n y: number;\n s?: string;\n rx?: number;\n ry?: number;\n /** Weight: samples aggregated into this point (movement only; clicks are 1). */\n w?: number;\n}\n\n/** Properties of a `heatmap` event: a batch of clicks on one page (flushed at ~40 points and on page leave). */\nexport interface HeatmapProperties {\n path?: string;\n viewportWidth: number;\n viewportHeight: number;\n /** Document scroll height when the batch was sent. */\n pageHeight: number;\n points: HeatmapPoint[];\n}\n\n/** Viewport buckets heatmaps are split by (CSS px of `viewportWidth`). */\nexport const HEATMAP_VIEWPORTS = { mobile: [0, 767], tablet: [768, 1279], desktop: [1280, 100_000] } as const;\nexport type HeatmapViewport = keyof typeof HEATMAP_VIEWPORTS;\n\n/**\n * One upload of rrweb events for a recording, `POST /api/v1/sdk/replay`. The SDK sends it as JSON,\n * or gzip-compressed JSON with `?enc=gzip`. A recording is keyed by the SDK session id; every page\n * load starts a new `windowId` whose uploads are numbered by `seq`.\n */\nexport const ReplayChunkSchema = z.object({\n sessionId: z.string().min(1).max(128),\n windowId: z.string().min(1).max(64),\n seq: z.number().int().min(0).max(1_000_000),\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n /** rrweb `eventWithTime` objects, in order. */\n events: z.array(z.object({ type: z.number().int(), timestamp: z.number() }).passthrough()).min(1).max(50_000),\n url: z.string().max(2000).optional(),\n device: z.object({ type: z.string().max(20), browser: z.string().max(40).optional(), os: z.string().max(40).optional() }).optional(),\n viewport: z.object({ width: z.number().int().min(0).max(100_000), height: z.number().int().min(0).max(100_000) }).optional(),\n sdk: z.object({ name: z.string().max(60), version: z.string().max(30) }).optional(),\n});\nexport type ReplayChunk = z.infer<typeof ReplayChunkSchema>;\n\n/** Max upload sizes for one replay chunk (bytes on the wire, and after decompression). */\nexport const REPLAY_MAX_COMPRESSED_BYTES = 2 * 1024 * 1024;\nexport const REPLAY_MAX_RAW_BYTES = 16 * 1024 * 1024;\n","/* Network requests recorded into session replays (zod-free: imported by the SDK recorder). */\n\n/** rrweb plugin name for network events in recordings (event type 6, `data.plugin`). */\nexport const NETWORK_PLUGIN = \"guidely/network@1\";\n\n/** Request kinds, from `fetch`/`XMLHttpRequest` patching or `PerformanceResourceTiming.initiatorType`. */\nexport type NetworkRequestType = \"fetch\" | \"xhr\" | \"websocket\" | \"document\" | \"script\" | \"stylesheet\" | \"image\" | \"font\" | \"media\" | \"beacon\" | \"other\";\n\n/**\n * One network request in a recording: the payload of an rrweb plugin event\n * `{ type: 6, data: { plugin: NETWORK_PLUGIN, payload: NetworkPluginPayload } }`, batched.\n * Times are epoch milliseconds (same clock as rrweb event timestamps).\n *\n * A WebSocket is a request with `type: \"websocket\"` and `method: \"GET\"`, emitted when it opens\n * (`startTime`) and again, with the same `id`, when it closes (`endTime`, `closeCode`, `closeReason`,\n * totals in `messages`). Its frames are `WebSocketMessage`s referencing that `id`.\n */\nexport interface NetworkRequest {\n /** Stable id within the recording. */\n id: string;\n type: NetworkRequestType;\n method: string;\n /** Absolute URL; values of sensitive-looking query parameters replaced with `[redacted]`. */\n url: string;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n /** HTTP status; 0 for network errors / blocked / aborted. Absent when the browser doesn't expose it. */\n status?: number;\n /** Set for failed requests: network error, abort or timeout message. */\n error?: string;\n /** Encoded bytes transferred / decoded response size, when known. */\n transferSize?: number;\n responseSize?: number;\n /** Only when `recordNetworkPayloads` is on; sensitive headers are `[redacted]`. */\n requestHeaders?: Record<string, string>;\n responseHeaders?: Record<string, string>;\n /** Text/JSON bodies, ≤10KB, sensitive JSON fields masked; `[binary]` / `[truncated]` markers otherwise. */\n requestBody?: string;\n responseBody?: string;\n /** WebSocket only: negotiated subprotocol, close details, and frame totals (all frames, including ones not recorded). */\n protocol?: string;\n closeCode?: number;\n closeReason?: string;\n messages?: { sent: number; received: number; sentBytes: number; receivedBytes: number; recorded: number };\n}\n\n/** One WebSocket frame. At most `WS_MAX_MESSAGES_PER_SOCKET` are recorded per connection per page load. */\nexport interface WebSocketMessage {\n /** The `NetworkRequest.id` of the connection. */\n socketId: string;\n dir: \"send\" | \"recv\";\n time: number;\n /** Bytes (UTF-8 length for text frames). */\n size: number;\n binary?: boolean;\n /** Only with `recordNetworkPayloads`: text ≤ 2KB (JSON with sensitive keys masked), else `[truncated]`; binary frames are `[binary <n> B]`. */\n data?: string;\n}\n\nexport interface NetworkPluginPayload {\n requests?: NetworkRequest[];\n messages?: WebSocketMessage[];\n /** Requests/frames dropped since the previous payload because a cap was reached. */\n dropped?: { requests?: number; messages?: number };\n}\n\nexport const WS_MAX_MESSAGES_PER_SOCKET = 200;\nexport const WS_MAX_MESSAGE_BYTES = 2048;\n\n/** Header names always replaced with `[redacted]` when payload capture is on. */\nexport const SENSITIVE_HEADER_PATTERN = /^(authorization|proxy-authorization|cookie|set-cookie|x-api-key|x-auth-token|x-csrf-token|x-xsrf-token|x-guidely-key|x-guidely-conversation)$/i;\n\n/** Query parameter and JSON field names whose values are redacted. */\nexport const SENSITIVE_PARAM_PATTERN = /(token|key|secret|password|passwd|pwd|auth|session|code|sig|signature|credential|ssn|card|cvv|iban)/i;\n","import { GuideConfigSchema, type GuideConfigInput, type GuideKind } from \"./guide\";\n\nexport interface GuideTemplate {\n id: string;\n name: string;\n description: string;\n kind: GuideKind;\n category: \"onboarding\" | \"feature\" | \"setup\" | \"forms\" | \"announcement\" | \"help\" | \"feedback\";\n config: GuideConfigInput;\n}\n\nconst nav = (opts: { last?: boolean; first?: boolean } = {}) =>\n [\n ...(opts.first ? [] : [{ id: \"back\", label: \"Back\", action: \"back\" as const, variant: \"ghost\" as const }]),\n opts.last\n ? { id: \"done\", label: \"Finish\", action: \"complete\" as const, variant: \"primary\" as const }\n : { id: \"next\", label: \"Next\", action: \"next\" as const, variant: \"primary\" as const },\n ];\n\nexport const GUIDE_TEMPLATES: GuideTemplate[] = [\n {\n id: \"new-user-onboarding\",\n name: \"New-user onboarding tour\",\n description: \"A welcome modal followed by three anchored steps that introduce the main navigation.\",\n kind: \"flow\",\n category: \"onboarding\",\n config: {\n steps: [\n { id: \"welcome\", type: \"modal\", title: \"Welcome aboard 👋\", body: \"<p>We'll show you around in under a minute. You can skip at any time.</p>\", showOverlay: true, buttons: [{ id: \"skip\", label: \"Skip tour\", action: \"dismiss\", variant: \"ghost\" }, { id: \"start\", label: \"Show me around\", action: \"next\" }] },\n { id: \"nav\", type: \"tooltip\", title: \"Your navigation\", body: \"<p>Everything lives in the sidebar. Switch between dashboards, contacts and settings here.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='sidebar']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", buttons: nav() },\n { id: \"create\", type: \"spotlight\", title: \"Create your first record\", body: \"<p>Use the primary button to add something new. We'll highlight it for you.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='primary-action']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", showOverlay: true, buttons: nav() },\n { id: \"help\", type: \"tooltip\", title: \"Need help later?\", body: \"<p>Open the help menu any time to replay this tour or browse the resource center.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='help']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", buttons: nav({ last: true }) },\n ],\n trigger: { type: \"page_load\" },\n frequency: { mode: \"once\", priority: 10 },\n targeting: { id: \"root\", op: \"and\", rules: [{ id: \"r1\", field: \"visitor.firstVisit\", op: \"is_true\" }] },\n },\n },\n {\n id: \"feature-discovery\",\n name: \"First-time feature discovery\",\n description: \"A hotspot that draws attention to a new capability and expands into a tooltip.\",\n kind: \"tooltip\",\n category: \"feature\",\n config: {\n steps: [{ id: \"hotspot\", type: \"hotspot\", title: \"New: smart filters\", body: \"<p>Filters now understand natural language. Try <em>“deals closing this month”</em>.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='filters']\" }], waitMs: 8000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", buttons: [{ id: \"got-it\", label: \"Got it\", action: \"complete\" }], hotspot: { size: 14, pulse: true, openOn: \"click\" }, showProgress: false }],\n trigger: { type: \"element_visible\", value: \"[data-tour='filters']\" },\n frequency: { mode: \"once\", maxImpressions: 3, priority: 50 },\n },\n },\n {\n id: \"setup-wizard\",\n name: \"Setup wizard\",\n description: \"Multi-step modal wizard that walks a new admin through initial configuration with branching.\",\n kind: \"flow\",\n category: \"setup\",\n config: {\n steps: [\n { id: \"intro\", type: \"modal\", title: \"Let's set up your workspace\", body: \"<p>Three quick steps: invite your team, connect a data source, and choose a plan.</p>\", showOverlay: true, buttons: [{ id: \"later\", label: \"Later\", action: \"dismiss\", variant: \"ghost\" }, { id: \"go\", label: \"Start setup\", action: \"next\" }] },\n { id: \"team\", type: \"popover\", title: \"Invite teammates\", body: \"<p>Guidely works best with your whole team. Add a few emails here.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='invite']\" }], waitMs: 5000, fallback: \"show_as_modal\", scrollIntoView: true }, buttons: nav() },\n { id: \"data\", type: \"popover\", title: \"Connect a data source\", body: \"<p>Import contacts from a CSV or connect your CRM.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='import']\" }], waitMs: 5000, fallback: \"show_as_modal\", scrollIntoView: true }, buttons: nav() },\n { id: \"done\", type: \"modal\", title: \"You're ready 🎉\", body: \"<p>That's it. Explore the dashboard, and open the help menu if you get stuck.</p>\", showOverlay: true, buttons: nav({ last: true }) },\n ],\n trigger: { type: \"page_load\", urlPattern: \"/dashboard\" },\n frequency: { mode: \"once\", priority: 20 },\n targeting: { id: \"root\", op: \"and\", rules: [{ id: \"r1\", field: \"user.role\", op: \"equals\", value: \"admin\" }] },\n },\n },\n {\n id: \"form-completion\",\n name: \"Form completion helper\",\n description: \"Tooltips that advance as the user fills out each field of a form.\",\n kind: \"flow\",\n category: \"forms\",\n config: {\n steps: [\n { id: \"name\", type: \"tooltip\", title: \"Name the contact\", body: \"<p>Use their full name so search works well.</p>\", target: { selectors: [{ kind: \"css\", value: \"input[name='name']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", advanceOn: \"element_click\", advanceValue: \"input[name='email']\", buttons: [] },\n { id: \"email\", type: \"tooltip\", title: \"Add an email\", body: \"<p>We'll use it for sequences and reminders.</p>\", target: { selectors: [{ kind: \"css\", value: \"input[name='email']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", buttons: nav() },\n { id: \"save\", type: \"spotlight\", title: \"Save\", body: \"<p>Hit save, and your contact appears in the list.</p>\", target: { selectors: [{ kind: \"css\", value: \"button[type='submit']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"top\", showOverlay: true, buttons: nav({ last: true }) },\n ],\n trigger: { type: \"url_match\", value: \"/contacts/new\" },\n frequency: { mode: \"once\", priority: 40 },\n },\n },\n {\n id: \"workflow-walkthrough\",\n name: \"Complex workflow walkthrough\",\n description: \"A multi-page flow that follows the user across routes with URL-aware steps.\",\n kind: \"flow\",\n category: \"onboarding\",\n config: {\n steps: [\n { id: \"start\", type: \"modal\", title: \"Close your first deal\", body: \"<p>We'll go from pipeline to closed-won in four steps.</p>\", showOverlay: true, buttons: [{ id: \"skip\", label: \"Not now\", action: \"dismiss\", variant: \"ghost\" }, { id: \"next\", label: \"Let's go\", action: \"next\" }] },\n { id: \"pipeline\", type: \"tooltip\", title: \"Open the pipeline\", body: \"<p>Click here to see your deals by stage.</p>\", url: \"/dashboard\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='nav-deals']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", advanceOn: \"element_click\", advanceValue: \"[data-tour='nav-deals']\", buttons: [] },\n { id: \"drag\", type: \"spotlight\", title: \"Move a deal\", body: \"<p>Drag a card to the next stage, or use the stage menu.</p>\", url: \"/deals\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='deal-card']\" }], waitMs: 8000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", showOverlay: true, buttons: nav() },\n { id: \"won\", type: \"tooltip\", title: \"Mark as won\", body: \"<p>When it closes, mark it won to update your forecast.</p>\", url: \"/deals\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='mark-won']\" }], waitMs: 8000, fallback: \"skip\", scrollIntoView: true }, placement: \"left\", buttons: nav({ last: true }) },\n ],\n trigger: { type: \"manual\" },\n frequency: { mode: \"every_time\", priority: 30 },\n },\n },\n {\n id: \"feature-announcement\",\n name: \"New feature announcement\",\n description: \"A centered modal with an image announcing a new capability.\",\n kind: \"announcement\",\n category: \"announcement\",\n config: {\n steps: [{ id: \"announce\", type: \"modal\", title: \"Introducing Reports 2.0\", body: \"<p>Build custom reports with drag-and-drop metrics, scheduled emails and shareable links.</p><ul><li>12 new chart types</li><li>Export to CSV and PDF</li></ul>\", imageUrl: \"https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&q=60\", showOverlay: true, buttons: [{ id: \"later\", label: \"Maybe later\", action: \"dismiss\", variant: \"ghost\" }, { id: \"try\", label: \"Try it now\", action: \"url\", value: \"/reports\" }], showProgress: false }],\n trigger: { type: \"page_load\", delayMs: 1500 },\n frequency: { mode: \"once\", priority: 60 },\n },\n },\n {\n id: \"contextual-tooltip\",\n name: \"Contextual tooltip\",\n description: \"A single tooltip that appears when a specific element becomes visible.\",\n kind: \"tooltip\",\n category: \"help\",\n config: {\n steps: [{ id: \"tip\", type: \"tooltip\", title: \"Pro tip\", body: \"<p>Press <strong>⌘K</strong> to jump anywhere.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='search']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", buttons: [{ id: \"ok\", label: \"Got it\", action: \"complete\" }], showProgress: false }],\n trigger: { type: \"element_visible\", value: \"[data-tour='search']\", delayMs: 500 },\n frequency: { mode: \"once\", priority: 80 },\n },\n },\n {\n id: \"product-update-banner\",\n name: \"Product update notification\",\n description: \"A dismissible top banner linking to release notes.\",\n kind: \"banner\",\n category: \"announcement\",\n config: {\n steps: [{ id: \"banner\", type: \"banner\", title: \"\", body: \"<p><strong>Scheduled maintenance</strong> on Saturday 02:00–03:00 UTC. <a href='/status'>Read more</a>.</p>\", position: \"top\", placement: \"top\", buttons: [{ id: \"dismiss\", label: \"Dismiss\", action: \"dismiss\", variant: \"ghost\" }], showProgress: false }],\n trigger: { type: \"page_load\" },\n frequency: { mode: \"once_per_session\", priority: 90 },\n },\n },\n {\n id: \"onboarding-checklist\",\n name: \"User onboarding checklist\",\n description: \"A persistent checklist with four tasks that complete automatically from events.\",\n kind: \"checklist\",\n category: \"onboarding\",\n config: {\n steps: [],\n checklist: {\n tasks: [\n { id: \"profile\", title: \"Complete your profile\", description: \"Add a photo and your role.\", completion: \"event\", completionValue: \"profile_completed\", action: \"url\", actionValue: \"/settings/profile\" },\n { id: \"contact\", title: \"Add your first contact\", description: \"Import or create a contact.\", completion: \"event\", completionValue: \"contact_created\", action: \"url\", actionValue: \"/contacts/new\" },\n { id: \"deal\", title: \"Create a deal\", description: \"Track your first opportunity.\", completion: \"event\", completionValue: \"deal_created\", action: \"url\", actionValue: \"/deals\" },\n { id: \"tour\", title: \"Take the product tour\", description: \"A 60-second walkthrough.\", completion: \"guide_completed\", completionValue: \"new-user-onboarding\", action: \"start_guide\", actionValue: \"new-user-onboarding\", required: false },\n ],\n ordered: false,\n launcherLabel: \"Getting started\",\n position: \"bottom-right\",\n completionTitle: \"You're all set! 🎉\",\n completionBody: \"You've completed onboarding. Explore the rest of the app at your own pace.\",\n autoOpen: true,\n dismissible: true,\n },\n trigger: { type: \"page_load\" },\n frequency: { mode: \"every_time\", priority: 200 },\n },\n },\n {\n id: \"nps-survey\",\n name: \"NPS survey\",\n description: \"Net Promoter Score with a conditional follow-up question.\",\n kind: \"survey\",\n category: \"feedback\",\n config: {\n steps: [],\n survey: {\n questions: [\n { id: \"nps\", type: \"nps\", title: \"How likely are you to recommend us to a colleague?\", lowLabel: \"Not likely\", highLabel: \"Very likely\" },\n { id: \"why-low\", type: \"text\", title: \"What could we do better?\", required: false, placeholder: \"Tell us more…\", showWhen: { questionId: \"nps\", op: \"lte\", value: 6 } },\n { id: \"why-high\", type: \"text\", title: \"What do you like most?\", required: false, placeholder: \"Tell us more…\", showWhen: { questionId: \"nps\", op: \"gte\", value: 9 } },\n ],\n position: \"bottom-right\",\n },\n trigger: { type: \"page_load\", delayMs: 5000 },\n frequency: { mode: \"interval\", intervalHours: 2160, priority: 150 },\n targeting: { id: \"root\", op: \"and\", rules: [{ id: \"r1\", field: \"visitor.returning\", op: \"is_true\" }] },\n },\n },\n];\n\nexport function templateConfig(id: string) {\n const t = GUIDE_TEMPLATES.find((x) => x.id === id);\n if (!t) return null;\n return { template: t, config: GuideConfigSchema.parse(t.config) };\n}\n","/**\n * Media in article bodies: uploaded images, videos and PDFs, and video embeds from a fixed set of hosts.\n * Sanitizers (server, browser runtime) only keep an `<iframe>` whose `src` is the canonical embed URL\n * that `toEmbedUrl` produces, so authors can never point a frame anywhere else.\n *\n * An uploaded PDF reads inline, as its pages: the dashboard renders each page to an image when the\n * PDF is uploaded, and the body holds plain HTML every renderer already understands:\n *\n * <div class=\"gd-pdf\">\n * <a class=\"gd-file\" href=\"…/{id}.pdf\" target=\"_blank\">{file name}</a>\n * <div class=\"gd-pdf-pages\"><img src=\"…/{page}.webp\" alt=\"{file name}, page 1 of 12\"> …</div>\n * </div>\n *\n * Renderers that know the classes draw a swipeable page viewer with the PDF one tap away; older ones\n * show a link and the pages as images. A PDF whose pages couldn't be rendered (password-protected,\n * damaged) is just the `gd-file` link, drawn as a file card.\n */\n\nexport type EmbedProvider = \"youtube\" | \"vimeo\" | \"loom\" | \"wistia\";\n\nexport interface VideoEmbed {\n provider: EmbedProvider;\n /** Canonical player URL, safe to use as an iframe `src`. */\n src: string;\n /** Page a viewer can open instead (native SDKs show a link rather than a player). */\n watchUrl: string;\n /** Accessible iframe title. */\n title: string;\n}\n\nexport const MEDIA_IMAGE_TYPES = [\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\"] as const;\nexport const MEDIA_VIDEO_TYPES = [\"video/mp4\", \"video/webm\"] as const;\nexport const MEDIA_FILE_TYPES = [\"application/pdf\"] as const;\nexport type MediaContentType = (typeof MEDIA_IMAGE_TYPES)[number] | (typeof MEDIA_VIDEO_TYPES)[number] | (typeof MEDIA_FILE_TYPES)[number];\nexport type MediaKind = \"image\" | \"video\" | \"file\";\nexport const MEDIA_IMAGE_MAX_BYTES = 10 * 1024 * 1024;\nexport const MEDIA_VIDEO_MAX_BYTES = 200 * 1024 * 1024;\nexport const MEDIA_FILE_MAX_BYTES = 50 * 1024 * 1024;\n/** The largest upload of any type. */\nexport const MEDIA_MAX_BYTES = Math.max(MEDIA_IMAGE_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_FILE_MAX_BYTES);\n\nexport function isMediaContentType(type: string): type is MediaContentType {\n return mediaKind(type) !== null;\n}\nexport function isVideoContentType(type: string): boolean {\n return (MEDIA_VIDEO_TYPES as readonly string[]).includes(type);\n}\nexport function mediaKind(type: string): MediaKind | null {\n if ((MEDIA_IMAGE_TYPES as readonly string[]).includes(type)) return \"image\";\n if ((MEDIA_VIDEO_TYPES as readonly string[]).includes(type)) return \"video\";\n if ((MEDIA_FILE_TYPES as readonly string[]).includes(type)) return \"file\";\n return null;\n}\nexport function mediaMaxBytes(type: string): number {\n const kind = mediaKind(type);\n return kind === \"video\" ? MEDIA_VIDEO_MAX_BYTES : kind === \"file\" ? MEDIA_FILE_MAX_BYTES : MEDIA_IMAGE_MAX_BYTES;\n}\n\n/** Class marking a link as an attached file (an uploaded PDF), drawn as a file card. */\nexport const FILE_LINK_CLASS = \"gd-file\";\n/** Class of the block holding a PDF's link and its rendered pages. */\nexport const PDF_BLOCK_CLASS = \"gd-pdf\";\n/** Class of the element wrapping a PDF's page images. */\nexport const PDF_PAGES_CLASS = \"gd-pdf-pages\";\n/** Pages rendered inline per PDF; readers open the PDF itself for the rest. */\nexport const PDF_MAX_PAGES = 40;\n\n/** True for an `<a>` with the file class and an absolute http(s) `href`: render it as a file card. */\nexport function isFileLink(className: string | null | undefined, href: string | null | undefined): boolean {\n return !!className && className.split(/\\s+/).includes(FILE_LINK_CLASS) && isSafeMediaUrl(href);\n}\n\nconst YOUTUBE_ID = /^[A-Za-z0-9_-]{11}$/;\nconst VIMEO_ID = /^\\d{1,12}$/;\nconst VIMEO_HASH = /^[0-9a-f]{6,20}$/i;\nconst LOOM_ID = /^[0-9a-f]{32}$/i;\nconst WISTIA_ID = /^[a-z0-9]{10}$/i;\n\nfunction parseUrl(input: string): URL | null {\n const s = input.trim();\n if (!s) return null;\n try {\n const u = new URL(/^[a-z][a-z0-9+.-]*:/i.test(s) ? s : `https://${s}`);\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n if (u.username || u.password || (u.port && u.port !== \"443\" && u.port !== \"80\")) return null;\n return u;\n } catch {\n return null;\n }\n}\n\n/** \"1h2m3s\", \"90s\", \"90\" → seconds. */\nfunction parseStart(v: string | null): number {\n if (!v) return 0;\n if (/^\\d+$/.test(v)) return Math.min(Number(v), 86400);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(v);\n if (!m || !m[0]) return 0;\n return Math.min(Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0), 86400);\n}\n\nfunction youtube(id: string, start: number): VideoEmbed | null {\n if (!YOUTUBE_ID.test(id)) return null;\n return {\n provider: \"youtube\",\n src: `https://www.youtube-nocookie.com/embed/${id}${start ? `?start=${start}` : \"\"}`,\n watchUrl: `https://www.youtube.com/watch?v=${id}${start ? `&t=${start}s` : \"\"}`,\n title: \"YouTube video\",\n };\n}\n\nfunction vimeo(id: string, hash: string | null): VideoEmbed | null {\n if (!VIMEO_ID.test(id) || (hash !== null && !VIMEO_HASH.test(hash))) return null;\n const h = hash ? hash.toLowerCase() : null;\n return { provider: \"vimeo\", src: `https://player.vimeo.com/video/${id}${h ? `?h=${h}` : \"\"}`, watchUrl: `https://vimeo.com/${id}${h ? `/${h}` : \"\"}`, title: \"Vimeo video\" };\n}\n\n/**\n * Turns a pasted video page or player URL from YouTube, Vimeo, Loom or Wistia into its canonical\n * embed. Returns null for anything else, including lookalike hosts.\n */\nexport function toEmbedUrl(input: string): VideoEmbed | null {\n const u = parseUrl(input);\n if (!u) return null;\n const host = u.hostname.toLowerCase().replace(/^www\\./, \"\");\n const parts = u.pathname.split(\"/\").filter(Boolean);\n switch (host) {\n case \"youtube.com\":\n case \"m.youtube.com\":\n case \"youtube-nocookie.com\": {\n const start = parseStart(u.searchParams.get(\"start\") ?? u.searchParams.get(\"t\"));\n if (parts[0] === \"watch\" && parts.length === 1) return youtube(u.searchParams.get(\"v\") ?? \"\", start);\n if ((parts[0] === \"embed\" || parts[0] === \"shorts\" || parts[0] === \"live\") && parts.length === 2) return youtube(parts[1]!, start);\n return null;\n }\n case \"youtu.be\":\n return parts.length === 1 ? youtube(parts[0]!, parseStart(u.searchParams.get(\"t\") ?? u.searchParams.get(\"start\"))) : null;\n case \"vimeo.com\":\n if (parts.length === 1) return vimeo(parts[0]!, null);\n if (parts.length === 2 && VIMEO_ID.test(parts[0]!)) return vimeo(parts[0]!, parts[1]!);\n return null;\n case \"player.vimeo.com\":\n return parts[0] === \"video\" && parts.length === 2 ? vimeo(parts[1]!, u.searchParams.get(\"h\")) : null;\n case \"loom.com\":\n if ((parts[0] === \"share\" || parts[0] === \"embed\") && parts.length === 2 && LOOM_ID.test(parts[1]!)) {\n const id = parts[1]!.toLowerCase();\n return { provider: \"loom\", src: `https://www.loom.com/embed/${id}`, watchUrl: `https://www.loom.com/share/${id}`, title: \"Loom video\" };\n }\n return null;\n default: {\n let id: string | undefined;\n if (host === \"fast.wistia.net\" || host === \"fast.wistia.com\") id = parts[0] === \"embed\" && parts[1] === \"iframe\" && parts.length === 3 ? parts[2] : undefined;\n else if (host === \"wi.st\" || host === \"wistia.com\" || /^[a-z0-9-]+\\.wistia\\.com$/.test(host)) id = parts[0] === \"medias\" && parts.length === 2 ? parts[1] : undefined;\n if (!id || !WISTIA_ID.test(id)) return null;\n return { provider: \"wistia\", src: `https://fast.wistia.net/embed/iframe/${id}`, watchUrl: `https://fast.wistia.net/embed/iframe/${id}`, title: \"Wistia video\" };\n }\n }\n}\n\n/** True only for a canonical embed URL (exactly what `toEmbedUrl` returns), so an iframe can't be pointed elsewhere. */\nexport function isAllowedEmbedSrc(src: string | null | undefined): boolean {\n if (!src) return false;\n return toEmbedUrl(src)?.src === src;\n}\n\n/** Fixed iframe attributes for an embed; sanitizers overwrite whatever the author's HTML carried. */\nexport const EMBED_IFRAME_ATTRS: Readonly<Record<string, string>> = {\n allow: \"fullscreen; picture-in-picture; encrypted-media\",\n allowfullscreen: \"\",\n loading: \"lazy\",\n referrerpolicy: \"strict-origin-when-cross-origin\",\n sandbox: \"allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox\",\n};\n\n/** Fixed `<video>` attributes: player controls, no autoplay or loop. */\nexport const VIDEO_ATTRS: Readonly<Record<string, string>> = { controls: \"\", preload: \"metadata\", playsinline: \"\" };\n\n/** `<video src>` / `poster` must be plain http(s): no data:, blob: or relative URLs (bodies render on customer sites). */\nexport function isSafeMediaUrl(url: string | null | undefined): boolean {\n if (!url) return false;\n try {\n const u = new URL(url);\n return (u.protocol === \"https:\" || u.protocol === \"http:\") && !u.username && !u.password;\n } catch {\n return false;\n }\n}\n","/**\n * Resource center structure shared by every SDK: nested collections and audience targeting.\n *\n * Audience targeting decides what the help widget lists; it is not access control. The published\n * config (and every article body) is the same for all visitors of an environment, and end-user\n * identities are self-asserted, so never rely on it to keep an article private.\n */\n\n/** Collections nest at most this deep (a collection, its sections, and their sub-sections). */\nexport const MAX_COLLECTION_DEPTH = 3;\n\nexport interface RcCollectionLike {\n id: string;\n name: string;\n order: number;\n /** Parent collection; null/absent for a top-level collection. */\n parentId?: string | null;\n /** Shown only to members of any of these audiences; empty/absent means everyone. */\n audienceIds?: string[];\n}\n\nexport interface RcArticleLike {\n id: string;\n collectionId?: string | null;\n audienceIds?: string[];\n}\n\nexport interface RcSection<C extends RcCollectionLike, A extends RcArticleLike> {\n /** null for articles outside any (known) collection. */\n collection: C | null;\n /** Collection names from the top level down, e.g. [\"Billing\", \"Invoices\"]. */\n path: string[];\n /** 0 for a top-level collection. */\n depth: number;\n articles: A[];\n}\n\ntype Membership = ReadonlySet<string> | readonly string[] | undefined | null;\n\n/** True when an item targeted at `required` audiences is shown to someone in `member`. */\nexport function matchesAudiences(required: readonly string[] | undefined | null, member: Membership): boolean {\n if (!required || required.length === 0) return true;\n if (!member) return false;\n const has = member instanceof Set ? (id: string) => member.has(id) : (id: string) => (member as readonly string[]).includes(id);\n return required.some(has);\n}\n\n/**\n * Article sections in display order: each collection (depth first, siblings by `order`) with the\n * visible articles filed directly in it, then the uncategorized articles. A collection the viewer\n * isn't targeted by hides its whole subtree, and sections without visible articles are left out\n * (their sub-collections still appear). Unknown parents count as top level, so an old config or a\n * dangling reference never hides content.\n */\nexport function resourceCenterSections<C extends RcCollectionLike, A extends RcArticleLike>(collections: readonly C[], articles: readonly A[], member?: Membership): Array<RcSection<C, A>> {\n const byId = new Map(collections.map((c) => [c.id, c]));\n const children = new Map<string | null, C[]>();\n for (const c of collections) {\n const parent = c.parentId && c.parentId !== c.id && byId.has(c.parentId) ? c.parentId : null;\n const list = children.get(parent) ?? [];\n list.push(c);\n children.set(parent, list);\n }\n for (const list of children.values()) list.sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));\n const direct = new Map<string, A[]>();\n const uncategorized: A[] = [];\n for (const a of articles) {\n if (!matchesAudiences(a.audienceIds, member)) continue;\n if (a.collectionId && byId.has(a.collectionId)) {\n const list = direct.get(a.collectionId) ?? [];\n list.push(a);\n direct.set(a.collectionId, list);\n } else uncategorized.push(a);\n }\n\n const sections: Array<RcSection<C, A>> = [];\n const seen = new Set<string>();\n const visit = (c: C, path: string[]) => {\n // A parent cycle in bad data would otherwise recurse forever; cycle members simply don't show.\n if (seen.has(c.id)) return;\n seen.add(c.id);\n if (!matchesAudiences(c.audienceIds, member)) return;\n const here = [...path, c.name];\n const list = direct.get(c.id);\n if (list?.length) sections.push({ collection: c, path: here, depth: here.length - 1, articles: list });\n for (const child of children.get(c.id) ?? []) visit(child, here);\n };\n for (const root of children.get(null) ?? []) visit(root, []);\n if (uncategorized.length) sections.push({ collection: null, path: [], depth: 0, articles: uncategorized });\n return sections;\n}\n\n/**\n * Whether one article is listed for a viewer: its own audiences and those of every collection above\n * it must match. For articles outside a loaded list (e.g. server search results).\n */\nexport function isArticleListed(collections: readonly RcCollectionLike[], article: RcArticleLike, member?: Membership): boolean {\n if (!matchesAudiences(article.audienceIds, member)) return false;\n const byId = new Map(collections.map((c) => [c.id, c]));\n let cur = article.collectionId ? byId.get(article.collectionId) : undefined;\n for (let guard = 0; cur && guard <= MAX_COLLECTION_DEPTH * 4; guard++) {\n if (!matchesAudiences(cur.audienceIds, member)) return false;\n cur = cur.parentId ? byId.get(cur.parentId) : undefined;\n }\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// Logged-in only articles\n// ---------------------------------------------------------------------------\n\n/** Who an article is listed for, besides its audiences: everyone, or logged-in (identified) visitors only. */\nexport const ARTICLE_VISIBILITIES = [\"everyone\", \"identified\"] as const;\nexport type ArticleVisibility = (typeof ARTICLE_VISIBILITIES)[number];\n\n/**\n * Reserved audience every logged-in visitor belongs to. The server folds an article's visibility into\n * the audiences it serves and adds this one to identified visitors' memberships, so every SDK (old ones\n * too) applies \"logged-in only\" through the audience matching it already does. Anonymous visitors never\n * identify, so their membership is empty and these articles stay hidden.\n */\nexport const LOGGED_IN_AUDIENCE = \"$identified\";\n\n/**\n * The audiences an article is served with. Logged-in only with no audiences becomes the reserved\n * audience; with audiences it is already implied, since audience membership only comes from identify.\n */\nexport function servedArticleAudiences(audienceIds: readonly string[], visibility: ArticleVisibility | string | null | undefined): string[] {\n return visibility === \"identified\" && audienceIds.length === 0 ? [LOGGED_IN_AUDIENCE] : [...audienceIds];\n}\n\n/** A visitor's memberships as matched against served articles: logged-in visitors are also in `LOGGED_IN_AUDIENCE`. */\nexport function visitorAudiences(audienceIds: readonly string[], identified: boolean): string[] {\n const ids = audienceIds.filter((id) => id !== LOGGED_IN_AUDIENCE);\n return identified ? [...ids, LOGGED_IN_AUDIENCE] : ids;\n}\n\n/** Ids of the articles a viewer sees (for filtering server search results the same way). */\nexport function visibleArticleIds(collections: readonly RcCollectionLike[], articles: readonly RcArticleLike[], member?: Membership): Set<string> {\n return new Set(resourceCenterSections(collections, articles, member).flatMap((s) => s.articles.map((a) => a.id)));\n}\n\n// ---------------------------------------------------------------------------\n// \"Show me\" prompts in help articles\n// ---------------------------------------------------------------------------\n\n/**\n * A \"Show me\" prompt in an article body is a plain link, `<p class=\"gd-show-me\"><a href=\"#guidely-show-me:<guide key>\">Show me how</a></p>`,\n * so it survives every sanitizer and reads as a harmless link anywhere else. The widgets turn it into a\n * button that starts the walkthrough (a live flow guide), or hide it when that guide isn't available.\n */\nexport const SHOW_ME_CLASS = \"gd-show-me\";\nexport const SHOW_ME_HREF_PREFIX = \"#guidely-show-me:\";\nconst SHOW_ME_KEY = /^[A-Za-z0-9_-]{1,64}$/;\n\nexport function showMeHref(guideKey: string): string {\n return `${SHOW_ME_HREF_PREFIX}${guideKey}`;\n}\n\n/** The guide key of a Show me link's `href`, or null. */\nexport function showMeKeyFromHref(href: string | null | undefined): string | null {\n if (!href || !href.startsWith(SHOW_ME_HREF_PREFIX)) return null;\n const key = href.slice(SHOW_ME_HREF_PREFIX.length);\n return SHOW_ME_KEY.test(key) ? key : null;\n}\n\n/** Guide keys of the Show me prompts in an article body, in order, without repeats (at most 10). */\nexport function showMeKeys(html: string | null | undefined): string[] {\n const out: string[] = [];\n for (const m of (html ?? \"\").matchAll(/href=\"#guidely-show-me:([A-Za-z0-9_-]{1,64})\"/g)) if (!out.includes(m[1]!)) out.push(m[1]!);\n return out.slice(0, 10);\n}\n\n/** The article body plays a video (uploaded, or embedded from YouTube, Vimeo, Loom or Wistia). */\nexport function hasVideoMedia(html: string | null | undefined): boolean {\n return /<(video|iframe)\\b/i.test(html ?? \"\");\n}\n\nconst words = (s: string) => s.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? [];\n\n/**\n * Help search on the device: every word of the query starts a word of the text, in any order, or the\n * query appears as typed. \"add user\" finds \"Add a new user\" and \"Users › Add\".\n */\nexport function matchesHelpQuery(text: string, query: string): boolean {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n const hay = text.toLowerCase();\n if (hay.includes(q)) return true;\n const terms = words(q);\n if (!terms.length) return false;\n const have = words(hay);\n return terms.every((t) => have.some((w) => w.startsWith(t) || (t.length > 3 && t.endsWith(\"s\") && w.startsWith(t.slice(0, -1)))));\n}\n\n// ---------------------------------------------------------------------------\n// Modules (section order + targeting) and \"What's new\"\n// ---------------------------------------------------------------------------\n\nexport const RC_MODULE_IDS = [\"announcements\", \"search\", \"checklists\", \"guides\", \"articles\", \"links\", \"faqs\"] as const;\nexport type ResourceCenterModuleId = (typeof RC_MODULE_IDS)[number];\n\nexport const RC_MODULE_LABELS: Record<ResourceCenterModuleId, string> = {\n announcements: \"What's new\",\n search: \"Search\",\n checklists: \"Checklists\",\n guides: \"Guides & tours\",\n articles: \"Articles\",\n links: \"Links\",\n faqs: \"FAQs\",\n};\n\n/**\n * The resource center's sections in display order: the configured modules (unknown ids dropped,\n * missing ones appended enabled, in the default order), so an old config shows every section.\n */\nexport function orderedModules<M extends { id: string; enabled: boolean }>(modules: readonly M[] | null | undefined): Array<M | { id: ResourceCenterModuleId; enabled: true }> {\n const known = (modules ?? []).filter((m, i, all) => (RC_MODULE_IDS as readonly string[]).includes(m.id) && all.findIndex((x) => x.id === m.id) === i);\n const missing = RC_MODULE_IDS.filter((id) => !known.some((m) => m.id === id)).map((id) => ({ id, enabled: true as const }));\n return [...known, ...missing];\n}\n\n/** Announcements a visitor sees: published (not in the future), audience-matched, newest first. */\nexport function visibleAnnouncements<A extends { publishedAt: string; audienceIds?: string[] }>(items: readonly A[] | null | undefined, member?: Membership, now: number = Date.now()): A[] {\n return (items ?? [])\n .filter((a) => {\n const t = Date.parse(a.publishedAt);\n return !Number.isNaN(t) && t <= now && matchesAudiences(a.audienceIds, member);\n })\n .sort((a, b) => Date.parse(b.publishedAt) - Date.parse(a.publishedAt));\n}\n\n/** Unread count for the launcher badge: announcements published after the visitor last opened \"What's new\". */\nexport function unreadAnnouncements(items: readonly { publishedAt: string }[], lastSeenAt: string | null | undefined): number {\n const seen = lastSeenAt ? Date.parse(lastSeenAt) : NaN;\n if (Number.isNaN(seen)) return items.length;\n return items.filter((a) => Date.parse(a.publishedAt) > seen).length;\n}\n","import { z } from \"zod\";\nimport { SelectorStrategySchema } from \"./guide\";\n\n/**\n * How-tos: step-by-step guides with screenshots, recorded by clicking through the customer's app\n * (SDK capture mode) and edited in the dashboard. Each step is either an action captured in the app\n * (click, type, select, navigate) or a block the author added (text, heading, tip, alert).\n */\n\nexport const HOWTO_STEP_KINDS = [\"action\", \"text\", \"heading\", \"tip\", \"alert\"] as const;\nexport type HowToStepKind = (typeof HOWTO_STEP_KINDS)[number];\n\nexport const HOWTO_ACTIONS = [\"click\", \"type\", \"select\", \"navigate\"] as const;\nexport type HowToAction = (typeof HOWTO_ACTIONS)[number];\n\n/** A rectangle as fractions (0–1) of its screenshot, so it survives any rendered size. */\nexport const NormalizedRectSchema = z.object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n width: z.number().min(0).max(1),\n height: z.number().min(0).max(1),\n});\nexport type NormalizedRect = z.infer<typeof NormalizedRectSchema>;\n\n/** The element an action was performed on, described for people (not for selecting it). */\nexport const CapturedElementSchema = z.object({\n /** Visible name: aria-label, associated label, text, placeholder, alt or title. */\n label: z.string().max(200).default(\"\"),\n /** button, link, tab, menuitem, checkbox, radio, field, dropdown, option, element… */\n role: z.string().max(40).default(\"element\"),\n tag: z.string().max(40).default(\"\"),\n});\nexport type CapturedElement = z.infer<typeof CapturedElementSchema>;\n\n/**\n * One action the SDK recorded, sent with its screenshot as multipart form data\n * (`step` = this JSON, `screenshot` = the image) to `POST /api/v1/sdk/capture/steps?token=`.\n * Sensitive values never arrive here: the SDK drops typed text from password, payment, one-time-code\n * and masked fields and redacts screenshots in the browser before uploading them.\n */\nexport const CaptureStepSchema = z.object({\n /** Random id from the SDK; a retried upload with the same id is stored once. */\n clientId: z.string().min(1).max(64),\n action: z.enum(HOWTO_ACTIONS),\n url: z.string().max(2000),\n pageTitle: z.string().max(300).default(\"\"),\n element: CapturedElementSchema.optional(),\n /** Typed text or chosen option; absent when it was sensitive (`valueRedacted`). */\n value: z.string().max(200).optional(),\n valueRedacted: z.boolean().default(false),\n /** Selectors for the element, so the step can later become an interactive tour step. */\n selectors: z.array(SelectorStrategySchema).max(10).default([]),\n /** Where the element sits in the screenshot. */\n highlight: NormalizedRectSchema.optional(),\n /** Number of regions the SDK blurred in the screenshot before upload. */\n redactions: z.number().int().min(0).max(1000).default(0),\n occurredAt: z.string().datetime().optional(),\n});\nexport type CaptureStep = z.infer<typeof CaptureStepSchema>;\nexport type CaptureStepInput = z.input<typeof CaptureStepSchema>;\n\n/** `GET /api/v1/sdk/capture/session?token=`: what the SDK needs to start recording. */\nexport interface CaptureSessionInfo {\n id: string;\n projectId: string;\n environment: string;\n howToId: string;\n howToTitle: string;\n /** Origin of the dashboard window that opened the app (for `postMessage`). */\n dashboardOrigin: string;\n expiresAt: string;\n /** Steps already recorded (a recording continues across full page loads). */\n stepCount: number;\n /** False when the server has no media storage: record steps without screenshots. */\n screenshots: boolean;\n}\n\nexport { CAPTURE_PARAM, CAPTURE_SCREENSHOT_MAX_BYTES } from \"./howto-limits\";\n\nfunction quoted(s: string | undefined) {\n const t = (s ?? \"\").replace(/\\s+/g, \" \").trim();\n return t.length > 60 ? `“${t.slice(0, 57)}…”` : `“${t}”`;\n}\n\n/**\n * A label as people would say it: icon glyphs and symbols at either end (\"+ New contact\", \"Next →\")\n * and required-field markers (\"Email *\", \"Name:\") removed. Falls back to the raw label when nothing\n * readable is left.\n */\nexport function cleanLabel(label: string | undefined | null): string {\n const raw = (label ?? \"\").replace(/\\s+/g, \" \").trim();\n const cleaned = raw\n .replace(/^[^\\p{L}\\p{N}“\"'(]+/u, \"\")\n .replace(/[\\s:*]+$/u, \"\")\n .replace(/[^\\p{L}\\p{N})”\"'?!.%]+$/u, \"\")\n .trim();\n return cleaned || raw;\n}\n\nconst SEPARATORS = /\\s+[·|•–—-]\\s+|\\s*[|·•]\\s*/;\nconst ID_SEGMENT = /^(?:\\d+|[0-9a-f]{8,}(?:-[0-9a-f]{4,})*|[A-Za-z0-9_-]{20,})$/i;\n\nfunction humanize(segment: string) {\n const words = decodeURIComponent(segment).replace(/[-_+]+/g, \" \").trim();\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : \"\";\n}\n\n/**\n * Name of the page a navigate step opens. A title like \"Contacts · Northwind CRM\" gives \"Contacts\";\n * a title that's just the app's name (no word of the path in it) gives the path instead, so\n * \"/contacts/new\" reads \"Contacts › New\". Ids in the path are skipped.\n */\nexport function pageName(url: string, pageTitle: string | undefined | null): string {\n const title = (pageTitle ?? \"\").replace(/\\s+/g, \" \").trim();\n const parts = title.split(SEPARATORS).map((p) => p.trim()).filter(Boolean);\n if (parts.length > 1) return parts[0]!;\n let segments: string[] = [];\n try {\n segments = new URL(url).pathname.split(\"/\").filter((p) => p && !ID_SEGMENT.test(p));\n } catch {\n segments = [];\n }\n const fromPath = segments.slice(-2).map(humanize).filter(Boolean).join(\" › \");\n if (!fromPath) return title || hostAndPath(url);\n if (!title) return fromPath;\n const lower = title.toLowerCase();\n const mentionsPath = segments.some((seg) => humanize(seg).toLowerCase().split(\" \").some((w) => w.length > 2 && lower.includes(w)));\n return mentionsPath ? title : fromPath;\n}\n\nconst ROLE_NOUN: Record<string, string> = { tab: \"tab\", menuitem: \"menu item\", field: \"field\", dropdown: \"dropdown\", option: \"option\" };\n\n/** Plain-language instruction for a captured action, e.g. `Click “Save”` or `Type “Acme” into “Company”`. */\nexport function describeCaptureStep(step: Pick<CaptureStepInput, \"action\" | \"element\" | \"value\" | \"valueRedacted\" | \"pageTitle\" | \"url\">): string {\n const label = cleanLabel(step.element?.label);\n const role = step.element?.role ?? \"\";\n switch (step.action) {\n case \"navigate\": {\n const where = pageName(step.url, step.pageTitle);\n return where ? `Go to ${quoted(where)}` : \"Open the page\";\n }\n case \"type\": {\n const field = label ? quoted(label) : \"the field\";\n if (step.valueRedacted || !step.value) return `Fill in ${field}`;\n return `Type ${quoted(step.value)} into ${field}`;\n }\n case \"select\":\n if (step.value && label) return `Select ${quoted(step.value)} from ${quoted(label)}`;\n if (step.value) return `Select ${quoted(step.value)}`;\n return label ? `Choose an option in ${quoted(label)}` : \"Choose an option\";\n case \"click\":\n default:\n if (role === \"checkbox\") return label ? `Check ${quoted(label)}` : \"Check the box\";\n if (role === \"switch\") return label ? `Turn ${quoted(label)} on or off` : \"Flip the switch\";\n if (role === \"radio\") return label ? `Select ${quoted(label)}` : \"Select the option\";\n if (role === \"menuitem\") return label ? `Choose ${quoted(label)} from the menu` : \"Choose the menu item\";\n if (role === \"tab\") return label ? `Open the ${quoted(label)} tab` : \"Open the tab\";\n if (label) return `Click ${quoted(label)}`;\n return ROLE_NOUN[role] ? `Click the ${ROLE_NOUN[role]}` : role === \"link\" ? \"Click the link\" : \"Click the button\";\n }\n}\n\nfunction hostAndPath(url: string) {\n try {\n const u = new URL(url);\n return `${u.host}${u.pathname === \"/\" ? \"\" : u.pathname}`;\n } catch {\n return url.slice(0, 80);\n }\n}\n\n/** A point as fractions (0–1) of a screenshot. */\nexport const NormalizedPointSchema = z.object({ x: z.number().min(0).max(1), y: z.number().min(0).max(1) });\nexport const ANNOTATION_COLORS = [\"brand\", \"red\", \"amber\", \"green\", \"black\", \"white\"] as const;\nexport type AnnotationColor = (typeof ANNOTATION_COLORS)[number];\n\n/**\n * A mark drawn over a step's screenshot, in fractions of the full image so it survives cropping and\n * any rendered size: an arrow, a text label or a box. `brand` uses the project's primary colour.\n */\nexport const HowToAnnotationSchema = z.discriminatedUnion(\"type\", [\n z.object({ id: z.string().min(1).max(32), type: z.literal(\"arrow\"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: z.enum(ANNOTATION_COLORS).default(\"brand\") }),\n z.object({ id: z.string().min(1).max(32), type: z.literal(\"text\"), at: NormalizedPointSchema, text: z.string().trim().min(1).max(120), color: z.enum(ANNOTATION_COLORS).default(\"brand\") }),\n z.object({ id: z.string().min(1).max(32), type: z.literal(\"box\"), rect: NormalizedRectSchema, color: z.enum(ANNOTATION_COLORS).default(\"brand\") }),\n]);\nexport type HowToAnnotation = z.infer<typeof HowToAnnotationSchema>;\nexport const MAX_ANNOTATIONS = 30;\n","/** How-to capture constants the browser SDK needs without zod (also exported from `@guidelytech/shared/runtime`). */\n\n/** Query parameter that starts capture mode in the SDK (separate from `guidely_authoring`, so SDKs without capture ignore it). */\nexport const CAPTURE_PARAM = \"guidely_capture\";\n/** Largest screenshot the capture endpoint accepts. */\nexport const CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;\n","/**\n * Page helpers shared by the SDK (page-aware messenger) and the server (page matching, analytics).\n * Pure and zod-free.\n */\n\n/**\n * One path segment that looks like an identifier: digits, a UUID, or a long hex string (hashes,\n * Mongo ids). Written so the same source works as a JS RegExp and a Postgres ARE (`regexp_replace`\n * with flags `gi`), which keeps id folding identical in SQL and in code. A segment may be followed\n * by the page query parameters a project keeps in its paths (`/contacts/42?tab=notes`).\n */\nexport const PATH_ID_PATTERN = \"/([0-9]+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[0-9a-f]{12,})(?=[/?]|$)\";\n\n/** `/contacts/42/notes/9f8e…` → `/contacts/:id/notes/:id`; `/contacts/42?tab=notes` → `/contacts/:id?tab=notes`. */\nexport function foldPathIds(path: string): string {\n return path.replace(new RegExp(PATH_ID_PATTERN, \"gi\"), \"/:id\");\n}\n\n/** Path segments that say nothing about what a page is for. */\nconst GENERIC_SEGMENTS = new Set([\"\", \":id\", \"app\", \"apps\", \"dashboard\", \"home\", \"index\", \"main\", \"new\", \"edit\", \"view\", \"show\", \"details\", \"detail\", \"overview\", \"list\", \"all\", \"page\", \"pages\", \"en\", \"v1\", \"v2\"]);\n\nfunction segmentsOf(path: string): string[] {\n const clean = foldPathIds((path.split(/[?#]/)[0] || \"/\").toLowerCase());\n return clean\n .split(\"/\")\n .map((s) => s.replace(/\\.(html?|php|aspx?)$/, \"\"))\n .filter((s) => !GENERIC_SEGMENTS.has(s) && /[a-z]/.test(s) && s.length <= 40);\n}\n\n/** Words describing a page, from its path (`/settings/billing-plans/42` → `settings billing plans`). */\nexport function pageTerms(path: string): string[] {\n const words = segmentsOf(path).flatMap((s) => s.split(/[-_.+\\s]+/).filter((w) => w.length > 1 && /[a-z]/.test(w)));\n return [...new Set(words)].slice(0, 8);\n}\n\n/** A short human name for a page (`/app/invoices/42` → `Invoices`), or null for the root and unnamed pages. */\nexport function pageLabel(path: string): string | null {\n const last = segmentsOf(path).at(-1);\n if (!last) return null;\n const words = last.split(/[-_.+\\s]+/).filter(Boolean);\n if (!words.length) return null;\n const label = words.join(\" \");\n return label.charAt(0).toUpperCase() + label.slice(1);\n}\n\n/** The first name in a user's traits (`firstName`, `first_name`, or the first word of `name`), or null. */\nexport function firstNameFromTraits(traits: Record<string, unknown> | null | undefined): string | null {\n if (!traits) return null;\n const pick = (v: unknown) => (typeof v === \"string\" ? v.trim() : \"\");\n const first = pick(traits.firstName) || pick(traits.first_name) || pick(traits.firstname) || pick(traits.name).split(/\\s+/)[0] || \"\";\n // Never greet someone by an email address or an id.\n if (!first || first.length > 40 || first.includes(\"@\") || !/\\p{L}/u.test(first)) return null;\n return first;\n}\n","/**\n * Tagged pages and features (named rules over the URLs and clicks the SDK captures), shared by the server (retroactive\n * matching, SQL generation), the dashboard (previews) and the SDK (event properties). Pure and zod-free.\n *\n * - An `ElementSnapshot` is the compact description of a clicked element the SDK attaches to `click`\n * events (`properties.el`): tag, id, classes, a few safe attributes, nth-of-type, ~5 ancestors and\n * the shadow hosts above it. CSS selector rules are evaluated against it with {@link matchCssSelector},\n * so a rule written today also matches clicks stored before it existed.\n * - Older clicks carry only a selector string; {@link snapshotFromSelector} turns that string into a\n * partial snapshot so CSS rules still match them where the string says enough.\n */\n\n// ---------------------------------------------------------------------------\n// Element snapshots\n// ---------------------------------------------------------------------------\n\n/** One element in a snapshot: tag, id, classes, safe attributes and its 1-based nth-of-type. */\nexport interface ElementNode {\n t: string;\n id?: string;\n c?: string[];\n a?: Record<string, string>;\n n?: number;\n}\n\n/** A clicked element (`click.properties.el`): the element, its ancestors (`p`, parent first) and shadow hosts (`h`, nearest first). */\nexport interface ElementSnapshot extends ElementNode {\n p?: ElementNode[];\n h?: ElementNode[];\n}\n\nexport const SNAPSHOT_LIMITS = { classes: 8, className: 60, attrs: 6, attrValue: 100, ancestors: 5, hosts: 3, tag: 40, id: 80 } as const;\n\n/** Attributes a snapshot may carry besides `data-*` ones. Never `value`, never event handlers. */\nexport const SNAPSHOT_ATTRS = [\"role\", \"name\", \"type\", \"aria-label\", \"title\", \"alt\", \"for\", \"href\"] as const;\n\n/** Framework and state `data-*` attributes that say nothing stable about an element. */\nexport const NOISY_DATA_ATTR = /^data-(state|v-|react|radix|headlessui|svelte|orientation|highlighted|focus|key|index|side|align|disabled|selected|active|open|rbd|dnd|sveltekit|guidely-(mask|ignore|block))/i;\n\n/** The custom attribute that names a feature by default (`<button data-guidely-feature=\"Export CSV\">`). */\nexport const DEFAULT_FEATURE_ATTRIBUTE = \"data-guidely-feature\";\nexport const FEATURE_ATTRIBUTE_PATTERN = /^data-[a-z0-9][a-z0-9_.-]{0,60}$/;\n\nfunction str(v: unknown, max: number): string | undefined {\n return typeof v === \"string\" && v ? v.slice(0, max) : undefined;\n}\n\nfunction cleanNode(raw: unknown): ElementNode | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n const t = str(r.t, SNAPSHOT_LIMITS.tag)?.toLowerCase();\n if (!t || !/^[a-z][a-z0-9-]*$/.test(t)) return null;\n const node: ElementNode = { t };\n const id = str(r.id, SNAPSHOT_LIMITS.id);\n if (id) node.id = id;\n if (Array.isArray(r.c)) {\n const c = r.c.filter((x): x is string => typeof x === \"string\" && !!x && x.length <= SNAPSHOT_LIMITS.className && !/\\s/.test(x)).slice(0, SNAPSHOT_LIMITS.classes);\n if (c.length) node.c = c;\n }\n if (r.a && typeof r.a === \"object\" && !Array.isArray(r.a)) {\n const a: Record<string, string> = {};\n for (const [k, v] of Object.entries(r.a as Record<string, unknown>)) {\n if (Object.keys(a).length >= SNAPSHOT_LIMITS.attrs) break;\n const key = k.toLowerCase();\n if (typeof v !== \"string\" || !(key.startsWith(\"data-\") || (SNAPSHOT_ATTRS as readonly string[]).includes(key)) || key === \"value\" || key.length > 60) continue;\n a[key] = v.slice(0, SNAPSHOT_LIMITS.attrValue);\n }\n if (Object.keys(a).length) node.a = a;\n }\n if (typeof r.n === \"number\" && Number.isInteger(r.n) && r.n >= 1 && r.n <= 10_000) node.n = r.n;\n return node;\n}\n\n/** Validates and trims a snapshot sent by an SDK (server side); null when it is not one. */\nexport function normalizeSnapshot(raw: unknown): ElementSnapshot | null {\n const el = cleanNode(raw);\n if (!el) return null;\n const r = raw as Record<string, unknown>;\n const out: ElementSnapshot = el;\n if (Array.isArray(r.p)) {\n const p = r.p.slice(0, SNAPSHOT_LIMITS.ancestors).map(cleanNode);\n // Ancestors are consecutive; stop at the first unusable one rather than skipping it.\n const cut = p.indexOf(null);\n const list = (cut === -1 ? p : p.slice(0, cut)) as ElementNode[];\n if (list.length) out.p = list;\n }\n if (Array.isArray(r.h)) {\n const h = r.h.slice(0, SNAPSHOT_LIMITS.hosts).map(cleanNode).filter((x): x is ElementNode => !!x);\n if (h.length) out.h = h;\n }\n return out;\n}\n\n/** JSON with sorted keys, so equal snapshots hash the same whatever order the SDK wrote them in. */\nexport function stableStringify(v: unknown): string {\n if (Array.isArray(v)) return `[${v.map(stableStringify).join(\",\")}]`;\n if (v && typeof v === \"object\") {\n const o = v as Record<string, unknown>;\n return `{${Object.keys(o)\n .filter((k) => o[k] !== undefined)\n .sort()\n .map((k) => `${JSON.stringify(k)}:${stableStringify(o[k])}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(v ?? null);\n}\n\n// ---------------------------------------------------------------------------\n// CSS selector subset: parse + match against a snapshot\n// ---------------------------------------------------------------------------\n\nexport type AttrOp = \"exists\" | \"=\" | \"^=\" | \"$=\" | \"*=\" | \"~=\" | \"|=\";\n\nexport interface AttrTest {\n name: string;\n op: AttrOp;\n value?: string;\n /** `[attr=\"x\" i]` */\n insensitive?: boolean;\n}\n\nexport interface Compound {\n tag?: string;\n id?: string;\n classes: string[];\n attrs: AttrTest[];\n /** `:nth-of-type(n)`; `odd`/`even` as `{ a: 2, b: 1|0 }`; `:first-of-type` is `{ a: 0, b: 1 }`. */\n nth?: { a: number; b: number };\n}\n\n/** A complex selector: compounds left to right and the combinator before each (index 0 has none). */\nexport interface ComplexSelector {\n compounds: Compound[];\n combinators: Array<\" \" | \">\" | \">>>\">;\n}\n\nexport class SelectorSyntaxError extends Error {}\n\nconst IDENT_START = /[A-Za-z_\\u00a0-\\uffff-]/;\nconst IDENT_CHAR = /[A-Za-z0-9_\\u00a0-\\uffff-]/;\n\n/**\n * Parses the supported subset: type and universal selectors, `#id`, `.class`, `[attr]`,\n * `[attr=v]`, `^=`, `$=`, `*=`, `~=`, `|=` (optionally `i`), `:nth-of-type(n|odd|even)`,\n * `:first-of-type`, descendant and child combinators, `>>>` (shadow host) and selector lists.\n * Throws {@link SelectorSyntaxError} on anything else.\n */\nexport function parseCssSelector(input: string): ComplexSelector[] {\n const s = input.trim();\n if (!s) throw new SelectorSyntaxError(\"Empty selector\");\n if (s.length > 1000) throw new SelectorSyntaxError(\"Selector is too long\");\n let i = 0;\n const peek = () => s[i];\n const eof = () => i >= s.length;\n const fail = (msg: string): never => {\n throw new SelectorSyntaxError(`${msg} at position ${i + 1}`);\n };\n const ws = () => {\n let any = false;\n while (!eof() && /\\s/.test(s[i]!)) {\n i++;\n any = true;\n }\n return any;\n };\n const escape = (): string => {\n // after the backslash\n i++;\n const hex = /^[0-9a-fA-F]{1,6}/.exec(s.slice(i));\n if (hex) {\n i += hex[0].length;\n if (s[i] === \" \") i++;\n return String.fromCodePoint(parseInt(hex[0], 16));\n }\n if (eof()) fail(\"Unfinished escape\");\n return s[i++]!;\n };\n const ident = (): string => {\n let out = \"\";\n if (s[i] === \"\\\\\") out += escape();\n else if (!eof() && IDENT_START.test(s[i]!)) out += s[i++];\n else fail(\"Expected a name\");\n while (!eof()) {\n if (s[i] === \"\\\\\") out += escape();\n else if (IDENT_CHAR.test(s[i]!)) out += s[i++];\n else break;\n }\n return out;\n };\n const quoted = (): string => {\n const q = s[i++];\n let out = \"\";\n while (!eof() && s[i] !== q) {\n if (s[i] === \"\\\\\") out += escape();\n else out += s[i++];\n }\n if (eof()) fail(\"Unterminated string\");\n i++;\n return out;\n };\n const compound = (): Compound | null => {\n const c: Compound = { classes: [], attrs: [] };\n let any = false;\n if (peek() === \"*\") {\n i++;\n any = true;\n } else if (!eof() && (IDENT_START.test(peek()!) || peek() === \"\\\\\")) {\n c.tag = ident().toLowerCase();\n any = true;\n }\n for (;;) {\n const ch = peek();\n if (ch === \"#\") {\n i++;\n c.id = ident();\n } else if (ch === \".\") {\n i++;\n c.classes.push(ident());\n } else if (ch === \"[\") {\n i++;\n ws();\n const name = ident().toLowerCase();\n ws();\n let op: AttrOp = \"exists\";\n let value: string | undefined;\n let insensitive = false;\n if (peek() !== \"]\") {\n const m = /^(=|\\^=|\\$=|\\*=|~=|\\|=)/.exec(s.slice(i));\n if (!m) fail(\"Unsupported attribute operator\");\n op = m![1] as AttrOp;\n i += m![1]!.length;\n ws();\n value = peek() === '\"' || peek() === \"'\" ? quoted() : ident();\n ws();\n if (peek() === \"i\" || peek() === \"I\") {\n i++;\n insensitive = true;\n ws();\n } else if (peek() === \"s\" || peek() === \"S\") {\n i++;\n ws();\n }\n }\n if (peek() !== \"]\") fail(\"Expected ]\");\n i++;\n c.attrs.push({ name, op, ...(value !== undefined ? { value } : {}), ...(insensitive ? { insensitive } : {}) });\n } else if (ch === \":\") {\n i++;\n if (peek() === \":\") fail(\"Pseudo-elements are not supported\");\n const name = ident().toLowerCase();\n if (name === \"first-of-type\") c.nth = { a: 0, b: 1 };\n else if (name === \"nth-of-type\") {\n if (peek() !== \"(\") fail(\"Expected (\");\n i++;\n ws();\n const m = /^(odd|even|\\d+)/i.exec(s.slice(i));\n if (!m) fail(\"Only :nth-of-type(n), odd or even are supported\");\n i += m![0].length;\n ws();\n if (peek() !== \")\") fail(\"Expected )\");\n i++;\n const v = m![0].toLowerCase();\n c.nth = v === \"odd\" ? { a: 2, b: 1 } : v === \"even\" ? { a: 2, b: 0 } : { a: 0, b: Number(v) };\n } else fail(`Unsupported pseudo-class :${name}`);\n } else break;\n any = true;\n }\n return any ? c : null;\n };\n\n const list: ComplexSelector[] = [];\n for (;;) {\n ws();\n const sel: ComplexSelector = { compounds: [], combinators: [] };\n const first = compound();\n if (!first) fail(\"Expected a selector\");\n sel.compounds.push(first!);\n for (;;) {\n const hadWs = ws();\n if (eof() || peek() === \",\") break;\n let comb: \" \" | \">\" | \">>>\" = \" \";\n if (s.startsWith(\">>>\", i)) {\n comb = \">>>\";\n i += 3;\n ws();\n } else if (peek() === \">\") {\n comb = \">\";\n i++;\n ws();\n } else if (peek() === \"+\" || peek() === \"~\") fail(\"Sibling combinators are not supported\");\n else if (!hadWs) fail(\"Unexpected character\");\n const next = compound();\n if (!next) fail(\"Expected a selector after the combinator\");\n sel.compounds.push(next!);\n sel.combinators.push(comb);\n }\n list.push(sel);\n if (eof()) break;\n i++; // \",\"\n }\n return list;\n}\n\n/** Is the selector inside the supported subset? Returns the error message, or null when it parses. */\nexport function cssSelectorError(selector: string): string | null {\n try {\n parseCssSelector(selector);\n return null;\n } catch (e) {\n return e instanceof Error ? e.message : \"Invalid selector\";\n }\n}\n\nfunction attrMatches(test: AttrTest, node: ElementNode): boolean {\n let actual: string | undefined;\n if (test.name === \"id\") actual = node.id;\n else if (test.name === \"class\") actual = node.c?.join(\" \");\n else actual = node.a?.[test.name];\n if (actual === undefined) return false;\n if (test.op === \"exists\") return true;\n let v = test.value ?? \"\";\n if (test.insensitive) {\n actual = actual.toLowerCase();\n v = v.toLowerCase();\n }\n switch (test.op) {\n case \"=\":\n return actual === v;\n case \"^=\":\n return !!v && actual.startsWith(v);\n case \"$=\":\n return !!v && actual.endsWith(v);\n case \"*=\":\n return !!v && actual.includes(v);\n case \"~=\":\n return !!v && actual.split(/\\s+/).includes(v);\n case \"|=\":\n return actual === v || actual.startsWith(`${v}-`);\n default:\n return false;\n }\n}\n\n/** Does one compound match one node? An unknown nth-of-type fails `:nth-of-type` tests. */\nexport function compoundMatches(c: Compound, node: ElementNode): boolean {\n if (c.tag && c.tag !== node.t) return false;\n if (c.id !== undefined && node.id !== c.id) return false;\n for (const cls of c.classes) if (!node.c?.includes(cls)) return false;\n for (const a of c.attrs) if (!attrMatches(a, node)) return false;\n if (c.nth) {\n if (!node.n) return false;\n const { a, b } = c.nth;\n if (a === 0 ? node.n !== b : (node.n - b) % a !== 0 || (node.n - b) / a < 0) return false;\n }\n return true;\n}\n\n/** Matches compounds (right to left) against a chain of nodes: index 0 is the element, then its ancestors. */\nfunction chainMatches(compounds: Compound[], combinators: Array<\" \" | \">\">, nodes: ElementNode[], ci = compounds.length - 1, ni = 0): boolean {\n if (!compoundMatches(compounds[ci]!, nodes[ni]!)) return false;\n if (ci === 0) return true;\n const comb = combinators[ci - 1]!;\n if (comb === \">\") return ni + 1 < nodes.length && chainMatches(compounds, combinators, nodes, ci - 1, ni + 1);\n for (let k = ni + 1; k < nodes.length; k++) if (chainMatches(compounds, combinators, nodes, ci - 1, k)) return true;\n return false;\n}\n\nfunction complexMatches(sel: ComplexSelector, snap: ElementSnapshot): boolean {\n // Split at `>>>`: the last segment is matched inside the element's own tree, each earlier\n // segment's last compound against a shadow host further out (any depth, like the runtime).\n const segments: Array<{ compounds: Compound[]; combinators: Array<\" \" | \">\"> }> = [{ compounds: [sel.compounds[0]!], combinators: [] }];\n sel.combinators.forEach((comb, k) => {\n const next = sel.compounds[k + 1]!;\n if (comb === \">>>\") segments.push({ compounds: [next], combinators: [] });\n else {\n const seg = segments[segments.length - 1]!;\n seg.compounds.push(next);\n seg.combinators.push(comb);\n }\n });\n const last = segments.pop()!;\n const nodes: ElementNode[] = [snap, ...(snap.p ?? [])];\n if (!chainMatches(last.compounds, last.combinators, nodes)) return false;\n const hosts = snap.h ?? [];\n let from = 0;\n for (let k = segments.length - 1; k >= 0; k--) {\n const target = segments[k]!.compounds[segments[k]!.compounds.length - 1]!;\n let found = -1;\n for (let j = from; j < hosts.length; j++) {\n if (compoundMatches(target, hosts[j]!)) {\n found = j;\n break;\n }\n }\n if (found === -1) return false;\n from = found + 1;\n }\n return true;\n}\n\nconst parsedCache = new Map<string, ComplexSelector[] | null>();\n\n/** Does a CSS selector (subset, see {@link parseCssSelector}) match the snapshot? Invalid selectors match nothing. */\nexport function matchCssSelector(selector: string | ComplexSelector[], snap: ElementSnapshot): boolean {\n let list: ComplexSelector[] | null;\n if (typeof selector === \"string\") {\n if (!parsedCache.has(selector)) {\n if (parsedCache.size > 500) parsedCache.clear();\n try {\n parsedCache.set(selector, parseCssSelector(selector));\n } catch {\n parsedCache.set(selector, null);\n }\n }\n list = parsedCache.get(selector)!;\n } else list = selector;\n return !!list && list.some((sel) => complexMatches(sel, snap));\n}\n\nfunction nodeOfCompound(c: Compound): ElementNode {\n const node: ElementNode = { t: c.tag ?? \"*\" };\n if (c.id) node.id = c.id;\n if (c.classes.length) node.c = c.classes.slice(0, SNAPSHOT_LIMITS.classes);\n const a: Record<string, string> = {};\n for (const t of c.attrs) if (t.op === \"=\" && t.value !== undefined) a[t.name] = t.value;\n if (Object.keys(a).length) node.a = a;\n if (c.nth && c.nth.a === 0) node.n = c.nth.b;\n return node;\n}\n\n/**\n * A partial snapshot read from a stored selector string (clicks captured before snapshots existed):\n * `#form > div:nth-of-type(2) > button[data-testid=\"save\"]` becomes a `button` with that attribute,\n * nth 1-unknown, and two ancestors. Shadow steps (`c-app >>> button`) become hosts. Null when the\n * string is not a selector in the supported subset.\n */\nexport function snapshotFromSelector(selector: string, tag?: string | null): ElementSnapshot | null {\n let list: ComplexSelector[];\n try {\n list = parseCssSelector(selector);\n } catch {\n return null;\n }\n if (list.length !== 1) return null;\n const sel = list[0]!;\n const segments: Compound[][] = [[sel.compounds[0]!]];\n sel.combinators.forEach((comb, k) => {\n if (comb === \">>>\") segments.push([sel.compounds[k + 1]!]);\n else segments[segments.length - 1]!.push(sel.compounds[k + 1]!);\n });\n const own = segments.pop()!;\n const el = nodeOfCompound(own[own.length - 1]!);\n if (el.t === \"*\" && tag && /^[a-z][a-z0-9-]*$/i.test(tag)) el.t = tag.toLowerCase();\n const snap: ElementSnapshot = el;\n const p = own.slice(0, -1).reverse().map(nodeOfCompound);\n if (p.length) snap.p = p.slice(0, SNAPSHOT_LIMITS.ancestors);\n const h = segments.reverse().map((seg) => nodeOfCompound(seg[seg.length - 1]!));\n if (h.length) snap.h = h.slice(0, SNAPSHOT_LIMITS.hosts);\n return snap;\n}\n\n// ---------------------------------------------------------------------------\n// Page rules\n// ---------------------------------------------------------------------------\n\nexport type QueryParamOp = \"exists\" | \"absent\" | \"equals\" | \"contains\";\nexport interface QueryParamCondition {\n name: string;\n op: QueryParamOp;\n value?: string;\n}\n\n/**\n * One way a URL belongs to a page. `url`: a pattern (`/accounts/:id/settings`, `/reports/*`,\n * `/docs/**`, `//*\\/billing`, `https://app.acme.com/x`) plus optional query conditions; `regex`: a\n * regular expression over the path; `title`: the document title (`equals` / `contains`). With\n * `exclude`, matching URLs are taken out of the page instead.\n */\nexport interface PageRule {\n id?: string;\n type: \"url\" | \"regex\" | \"title\";\n value: string;\n op?: \"equals\" | \"contains\";\n query?: QueryParamCondition[];\n exclude?: boolean;\n}\n\nexport const PAGE_RULE_LIMITS = { rules: 20, value: 500, query: 5 } as const;\n\nexport interface PagePattern {\n /** Anchored regex source, valid both as a JS RegExp (flag `i`) and a Postgres ARE (`~*`). */\n source: string;\n /** What it runs against: the path (query removed) or the full URL without query and hash. */\n target: \"path\" | \"url\";\n /** Query conditions written into the pattern (`/search?tab=people`). */\n query: QueryParamCondition[];\n}\n\nconst escapeRe = (s: string) => s.replace(/[.+?^${}()|[\\]\\\\*]/g, \"\\\\$&\");\n\nfunction globToRegex(pattern: string): string {\n let out = \"\";\n for (let k = 0; k < pattern.length; k++) {\n const ch = pattern[k]!;\n if (ch === \"*\") {\n if (pattern[k + 1] === \"*\") {\n out += \".*\";\n k++;\n } else out += \"[^/]*\";\n } else if (ch === \":\" && (k === 0 || pattern[k - 1] === \"/\") && /[A-Za-z_]/.test(pattern[k + 1] ?? \"\")) {\n // `:name` path parameter: one whole segment.\n let j = k + 1;\n while (j < pattern.length && /[\\w]/.test(pattern[j]!)) j++;\n out += \"[^/]+\";\n k = j - 1;\n } else out += escapeRe(ch);\n }\n return out;\n}\n\n/** Turns a URL rule pattern into a regex. Query parameters in the pattern become conditions. */\nexport function pagePattern(raw: string): PagePattern {\n let p = raw.trim();\n const query: QueryParamCondition[] = [];\n const hash = p.indexOf(\"#\");\n if (hash !== -1) p = p.slice(0, hash);\n const q = p.indexOf(\"?\");\n if (q !== -1) {\n for (const part of p.slice(q + 1).split(\"&\")) {\n if (!part) continue;\n const eq = part.indexOf(\"=\");\n const name = decodeSafe(eq === -1 ? part : part.slice(0, eq));\n const value = eq === -1 ? undefined : decodeSafe(part.slice(eq + 1));\n if (!name) continue;\n query.push(value === undefined || value === \"*\" ? { name, op: \"exists\" } : { name, op: \"equals\", value });\n }\n p = p.slice(0, q);\n }\n let target: \"path\" | \"url\" = \"path\";\n // `//*` means any domain: keep only the path.\n if (p.startsWith(\"//*\")) p = p.slice(3);\n let prefix = \"\";\n const abs = /^(https?:)?\\/\\/([^/]+)(.*)$/i.exec(p);\n if (abs) {\n target = \"url\";\n prefix = `https?://${globToRegex(abs[2]!.toLowerCase())}`;\n p = abs[3] || \"/\";\n }\n if (!p.startsWith(\"/\")) p = `/${p}`;\n // A trailing slash is optional, as on most sites.\n const body = p.length > 1 && p.endsWith(\"/\") ? p.slice(0, -1) : p;\n const src = body === \"/\" ? \"/?\" : `${globToRegex(body)}/?`;\n return { source: `^${prefix}${src}$`, target, query: query.slice(0, PAGE_RULE_LIMITS.query) };\n}\n\nfunction decodeSafe(s: string): string {\n try {\n return decodeURIComponent(s.replace(/\\+/g, \" \"));\n } catch {\n return s;\n }\n}\n\n/** Regex (JS + Postgres) for a query condition over a raw URL. */\nexport function queryConditionRegex(c: QueryParamCondition): string {\n const name = escapeRe(c.name);\n switch (c.op) {\n case \"equals\":\n return `[?&]${name}=${escapeRe(encodeLoose(c.value ?? \"\"))}(&|#|$)`;\n case \"contains\":\n return `[?&]${name}=[^&#]*${escapeRe(encodeLoose(c.value ?? \"\"))}`;\n default:\n return `[?&]${name}(=|&|#|$)`;\n }\n}\n\n/** URL-encodes what browsers encode in query values, leaving the common safe characters alone. */\nfunction encodeLoose(v: string): string {\n return encodeURIComponent(v).replace(/%2F/gi, \"/\").replace(/%3A/gi, \":\").replace(/%2C/gi, \",\").replace(/%40/gi, \"@\");\n}\n\nexport interface PageContext {\n /** Full URL (with query) when known. */\n url?: string | null;\n /** Path as stored (`/a/b`, or `/a/b?section=x` with kept page parameters). */\n path?: string | null;\n title?: string | null;\n}\n\nfunction pathOnly(ctx: PageContext): string | null {\n if (ctx.path) return ctx.path.split(\"?\")[0] || \"/\";\n if (!ctx.url) return null;\n try {\n return new URL(ctx.url, \"http://x.invalid\").pathname;\n } catch {\n return null;\n }\n}\n\nfunction regexOrNull(source: string): RegExp | null {\n try {\n return new RegExp(source, \"i\");\n } catch {\n return null;\n }\n}\n\n/** JS twin of the SQL a page rule compiles to (server `pageRuleSql`). */\nexport function pageRuleMatches(rule: PageRule, ctx: PageContext): boolean {\n const path = pathOnly(ctx);\n if (rule.type === \"title\") {\n const t = (ctx.title ?? \"\").toLowerCase();\n const v = rule.value.toLowerCase();\n return !!t && (rule.op === \"contains\" ? t.includes(v) : t === v);\n }\n if (rule.type === \"regex\") {\n const re = regexOrNull(rule.value);\n return !!re && path !== null && re.test(path);\n }\n const pat = pagePattern(rule.value);\n const re = regexOrNull(pat.source);\n if (!re) return false;\n let subject: string | null = path;\n if (pat.target === \"url\") {\n if (!ctx.url) return false;\n subject = ctx.url.split(/[?#]/)[0]!;\n }\n if (subject === null || !re.test(subject)) return false;\n const conds = [...pat.query, ...(rule.query ?? [])];\n for (const c of conds) {\n const hit = !!ctx.url && new RegExp(queryConditionRegex(c), \"i\").test(ctx.url);\n if (c.op === \"absent\" ? hit : !hit) return false;\n }\n return true;\n}\n\n/** Included by any include rule and excluded by no exclude rule. */\nexport function pageRulesMatch(rules: PageRule[], ctx: PageContext): boolean {\n const include = rules.filter((r) => !r.exclude);\n if (!include.length || !include.some((r) => pageRuleMatches(r, ctx))) return false;\n return !rules.some((r) => r.exclude && pageRuleMatches(r, ctx));\n}\n\n/** Validation message for a page rule, or null. */\nexport function pageRuleError(rule: PageRule): string | null {\n const v = rule.value?.trim();\n if (!v) return \"A rule needs a value\";\n if (v.length > PAGE_RULE_LIMITS.value) return \"The rule is too long\";\n if (rule.type === \"regex\") {\n if (!regexOrNull(v)) return `\"${v}\" is not a valid regular expression`;\n if (/\\(\\?[<=!]/.test(v) || /\\\\[1-9]/.test(v)) return \"Look-arounds and back-references are not supported\";\n }\n if (rule.type === \"url\" && !regexOrNull(pagePattern(v).source)) return `\"${v}\" is not a valid URL rule`;\n for (const q of rule.query ?? []) if (!/^[A-Za-z0-9_.\\-[\\]]{1,60}$/.test(q.name)) return `\"${q.name}\" is not a query parameter name`;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Feature rules\n// ---------------------------------------------------------------------------\n\nexport type SelectorOp = \"exact\" | \"prefix\" | \"contains\" | \"glob\" | \"css\";\n\n/**\n * One way a click belongs to a feature. Every condition present must hold. `selector.op = \"css\"`\n * evaluates a CSS selector against the element snapshot (or, for old clicks, the snapshot read from\n * the stored selector string); the other selector operators compare the stored selector string —\n * mobile taps store the accessibility id / `data-guidely-id` there, so `exact` works for them too.\n */\nexport interface FeatureRule {\n id?: string;\n selector?: { op: SelectorOp; value: string };\n text?: { op: \"equals\" | \"contains\"; value: string };\n tag?: string;\n href?: { op: \"equals\" | \"prefix\" | \"contains\"; value: string };\n /** Only clicks on this tagged page / URL pattern. */\n page?: { pageId?: string; pattern?: string };\n /** `web`, `ios`, `android` (mobile autocapture sets `properties.platform`). */\n platform?: string;\n exclude?: boolean;\n}\n\nexport const FEATURE_RULE_LIMITS = { rules: 20, value: 1000 } as const;\n\nexport interface ClickFacts {\n selector?: string | null;\n text?: string | null;\n tag?: string | null;\n href?: string | null;\n platform?: string | null;\n}\n\nfunction globMatch(pattern: string, value: string): boolean {\n const re = new RegExp(`^${pattern.split(\"*\").map(escapeRe).join(\".*\")}$`, \"s\");\n return re.test(value);\n}\n\n/** Does a click (facts + a CSS test) satisfy one rule's element conditions? Page scope is checked by the caller. */\nexport function featureRuleMatchesClick(rule: FeatureRule, click: ClickFacts, css: (selector: string) => boolean): boolean {\n if (!rule.selector && !rule.text && !rule.tag && !rule.href) return false;\n if (rule.selector) {\n const sel = click.selector ?? \"\";\n const v = rule.selector.value;\n const ok =\n rule.selector.op === \"css\" ? css(v) : rule.selector.op === \"exact\" ? sel === v : rule.selector.op === \"prefix\" ? sel.startsWith(v) : rule.selector.op === \"contains\" ? sel.includes(v) : globMatch(v, sel);\n if (!ok) return false;\n }\n if (rule.text) {\n const t = (click.text ?? \"\").toLowerCase();\n const v = rule.text.value.toLowerCase();\n if (rule.text.op === \"contains\" ? !t.includes(v) : t !== v) return false;\n }\n if (rule.tag && (click.tag ?? \"\").toLowerCase() !== rule.tag.toLowerCase()) return false;\n if (rule.href) {\n const h = click.href ?? \"\";\n const v = rule.href.value;\n if (rule.href.op === \"equals\" ? h !== v : rule.href.op === \"prefix\" ? !h.startsWith(v) : !h.includes(v)) return false;\n }\n if (rule.platform && (click.platform ?? \"web\") !== rule.platform) return false;\n return true;\n}\n\n/** Validation message for a feature rule, or null. */\nexport function featureRuleError(rule: FeatureRule): string | null {\n if (!rule.selector && !rule.text && !rule.tag && !rule.href) return \"A feature rule needs a selector, text, tag or link condition\";\n if (rule.selector) {\n const v = rule.selector.value?.trim();\n if (!v) return \"The selector is empty\";\n if (v.length > FEATURE_RULE_LIMITS.value) return \"The selector is too long\";\n if (rule.selector.op === \"css\") {\n const err = cssSelectorError(v);\n if (err) return `Unsupported CSS selector: ${err}`;\n }\n }\n if (rule.text && !rule.text.value.trim()) return \"The text condition is empty\";\n if (rule.href && !rule.href.value.trim()) return \"The link condition is empty\";\n if (rule.tag && !/^[a-z][a-z0-9-]{0,40}$/i.test(rule.tag)) return \"The tag is not an element name\";\n if (rule.page?.pattern) return pageRuleError({ type: \"url\", value: rule.page.pattern });\n return null;\n}\n\n/** Selector to find a feature's elements on a page (dashboard overlays, SDK property capture), when the rules give one. */\nexport function featureCssSelectors(rules: FeatureRule[]): string[] {\n const out: string[] = [];\n for (const r of rules) {\n if (r.exclude || !r.selector) continue;\n if ((r.selector.op === \"css\" || r.selector.op === \"exact\") && !cssSelectorError(r.selector.value)) out.push(r.selector.value);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Event properties captured from the DOM (configured per page / feature, sent in the SDK config)\n// ---------------------------------------------------------------------------\n\nexport interface TagPropertyDefinition {\n id: string;\n name: string;\n /** Element to read: CSS selector (may use `>>>`); empty = the clicked element itself (features only). */\n selector?: string;\n source: \"text\" | \"attribute\";\n /** Attribute name for `source: \"attribute\"`; `value` is never read. */\n attribute?: string;\n}\n\n/** One tag's capture config in the SDK payload (`SdkConfigResponse.tagging.properties`). */\nexport interface TagPropertyConfig {\n kind: \"page\" | \"feature\";\n tagId: string;\n /** Page rules (pages) or feature rules (features), evaluated in the browser. */\n pageRules?: PageRule[];\n featureRules?: FeatureRule[];\n properties: TagPropertyDefinition[];\n}\n\nexport interface TaggingSdkConfig {\n /** Attribute that names features automatically (null = off). */\n featureAttribute: string | null;\n properties: TagPropertyConfig[];\n}\n\nexport const TAG_PROPERTY_LIMITS = { perTag: 10, total: 50, value: 100 } as const;\n\n/** Attribute names an event property may read. */\nexport function propertyAttributeAllowed(name: string): boolean {\n const n = name.toLowerCase();\n if (n === \"value\" || n.startsWith(\"on\") || n === \"style\" || n === \"srcdoc\") return false;\n return /^[a-z][a-z0-9_:.-]{0,60}$/.test(n);\n}\n","/**\n * The script-tag install snippet's stub. It defines `window.Guidely` before the SDK has loaded, so\n * the page can call `Guidely.init(…)` and `Guidely.get().identify(…)` straight away: calls are\n * queued and replayed by the SDK when it arrives (`packages/embed`). If the SDK can't load at all\n * (Guidely unreachable, blocked by an extension), the calls simply do nothing and the page carries on.\n *\n * Queued calls are `[onClient, method, args]` in `Guidely._q`; `Guidely.get()` returns `Guidely._c`,\n * which the SDK upgrades in place to forward to the real client. Flag reads return their fallback\n * until then. ES5 only: it runs on the customer's page before anything else.\n */\nexport const SCRIPT_STUB_METHODS = [\n \"identify\",\n \"track\",\n \"page\",\n \"reset\",\n \"setAccount\",\n \"updateTraits\",\n \"setConsent\",\n \"setLocale\",\n \"startGuide\",\n \"stopGuide\",\n \"dismissGuide\",\n \"openMessenger\",\n \"closeMessenger\",\n \"showNewMessage\",\n \"openResourceCenter\",\n \"closeResourceCenter\",\n \"openChecklist\",\n \"closeChecklist\",\n \"completeChecklistTask\",\n \"openComplaint\",\n \"openIdeas\",\n \"captureException\",\n \"agentConversation\",\n \"trackAgentTurn\",\n \"on\",\n] as const;\n\nexport const SCRIPT_STUB = `!function(w){if(w.Guidely)return;var g=w.Guidely={_q:[]},c=g._c={};function q(o,k){o[k]=function(){g._q.push([o===c?1:0,k,[].slice.call(arguments)])}}q(g,\"init\");\"${SCRIPT_STUB_METHODS.join(\" \")}\".split(\" \").forEach(function(k){q(c,k)});c.isFeatureEnabled=function(k,f){return!!f};c.getFeatureValue=function(k,f){return f};g.get=function(){return c}}(window);`;\n\n/** The full script-tag install: stub, init (queued until the SDK loads), then the async SDK script. */\nexport function scriptSnippet(scriptUrl: string, initOptions: string): string {\n return `<script>\n ${SCRIPT_STUB}\n Guidely.init(${initOptions});\n</script>\n<script src=\"${scriptUrl}\" async></script>`;\n}\n","/**\n * Guide and resource-center localization (zod-free, so the browser SDK can import it).\n *\n * Every translatable text field has a stable key derived from ids, never from positions, so\n * reordering steps keeps translations attached: `steps.<stepId>.title`,\n * `steps.<stepId>.buttons.<buttonId>.label`, `checklist.tasks.<taskId>.title`,\n * `survey.questions.<questionId>.options.<optionId>.label`, …\n *\n * A visitor's language comes from (in order) an explicit SDK locale, the `language` / `locale`\n * trait, then the browser / device language. `resolveLocale` matches it against the languages a\n * guide is translated into (exact tag first, then the base language) and falls back to the\n * project's default language, in which the guide is written.\n */\nimport type { GuideConfig } from \"./guide\";\nimport type { PublishedGuide, ResourceCenterAnnouncement, ResourceCenterArticle, ResourceCenterConfig } from \"./sdk-api\";\n\nexport type TextKind = \"text\" | \"html\";\n\nexport interface TextEntry {\n key: string;\n /** Default-language text. */\n source: string;\n kind: TextKind;\n /** Human-readable location for translators (\"Step 2 · Title\"). */\n label: string;\n}\n\n/** Project-level language settings (Project.settings.localization). */\nexport interface LocalizationSettings {\n /** Language the content is written in. */\n defaultLocale: string;\n /** Additional languages offered for translation. */\n locales: string[];\n /** Machine-translate new and changed text into every language automatically. */\n autoTranslate?: boolean;\n /** Machine translations need a teammate's approval before visitors see them. */\n requireReview?: boolean;\n}\n\n/**\n * Review state of one translated text. `machine` texts were written by AI translation; `human`\n * ones were typed or imported by a teammate (approved by doing so). `outdated` means the source\n * text changed after the translation was written or approved.\n */\nexport interface TranslationReviewState {\n origin: \"machine\" | \"human\";\n approved: boolean;\n outdated: boolean;\n reviewedBy?: string | null;\n reviewedAt?: string | null;\n}\n\n/** locale → key → review state. Texts without a state are human translations from before review existed. */\nexport type TranslationReviewMap = Record<string, Record<string, TranslationReviewState>>;\n\n/** Does this translation still need a teammate to look at it? */\nexport function needsReview(state: TranslationReviewState | undefined): boolean {\n return !!state && ((state.origin === \"machine\" && !state.approved) || state.outdated);\n}\n\nexport const DEFAULT_LOCALE = \"en\";\n\n/** Common languages offered in the dashboard's language picker (any BCP 47 tag is accepted). */\nexport const COMMON_LOCALES: Array<{ code: string; name: string }> = [\n { code: \"en\", name: \"English\" },\n { code: \"en-GB\", name: \"English (UK)\" },\n { code: \"fr\", name: \"French\" },\n { code: \"fr-CA\", name: \"French (Canada)\" },\n { code: \"de\", name: \"German\" },\n { code: \"es\", name: \"Spanish\" },\n { code: \"es-MX\", name: \"Spanish (Mexico)\" },\n { code: \"it\", name: \"Italian\" },\n { code: \"pt\", name: \"Portuguese\" },\n { code: \"pt-BR\", name: \"Portuguese (Brazil)\" },\n { code: \"nl\", name: \"Dutch\" },\n { code: \"sv\", name: \"Swedish\" },\n { code: \"da\", name: \"Danish\" },\n { code: \"nb\", name: \"Norwegian\" },\n { code: \"fi\", name: \"Finnish\" },\n { code: \"pl\", name: \"Polish\" },\n { code: \"cs\", name: \"Czech\" },\n { code: \"tr\", name: \"Turkish\" },\n { code: \"ru\", name: \"Russian\" },\n { code: \"uk\", name: \"Ukrainian\" },\n { code: \"ar\", name: \"Arabic\" },\n { code: \"he\", name: \"Hebrew\" },\n { code: \"hi\", name: \"Hindi\" },\n { code: \"ja\", name: \"Japanese\" },\n { code: \"ko\", name: \"Korean\" },\n { code: \"zh-Hans\", name: \"Chinese (Simplified)\" },\n { code: \"zh-Hant\", name: \"Chinese (Traditional)\" },\n { code: \"id\", name: \"Indonesian\" },\n { code: \"th\", name: \"Thai\" },\n { code: \"vi\", name: \"Vietnamese\" },\n];\n\nexport function localeName(code: string): string {\n const exact = COMMON_LOCALES.find((l) => l.code.toLowerCase() === code.toLowerCase());\n if (exact) return exact.name;\n const base = COMMON_LOCALES.find((l) => l.code.toLowerCase() === baseLanguage(code));\n return base ? `${base.name} (${code})` : code;\n}\n\n/** `fr_FR` / `FR-fr` → `fr-FR`; script subtags keep title case (`zh-hans` → `zh-Hans`). Invalid input → \"\". */\nexport function normalizeLocale(input: unknown): string {\n if (typeof input !== \"string\") return \"\";\n const parts = input.trim().replace(/_/g, \"-\").split(\"-\").filter(Boolean);\n if (!parts.length || !/^[a-zA-Z]{2,3}$/.test(parts[0]!)) return \"\";\n return parts\n .slice(0, 3)\n .map((p, i) => (i === 0 ? p.toLowerCase() : p.length === 4 ? p[0]!.toUpperCase() + p.slice(1).toLowerCase() : p.length === 2 ? p.toUpperCase() : p))\n .join(\"-\");\n}\n\nexport function baseLanguage(locale: string): string {\n return normalizeLocale(locale).split(\"-\")[0] ?? \"\";\n}\n\n/**\n * Picks the language to show: for each requested locale in order, an exact match among\n * `available`, else one sharing its base language (`fr-CA` → `fr`, `fr` → `fr-FR`). Falls back to\n * `defaultLocale`. Matching ignores case.\n */\nexport function resolveLocale(requested: ReadonlyArray<string | null | undefined>, available: readonly string[], defaultLocale: string = DEFAULT_LOCALE): string {\n const def = normalizeLocale(defaultLocale) || DEFAULT_LOCALE;\n const avail = available.map(normalizeLocale).filter(Boolean);\n const all = [def, ...avail.filter((a) => a.toLowerCase() !== def.toLowerCase())];\n for (const raw of requested) {\n const want = normalizeLocale(raw);\n if (!want) continue;\n const exact = all.find((a) => a.toLowerCase() === want.toLowerCase());\n if (exact) return exact;\n const base = baseLanguage(want);\n const sameBase = all.find((a) => a.toLowerCase() === base) ?? all.find((a) => baseLanguage(a) === base);\n if (sameBase) return sameBase;\n }\n return def;\n}\n\n/** Locale candidates for a visitor: explicit option, traits (`language`, `locale`), then the platform's languages. */\nexport function visitorLocales(explicit: string | null | undefined, traits: Record<string, unknown> | null | undefined, platform: ReadonlyArray<string | null | undefined> = []): string[] {\n const out: string[] = [];\n const push = (v: unknown) => {\n const n = normalizeLocale(v);\n if (n && !out.includes(n)) out.push(n);\n };\n push(explicit);\n push(traits?.language);\n push(traits?.locale);\n for (const p of platform) push(p);\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Guides\n// ---------------------------------------------------------------------------\n\n/** Every translatable text in a guide config, in display order. Empty texts are skipped. */\nexport function guideTextEntries(config: Pick<GuideConfig, \"steps\" | \"checklist\" | \"survey\">): TextEntry[] {\n const out: TextEntry[] = [];\n const add = (key: string, source: string | undefined | null, kind: TextKind, label: string) => {\n if (source && source.trim()) out.push({ key, source, kind, label });\n };\n config.steps.forEach((s, i) => {\n const at = `Step ${i + 1}`;\n add(`steps.${s.id}.title`, s.title, \"text\", `${at} · Title`);\n add(`steps.${s.id}.body`, s.body, \"html\", `${at} · Body`);\n add(`steps.${s.id}.customHtml`, s.customHtml, \"html\", `${at} · Custom HTML`);\n add(`steps.${s.id}.imageAlt`, s.imageAlt, \"text\", `${at} · Image description`);\n s.buttons.forEach((b) => add(`steps.${s.id}.buttons.${b.id}.label`, b.label, \"text\", `${at} · Button “${b.label}”`));\n });\n const c = config.checklist;\n if (c) {\n add(\"checklist.launcherLabel\", c.launcherLabel, \"text\", \"Checklist · Launcher label\");\n add(\"checklist.completionTitle\", c.completionTitle, \"text\", \"Checklist · Completion title\");\n add(\"checklist.completionBody\", c.completionBody, \"html\", \"Checklist · Completion message\");\n c.tasks.forEach((t, i) => {\n add(`checklist.tasks.${t.id}.title`, t.title, \"text\", `Task ${i + 1} · Title`);\n add(`checklist.tasks.${t.id}.description`, t.description, \"html\", `Task ${i + 1} · Description`);\n });\n }\n const sv = config.survey;\n if (sv) {\n sv.questions.forEach((q, i) => {\n const at = `Question ${i + 1}`;\n add(`survey.questions.${q.id}.title`, q.title, \"text\", `${at} · Question`);\n add(`survey.questions.${q.id}.description`, q.description, \"text\", `${at} · Description`);\n add(`survey.questions.${q.id}.placeholder`, q.placeholder, \"text\", `${at} · Placeholder`);\n add(`survey.questions.${q.id}.lowLabel`, q.lowLabel, \"text\", `${at} · Low label`);\n add(`survey.questions.${q.id}.highLabel`, q.highLabel, \"text\", `${at} · High label`);\n q.options.forEach((o) => add(`survey.questions.${q.id}.options.${o.id}.label`, o.label, \"text\", `${at} · Option “${o.label}”`));\n });\n add(\"survey.thankYouTitle\", sv.thankYouTitle, \"text\", \"Survey · Thank-you title\");\n add(\"survey.thankYouBody\", sv.thankYouBody, \"html\", \"Survey · Thank-you message\");\n }\n return out;\n}\n\n/** Locales a guide has any translation for. */\nexport function guideLocales(config: Pick<GuideConfig, \"localization\">): string[] {\n const t = config.localization?.translations ?? {};\n return Object.keys(t).filter((l) => Object.values(t[l] ?? {}).some((v) => typeof v === \"string\" && v.trim() !== \"\"));\n}\n\nfunction pick(map: Record<string, string> | undefined, key: string, fallback: string): string;\nfunction pick(map: Record<string, string> | undefined, key: string, fallback: string | undefined): string | undefined;\nfunction pick(map: Record<string, string> | undefined, key: string, fallback: string | undefined): string | undefined {\n const v = map?.[key];\n return typeof v === \"string\" && v.trim() !== \"\" ? v : fallback;\n}\n\n/** The config with one language's translations applied (untranslated texts keep the default language). */\nexport function applyGuideTranslations<C extends Pick<GuideConfig, \"steps\" | \"checklist\" | \"survey\">>(config: C, map: Record<string, string> | undefined): C {\n if (!map || !Object.keys(map).length) return config;\n return {\n ...config,\n steps: config.steps.map((s) => ({\n ...s,\n title: pick(map, `steps.${s.id}.title`, s.title),\n body: pick(map, `steps.${s.id}.body`, s.body),\n customHtml: pick(map, `steps.${s.id}.customHtml`, s.customHtml),\n imageAlt: pick(map, `steps.${s.id}.imageAlt`, s.imageAlt),\n buttons: s.buttons.map((b) => ({ ...b, label: pick(map, `steps.${s.id}.buttons.${b.id}.label`, b.label) })),\n })),\n checklist: config.checklist\n ? {\n ...config.checklist,\n launcherLabel: pick(map, \"checklist.launcherLabel\", config.checklist.launcherLabel),\n completionTitle: pick(map, \"checklist.completionTitle\", config.checklist.completionTitle),\n completionBody: pick(map, \"checklist.completionBody\", config.checklist.completionBody),\n tasks: config.checklist.tasks.map((t) => ({ ...t, title: pick(map, `checklist.tasks.${t.id}.title`, t.title), description: pick(map, `checklist.tasks.${t.id}.description`, t.description) })),\n }\n : config.checklist,\n survey: config.survey\n ? {\n ...config.survey,\n thankYouTitle: pick(map, \"survey.thankYouTitle\", config.survey.thankYouTitle),\n thankYouBody: pick(map, \"survey.thankYouBody\", config.survey.thankYouBody),\n questions: config.survey.questions.map((q) => ({\n ...q,\n title: pick(map, `survey.questions.${q.id}.title`, q.title),\n description: pick(map, `survey.questions.${q.id}.description`, q.description),\n placeholder: pick(map, `survey.questions.${q.id}.placeholder`, q.placeholder),\n lowLabel: pick(map, `survey.questions.${q.id}.lowLabel`, q.lowLabel),\n highLabel: pick(map, `survey.questions.${q.id}.highLabel`, q.highLabel),\n options: q.options.map((o) => ({ ...o, label: pick(map, `survey.questions.${q.id}.options.${o.id}.label`, o.label) })),\n })),\n }\n : config.survey,\n };\n}\n\n/**\n * The guide as a visitor speaking `requested` should see it, with `locale` set to the language\n * chosen (the default language when none of the guide's translations match).\n */\nexport function localizeGuide(guide: PublishedGuide, requested: readonly string[], defaultLocale: string = DEFAULT_LOCALE): PublishedGuide & { locale: string } {\n const translations = guide.config.localization?.translations ?? {};\n const locale = resolveLocale(requested, guideLocales(guide.config), defaultLocale);\n const key = Object.keys(translations).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());\n if (!key) return { ...guide, locale };\n return { ...guide, locale, config: applyGuideTranslations(guide.config, translations[key]) };\n}\n\nexport interface TranslationCoverage {\n locale: string;\n total: number;\n translated: number;\n /** Keys with no translation. */\n missing: string[];\n /** Keys whose translation exists but whose key no longer matches any text (stale). */\n stale: string[];\n}\n\nexport function translationCoverage(entries: readonly TextEntry[], map: Record<string, string> | undefined, locale: string): TranslationCoverage {\n const keys = new Set(entries.map((e) => e.key));\n const missing = entries.filter((e) => !pick(map, e.key, undefined)).map((e) => e.key);\n const stale = Object.keys(map ?? {}).filter((k) => !keys.has(k) && (map?.[k] ?? \"\").trim() !== \"\");\n return { locale, total: entries.length, translated: entries.length - missing.length, missing, stale };\n}\n\n// ---------------------------------------------------------------------------\n// Resource center\n// ---------------------------------------------------------------------------\n\n/** Translations carried by the published resource center (texts other than articles and announcements). */\nexport type ResourceCenterTranslations = Record<string, Record<string, string>>;\n\n/** Translatable resource-center texts (title, launcher label, links, FAQs, collections). */\nexport function resourceCenterTextEntries(rc: Pick<ResourceCenterConfig, \"title\" | \"launcher\" | \"links\" | \"faqs\" | \"collections\">): TextEntry[] {\n const out: TextEntry[] = [];\n const add = (key: string, source: string | undefined | null, kind: TextKind, label: string) => {\n if (source && source.trim()) out.push({ key, source, kind, label });\n };\n add(\"title\", rc.title, \"text\", \"Title\");\n add(\"launcher.label\", rc.launcher?.label, \"text\", \"Launcher label\");\n rc.collections.forEach((c) => {\n add(`collections.${c.id}.name`, c.name, \"text\", `Collection “${c.name}”`);\n add(`collections.${c.id}.description`, c.description, \"text\", `Collection “${c.name}” · Description`);\n });\n rc.links.forEach((l) => add(`links.${l.id}.label`, l.label, \"text\", `Link “${l.label}”`));\n rc.faqs.forEach((f, i) => {\n add(`faqs.${f.id}.question`, f.question, \"text\", `FAQ ${i + 1} · Question`);\n add(`faqs.${f.id}.answer`, f.answer, \"html\", `FAQ ${i + 1} · Answer`);\n });\n return out;\n}\n\n/** Article texts, keyed `title` / `summary` / `body`. */\nexport function articleTextEntries(a: { title: string; summary?: string | null; body?: string | null }): TextEntry[] {\n const out: TextEntry[] = [];\n if (a.title.trim()) out.push({ key: \"title\", source: a.title, kind: \"text\", label: \"Title\" });\n if (a.summary?.trim()) out.push({ key: \"summary\", source: a.summary, kind: \"text\", label: \"Summary\" });\n if (a.body?.trim()) out.push({ key: \"body\", source: a.body, kind: \"html\", label: \"Body\" });\n return out;\n}\n\n/** Locales the resource center offers (its own strings, articles or announcements). */\nexport function resourceCenterLocales(rc: ResourceCenterConfig): string[] {\n const set = new Set<string>(Object.keys(rc.translations ?? {}));\n for (const a of rc.articles) for (const l of Object.keys(a.translations ?? {})) set.add(l);\n for (const a of rc.announcements ?? []) for (const l of Object.keys(a.translations ?? {})) set.add(l);\n return [...set];\n}\n\nfunction translationFor<T>(map: Record<string, T> | undefined, locale: string): T | undefined {\n if (!map) return undefined;\n const key = Object.keys(map).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());\n return key ? map[key] : undefined;\n}\n\nexport function localizeArticle(a: ResourceCenterArticle, locale: string): ResourceCenterArticle {\n const t = translationFor(a.translations, locale);\n if (!t) return a;\n const body = t.body?.trim() ? t.body : a.body;\n // A translated body that was left out of the snapshot is fetched with `?locale=`.\n return { ...a, title: t.title?.trim() ? t.title : a.title, summary: t.summary?.trim() ? t.summary : a.summary, body, ...(t.bodyOmitted ? { bodyOmitted: true } : {}) };\n}\n\nexport function localizeAnnouncement(a: ResourceCenterAnnouncement, locale: string): ResourceCenterAnnouncement {\n const t = translationFor(a.translations, locale);\n if (!t) return a;\n return { ...a, title: t.title?.trim() ? t.title : a.title, body: t.body?.trim() ? t.body : a.body };\n}\n\n/** The resource center in the visitor's language (with `locale` = the language chosen). */\nexport function localizeResourceCenter(rc: ResourceCenterConfig, requested: readonly string[], defaultLocale: string = DEFAULT_LOCALE): ResourceCenterConfig & { locale: string } {\n const locale = resolveLocale(requested, resourceCenterLocales(rc), defaultLocale);\n if (locale.toLowerCase() === normalizeLocale(defaultLocale).toLowerCase()) return { ...rc, locale };\n const map = translationFor(rc.translations, locale);\n return {\n ...rc,\n locale,\n title: pick(map, \"title\", rc.title),\n launcher: { ...rc.launcher, label: pick(map, \"launcher.label\", rc.launcher.label) },\n collections: rc.collections.map((c) => ({ ...c, name: pick(map, `collections.${c.id}.name`, c.name), description: pick(map, `collections.${c.id}.description`, c.description) })),\n links: rc.links.map((l) => ({ ...l, label: pick(map, `links.${l.id}.label`, l.label) })),\n faqs: rc.faqs.map((f) => ({ ...f, question: pick(map, `faqs.${f.id}.question`, f.question), answer: pick(map, `faqs.${f.id}.answer`, f.answer) })),\n articles: rc.articles.map((a) => localizeArticle(a, locale)),\n announcements: rc.announcements?.map((a) => localizeAnnouncement(a, locale)),\n };\n}\n","/**\n * Guide A/B tests (zod-free; shared by the server, the web SDK and the mobile SDK ports).\n *\n * Each visitor falls into a bucket 0–99: `rolloutBucket(userId || anonymousId, salt)` (FNV-1a,\n * see utils.ts), with `salt = experimentSalt(experimentId)`. Variants own consecutive bucket ranges\n * in their listed order, sized by their integer weights (which sum to 100). The server folds each\n * variant's range into the targeting it serves as two `experiment.bucket` rules, so every SDK\n * applies the split with the rule engine it already has, and assignment is the same everywhere:\n * the server's `assignGuideVariant` and an SDK evaluating the served rules always agree.\n */\nimport { rolloutBucket } from \"./utils\";\nimport type { Rule, RuleGroup } from \"./targeting-eval\";\n\n/** The \"no guide\" variant: visitors in it see nothing, and are measured against the guide variants. */\nexport const CONTROL_VARIANT_ID = \"control\";\n\nexport const GUIDE_EXPERIMENT_STATUSES = [\"draft\", \"running\", \"completed\"] as const;\nexport type GuideExperimentStatus = (typeof GUIDE_EXPERIMENT_STATUSES)[number];\n\nexport const GUIDE_EXPERIMENT_GOALS = [\"guide_completed\", \"event\", \"page_visit\", \"click_text\"] as const;\nexport type GuideExperimentGoalKind = (typeof GUIDE_EXPERIMENT_GOALS)[number];\n\nexport const GUIDE_EXPERIMENT_GOAL_LABELS: Record<GuideExperimentGoalKind, string> = {\n guide_completed: \"Completes the guide\",\n event: \"Tracks an event\",\n page_visit: \"Visits a page\",\n click_text: \"Clicks an element with text\",\n};\n\nexport interface GuideExperimentGoal {\n kind: GuideExperimentGoalKind;\n /** Event name, page path pattern (`/billing/*`) or click text, depending on `kind`. */\n value?: string;\n}\n\nexport interface GuideExperimentVariant {\n id: string;\n name: string;\n /** The guide shown to this variant; null for the control group (no guide). */\n guideId: string | null;\n /** Share of visitors, a whole percentage; all weights sum to 100. */\n weight: number;\n}\n\nexport function experimentSalt(experimentId: string): string {\n return `gx:${experimentId}`;\n}\n\n/** Bucket ranges `[from, to)` per variant, in order. */\nexport function variantRanges(variants: ReadonlyArray<Pick<GuideExperimentVariant, \"id\" | \"weight\">>): Array<{ id: string; from: number; to: number }> {\n let at = 0;\n return variants.map((v) => {\n const from = at;\n at = Math.min(100, at + Math.max(0, Math.round(v.weight)));\n return { id: v.id, from, to: at };\n });\n}\n\n/** The variant a visitor is in, or null when weights leave their bucket unassigned. */\nexport function assignGuideVariant(variants: ReadonlyArray<Pick<GuideExperimentVariant, \"id\" | \"weight\">>, experimentId: string, subject: string): string | null {\n const bucket = rolloutBucket(subject, experimentSalt(experimentId));\n return variantRanges(variants).find((r) => bucket >= r.from && bucket < r.to)?.id ?? null;\n}\n\n/** Rules restricting targeting to bucket range `[from, to)` of `salt`. */\nexport function experimentBucketRules(salt: string, from: number, to: number): Rule[] {\n return [\n { id: \"experiment-from\", field: \"experiment.bucket\", key: salt, op: \"gte\", value: from },\n { id: \"experiment-to\", field: \"experiment.bucket\", key: salt, op: \"lt\", value: to },\n ];\n}\n\n/** Targeting with a variant's bucket range folded in (an SDK without `experiment.bucket` shows the guide to nobody). */\nexport function withExperimentBucket(targeting: RuleGroup, salt: string, from: number, to: number): RuleGroup {\n return { id: \"experiment\", op: \"and\", rules: [...experimentBucketRules(salt, from, to), targeting] };\n}\n\n/** Problems with a variant list; empty when it can run. */\nexport function variantProblems(variants: ReadonlyArray<GuideExperimentVariant>): string[] {\n const problems: string[] = [];\n if (variants.length < 2) problems.push(\"An A/B test needs at least two variants.\");\n if (variants.length > 5) problems.push(\"An A/B test can have at most five variants.\");\n const guides = variants.filter((v) => v.guideId);\n if (guides.length === 0) problems.push(\"At least one variant must show a guide.\");\n if (variants.filter((v) => !v.guideId).length > 1) problems.push(\"Only one variant can be the control group (no guide).\");\n if (new Set(guides.map((v) => v.guideId)).size !== guides.length) problems.push(\"Each variant needs its own guide.\");\n if (new Set(variants.map((v) => v.id)).size !== variants.length) problems.push(\"Variant ids must be unique.\");\n if (variants.some((v) => !Number.isInteger(v.weight) || v.weight < 1)) problems.push(\"Every variant needs a whole-number share of at least 1%.\");\n const total = variants.reduce((s, v) => s + v.weight, 0);\n if (total !== 100) problems.push(`Traffic shares must add up to 100% (now ${total}%).`);\n return problems;\n}\n\n/** Splits 100% as evenly as possible across `n` variants (first ones get the remainder). */\nexport function evenWeights(n: number): number[] {\n if (n <= 0) return [];\n const base = Math.floor(100 / n);\n return Array.from({ length: n }, (_, i) => base + (i < 100 - base * n ? 1 : 0));\n}\n","/**\n * Custom CSS for guides and themes (zod-free; the server sanitizes on save, the web runtime\n * sanitizes again and scopes before injecting).\n *\n * Guides render inside the SDK's Shadow DOM, so page styles and guide styles never mix. Within the\n * shadow root, every rule is additionally prefixed with the guide's own container selector, so one\n * guide's CSS can't restyle another guide, the resource center or the messenger. Sanitizing removes\n * what could reach outside the container or load anything: `@import`, `:host` / `::slotted` rules,\n * `url()`s other than https images and `data:image/…`, legacy script hooks (`expression()`,\n * `behavior`, `-moz-binding`, `javascript:`) and any markup.\n */\n\nexport const MAX_CUSTOM_CSS = 20000;\n\nconst BLOCKED_AT_RULES = /^@(import|charset|namespace|document|-moz-document)\\b/i;\nconst ALLOWED_AT_RULES = /^@(media|supports|container|layer|keyframes|-webkit-keyframes|font-face)\\b/i;\n\ninterface Block {\n /** Selector or at-rule prelude; \"\" for a bare declaration list. */\n prelude: string;\n /** Declarations (for rules) or nested CSS (for grouping at-rules). */\n body: string;\n}\n\n/** Splits CSS into top-level `prelude { body }` blocks, respecting strings and nesting. Statements without a block are dropped. */\nfunction splitBlocks(css: string): Block[] {\n const out: Block[] = [];\n let i = 0;\n const n = css.length;\n while (i < n) {\n let prelude = \"\";\n let quote: string | null = null;\n while (i < n) {\n const ch = css[i]!;\n if (quote) {\n prelude += ch;\n if (ch === \"\\\\\") prelude += css[++i] ?? \"\";\n else if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n prelude += ch;\n } else if (ch === \"{\") break;\n else if (ch === \";\") {\n prelude = \"\"; // a statement (e.g. @import) – dropped\n } else if (ch === \"}\") {\n prelude = \"\"; // stray brace\n } else prelude += ch;\n i++;\n }\n if (i >= n) break;\n // css[i] === \"{\"\n i++;\n let depth = 1;\n let body = \"\";\n quote = null;\n while (i < n && depth > 0) {\n const ch = css[i]!;\n if (quote) {\n body += ch;\n if (ch === \"\\\\\") body += css[++i] ?? \"\";\n else if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n body += ch;\n } else if (ch === \"{\") {\n depth++;\n body += ch;\n } else if (ch === \"}\") {\n depth--;\n if (depth > 0) body += ch;\n } else body += ch;\n i++;\n }\n out.push({ prelude: prelude.trim(), body });\n }\n return out;\n}\n\n/** Splits a selector list on top-level commas. */\nfunction splitSelectors(list: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let cur = \"\";\n for (const ch of list) {\n if (ch === \"(\" || ch === \"[\") depth++;\n else if (ch === \")\" || ch === \"]\") depth = Math.max(0, depth - 1);\n if (ch === \",\" && depth === 0) {\n out.push(cur.trim());\n cur = \"\";\n } else cur += ch;\n }\n if (cur.trim()) out.push(cur.trim());\n return out;\n}\n\nfunction safeUrl(raw: string): boolean {\n const u = raw.trim().replace(/^['\"]|['\"]$/g, \"\").trim();\n return /^https:\\/\\//i.test(u) || /^data:image\\/(png|jpe?g|gif|webp|svg\\+xml)[;,]/i.test(u);\n}\n\n/** Cleans one declaration list. */\nfunction cleanDeclarations(body: string): string {\n return body\n .replace(/url\\(([^)]*)\\)/gi, (m, inner: string) => (safeUrl(inner) ? m : \"none\"))\n .replace(/expression\\s*\\(/gi, \"(\")\n .replace(/javascript\\s*:/gi, \"\")\n .replace(/(^|[;{\\s])(-moz-binding|behavior)\\s*:[^;]*;?/gi, \"$1\")\n .replace(/[{}]/g, \"\")\n .trim();\n}\n\n/** Removes everything unsafe; keeps the rule structure. */\nexport function sanitizeCustomCss(input: string | null | undefined): string {\n if (!input) return \"\";\n let css = String(input).slice(0, MAX_CUSTOM_CSS);\n css = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/<(script|style)\\b[^>]*>[\\s\\S]*?<\\/\\1\\s*>/gi, \"\").replace(/<\\/?[a-z!][^>]*>/gi, \"\").replace(/</g, \"\");\n return render(splitBlocks(css), 0);\n}\n\nfunction render(blocks: Block[], depth: number): string {\n const parts: string[] = [];\n for (const b of blocks) {\n if (!b.prelude) continue;\n if (b.prelude.startsWith(\"@\")) {\n if (BLOCKED_AT_RULES.test(b.prelude) || !ALLOWED_AT_RULES.test(b.prelude)) continue;\n if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) {\n // Keyframe selectors (from/to/50%) and font-face descriptors are declarations-like.\n const inner = /^@font-face/i.test(b.prelude) ? cleanDeclarations(b.body) : splitBlocks(b.body).map((k) => `${k.prelude}{${cleanDeclarations(k.body)}}`).join(\"\");\n parts.push(`${b.prelude}{${inner}}`);\n } else if (depth < 3) parts.push(`${b.prelude}{${render(splitBlocks(b.body), depth + 1)}}`);\n continue;\n }\n const selectors = splitSelectors(b.prelude).filter((s) => !/:host|::slotted|::part/i.test(s));\n if (!selectors.length) continue;\n parts.push(`${selectors.join(\",\")}{${cleanDeclarations(b.body)}}`);\n }\n return parts.join(\"\\n\");\n}\n\n/**\n * Prefixes every selector with `scope` (e.g. `.g-scope[data-guide=\"abc\"]`). `:root`, `html`,\n * `body`, `:scope` and `&` at the start of a selector refer to the container itself.\n */\nexport function scopeCustomCss(css: string, scope: string): string {\n return scopeBlocks(splitBlocks(sanitizeCustomCss(css)), scope, 0);\n}\n\nfunction scopeBlocks(blocks: Block[], scope: string, depth: number): string {\n const parts: string[] = [];\n for (const b of blocks) {\n if (b.prelude.startsWith(\"@\")) {\n if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) parts.push(`${b.prelude}{${b.body}}`);\n else if (depth < 3) parts.push(`${b.prelude}{${scopeBlocks(splitBlocks(b.body), scope, depth + 1)}}`);\n continue;\n }\n const sels = splitSelectors(b.prelude).map((s) => {\n const self = s.match(/^(:root|html|body|:scope|&)(?![\\w-])(.*)$/i);\n if (self) return `${scope}${self[2] ?? \"\"}`;\n return `${scope} ${s}`;\n });\n parts.push(`${sels.join(\",\")}{${b.body}}`);\n }\n return parts.join(\"\\n\");\n}\n","/**\n * Translation exchange files: XLIFF 1.2 (what translation tools and agencies expect) and CSV (for\n * spreadsheets). Both carry one target language; units are identified by their translation key.\n * Import reads XLIFF 1.2 and 2.x (`<trans-unit>` / `<unit>`) and CSVs with a `key` column plus a\n * `target` (or locale-named) column.\n */\n\nexport interface TranslationUnit {\n key: string;\n source: string;\n target: string;\n /** Where the text appears, for translators. */\n note?: string;\n}\n\nexport interface ParsedTranslations {\n targetLocale?: string;\n /** key → translated text (empty translations are left out). */\n entries: Record<string, string>;\n}\n\nfunction xmlEscape(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n}\n\nfunction xmlUnescape(s: string): string {\n return s\n .replace(/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>/g, (_, c: string) => c.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\"))\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&#(\\d+);/g, (_, d: string) => String.fromCodePoint(Number(d)))\n .replace(/&#x([0-9a-f]+);/gi, (_, h: string) => String.fromCodePoint(parseInt(h, 16)))\n .replace(/&amp;/g, \"&\");\n}\n\nexport function toXliff(units: readonly TranslationUnit[], opts: { sourceLocale: string; targetLocale: string; original: string }): string {\n const body = units\n .map(\n (u) =>\n ` <trans-unit id=\"${xmlEscape(u.key)}\">\\n <source>${xmlEscape(u.source)}</source>\\n <target${u.target ? \"\" : ' state=\"needs-translation\"'}>${xmlEscape(u.target)}</target>${u.note ? `\\n <note>${xmlEscape(u.note)}</note>` : \"\"}\\n </trans-unit>`,\n )\n .join(\"\\n\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\\n <file original=\"${xmlEscape(opts.original)}\" source-language=\"${xmlEscape(opts.sourceLocale)}\" target-language=\"${xmlEscape(opts.targetLocale)}\" datatype=\"html\">\\n <body>\\n${body}\\n </body>\\n </file>\\n</xliff>\\n`;\n}\n\nexport function parseXliff(xml: string): ParsedTranslations {\n const target = xml.match(/target-language=\"([^\"]+)\"/)?.[1] ?? xml.match(/\\btrgLang=\"([^\"]+)\"/)?.[1];\n const entries: Record<string, string> = {};\n for (const m of xml.matchAll(/<(trans-unit|unit)\\b[^>]*\\bid=\"([^\"]*)\"[^>]*>([\\s\\S]*?)<\\/\\1>/g)) {\n const key = xmlUnescape(m[2]!);\n const t = m[3]!.match(/<target\\b[^>]*>([\\s\\S]*?)<\\/target>/);\n const text = t ? xmlUnescape(t[1]!) : \"\";\n if (key && text.trim()) entries[key] = text;\n }\n return { targetLocale: target ? xmlUnescape(target) : undefined, entries };\n}\n\nfunction csvCell(s: string): string {\n return /[\",\\n\\r]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\n}\n\n/** CSV with columns key, context, source, <targetLocale>. */\nexport function toTranslationCsv(units: readonly TranslationUnit[], targetLocale: string): string {\n const rows = [[\"key\", \"context\", \"source\", targetLocale], ...units.map((u) => [u.key, u.note ?? \"\", u.source, u.target])];\n return rows.map((r) => r.map(csvCell).join(\",\")).join(\"\\r\\n\") + \"\\r\\n\";\n}\n\n/** RFC 4180 CSV parsing (quoted fields, doubled quotes, CRLF/LF). */\nexport function parseCsvRows(text: string): string[][] {\n const rows: string[][] = [];\n let row: string[] = [];\n let cell = \"\";\n let quoted = false;\n const src = text.replace(/^\\uFEFF/, \"\");\n for (let i = 0; i < src.length; i++) {\n const ch = src[i]!;\n if (quoted) {\n if (ch === '\"') {\n if (src[i + 1] === '\"') {\n cell += '\"';\n i++;\n } else quoted = false;\n } else cell += ch;\n } else if (ch === '\"') quoted = true;\n else if (ch === \",\") {\n row.push(cell);\n cell = \"\";\n } else if (ch === \"\\n\" || ch === \"\\r\") {\n if (ch === \"\\r\" && src[i + 1] === \"\\n\") i++;\n row.push(cell);\n rows.push(row);\n row = [];\n cell = \"\";\n } else cell += ch;\n }\n if (cell !== \"\" || row.length) {\n row.push(cell);\n rows.push(row);\n }\n return rows.filter((r) => r.some((c) => c.trim() !== \"\"));\n}\n\n/** Reads a translation CSV: the `key` column and the `target` column, else the last column not named key/context/source/label. */\nexport function parseTranslationCsv(text: string): ParsedTranslations {\n const [header, ...rows] = parseCsvRows(text);\n if (!header) return { entries: {} };\n const names = header.map((h) => h.trim());\n const lower = names.map((h) => h.toLowerCase());\n const keyCol = lower.indexOf(\"key\");\n if (keyCol < 0) return { entries: {} };\n let targetCol = lower.indexOf(\"target\");\n if (targetCol < 0) {\n for (let i = names.length - 1; i >= 0; i--) {\n if (![\"key\", \"context\", \"source\", \"label\", \"note\"].includes(lower[i]!)) {\n targetCol = i;\n break;\n }\n }\n }\n if (targetCol < 0) return { entries: {} };\n const entries: Record<string, string> = {};\n for (const r of rows) {\n const key = (r[keyCol] ?? \"\").trim();\n const value = r[targetCol] ?? \"\";\n if (key && value.trim()) entries[key] = value;\n }\n return { targetLocale: lower[targetCol] === \"target\" ? undefined : names[targetCol], entries };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["id","import_zod","import_zod","str","import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","id","id","has","id","import_zod","words","words","pick","id","quoted","re","quoted"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/platform.ts","../src/widgets.ts","../src/targeting.ts","../src/targeting-eval.ts","../src/guide.ts","../src/contrast.ts","../src/events.ts","../src/events-util.ts","../src/errors.ts","../src/sdk-api.ts","../src/messenger.ts","../src/complaints.ts","../src/complaints-limits.ts","../src/agents.ts","../src/agents-limits.ts","../src/feedback.ts","../src/feedback-limits.ts","../src/capture.ts","../src/network.ts","../src/templates.ts","../src/media.ts","../src/resource-center.ts","../src/howto.ts","../src/howto-limits.ts","../src/page.ts","../src/tagging.ts","../src/snippet.ts","../src/localization.ts","../src/guide-experiments.ts","../src/custom-css.ts","../src/translation-files.ts"],"sourcesContent":["export * from \"./utils\";\nexport * from \"./platform\";\nexport * from \"./widgets\";\nexport * from \"./targeting\";\nexport * from \"./guide\";\nexport * from \"./events\";\nexport * from \"./sdk-api\";\nexport * from \"./messenger\";\nexport * from \"./complaints\";\nexport * from \"./agents\";\nexport * from \"./feedback\";\nexport * from \"./capture\";\nexport * from \"./network\";\nexport * from \"./templates\";\nexport * from \"./media\";\nexport * from \"./resource-center\";\nexport * from \"./howto\";\nexport * from \"./page\";\nexport * from \"./tagging\";\nexport * from \"./snippet\";\nexport * from \"./localization\";\nexport * from \"./guide-experiments\";\nexport * from \"./custom-css\";\nexport * from \"./contrast\";\nexport * from \"./translation-files\";\nexport const SDK_API_VERSION = \"v1\";\nexport const SHARED_VERSION = \"0.15.0\";\n","/** FNV-1a 32-bit hash; deterministic across SDK and server for rollout bucketing. */\nexport function fnv1a(input: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h >>> 0;\n}\n\n/** Deterministic 0-99 bucket for percentage rollouts. */\nexport function rolloutBucket(subject: string, salt: string): number {\n return fnv1a(`${salt}:${subject}`) % 100;\n}\n\nexport function slugify(input: string): string {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 64) || \"untitled\";\n}\n\nconst ALPHABET = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n/** URL-safe random id. Uses crypto when available, falls back to Math.random (ids are not secrets). */\nexport function randomId(size = 16): string {\n const g: any = typeof globalThis !== \"undefined\" ? globalThis : {};\n let bytes: Uint8Array;\n if (g.crypto && typeof g.crypto.getRandomValues === \"function\") {\n bytes = new Uint8Array(size);\n g.crypto.getRandomValues(bytes);\n } else {\n bytes = new Uint8Array(size);\n for (let i = 0; i < size; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n let out = \"\";\n for (let i = 0; i < size; i++) out += ALPHABET[(bytes[i] as number) % ALPHABET.length];\n return out;\n}\n\nexport function isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Safe nested getter: get(obj, \"account.plan\") */\nexport function getPath(obj: unknown, path: string): unknown {\n if (!path) return obj;\n let cur: any = obj;\n for (const part of path.split(\".\")) {\n if (cur == null) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\nexport function clamp(n: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, n));\n}\n\n/** Glob-style URL pattern match: `*` matches any chars except `/`, `**` matches anything. */\nexport function matchUrlPattern(pattern: string, url: string): boolean {\n if (!pattern) return true;\n if (pattern === url) return true;\n const escaped = pattern\n .replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*\\*/g, \"__GLOBSTAR__\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/__GLOBSTAR__/g, \".*\");\n const re = new RegExp(`^${escaped}$`);\n return re.test(url) || re.test(stripOrigin(url));\n}\n\nexport function stripOrigin(url: string): string {\n try {\n const u = new URL(url);\n return u.pathname + u.search + u.hash;\n } catch {\n return url;\n }\n}\n\n/** Safe regexp construction with a length cap to limit ReDoS exposure. */\nexport function safeRegExp(source: string, flags = \"i\"): RegExp | null {\n if (!source || source.length > 200) return null;\n try {\n return new RegExp(source, flags);\n } catch {\n return null;\n }\n}\n","/**\n * Cross-platform helpers shared by the web SDK, the React Native SDK and (as a reference for) the\n * native iOS/Android SDKs. Zod-free so it can ship in runtime bundles.\n */\n\n/** Platforms a guide can be delivered to. */\nexport const PLATFORMS = [\"web\", \"ios\", \"android\"] as const;\nexport type Platform = (typeof PLATFORMS)[number];\n\n/** Guides published before platforms existed have no `platforms` field and are web-only. */\nexport const DEFAULT_PLATFORMS: Platform[] = [\"web\"];\n\n/** Platforms a guide config targets (missing field → web only). */\nexport function guidePlatforms(config: { platforms?: readonly string[] | null }): string[] {\n return Array.isArray(config.platforms) ? [...config.platforms] : [...DEFAULT_PLATFORMS];\n}\n\nexport function supportsPlatform(config: { platforms?: readonly string[] | null }, platform: string): boolean {\n return guidePlatforms(config).includes(platform);\n}\n\n/** Attribute web apps put on elements to share a target id with their mobile apps. */\nexport const GUIDELY_ID_ATTRIBUTE = \"data-guidely-id\";\n\n/**\n * Extracts a Guidely target id from a trigger / advance / checklist value so the same guide works on\n * web and mobile. Accepts a bare id (`new-deal`), `#new-deal`, or `[data-guidely-id=\"new-deal\"]`\n * (also `data-testid` / `data-tour`). Returns null for selectors that cannot name a single id.\n */\nexport function guidelyIdFromSelector(value: string | null | undefined): string | null {\n const v = (value ?? \"\").trim();\n if (!v) return null;\n if (/^[A-Za-z0-9_][A-Za-z0-9_\\-:.]*$/.test(v)) return v;\n const hash = v.match(/^#([A-Za-z0-9_][A-Za-z0-9_\\-:.]*)$/);\n if (hash) return hash[1] as string;\n const attr = v.match(/^(?:[a-z][a-z0-9]*)?\\[\\s*data-(?:guidely-id|testid|tour)\\s*=\\s*([\"']?)([^\"'\\]]+)\\1\\s*\\]$/i);\n if (attr) return (attr[2] as string).trim();\n return null;\n}\n\n/**\n * Mobile SDKs have screens instead of URLs. URL-based features (URL patterns, `url_match` triggers,\n * multi-page steps, `url_visited` checklist tasks) match against the screen path `/<ScreenName>`.\n */\nexport function screenPath(screen: string | null | undefined): string {\n const s = (screen ?? \"\").trim();\n if (!s) return \"/\";\n return s.startsWith(\"/\") ? s : `/${s}`;\n}\n\n/**\n * Compares dotted version strings numerically (`2.10.0` > `2.9.3`). Non-numeric parts compare as\n * strings; a missing part counts as 0 (`2.1` == `2.1.0`). Returns -1, 0 or 1, or null when either\n * side is empty.\n */\nexport function compareVersions(a: unknown, b: unknown): -1 | 0 | 1 | null {\n const sa = a == null ? \"\" : String(a).trim().replace(/^v/i, \"\");\n const sb = b == null ? \"\" : String(b).trim().replace(/^v/i, \"\");\n if (!sa || !sb) return null;\n const pa = sa.split(/[.+-]/);\n const pb = sb.split(/[.+-]/);\n const n = Math.max(pa.length, pb.length);\n for (let i = 0; i < n; i++) {\n const x = pa[i] ?? \"0\";\n const y = pb[i] ?? \"0\";\n const nx = /^\\d+$/.test(x) ? Number(x) : NaN;\n const ny = /^\\d+$/.test(y) ? Number(y) : NaN;\n if (!Number.isNaN(nx) && !Number.isNaN(ny)) {\n if (nx !== ny) return nx < ny ? -1 : 1;\n } else if (x !== y) {\n return x < y ? -1 : 1;\n }\n }\n return 0;\n}\n","/**\n * Pure checklist / survey logic shared by every renderer (web runtime, React Native, and the\n * reference for the native SDKs). Zod-free; uses structural types so it stays in the runtime entry.\n */\n\nexport type SurveyAnswer = string | number | boolean | string[];\nexport type SurveyAnswers = Record<string, SurveyAnswer>;\n\nexport interface ShowWhen {\n questionId: string;\n op: \"equals\" | \"lte\" | \"gte\" | \"in\";\n value: string | number | string[];\n}\n\n/** Evaluates a question's `showWhen` condition against current answers. */\nexport function isQuestionVisible(q: { showWhen?: ShowWhen }, answers: SurveyAnswers): boolean {\n if (!q.showWhen) return true;\n const actual = answers[q.showWhen.questionId];\n if (actual === undefined) return false;\n const expected = q.showWhen.value;\n switch (q.showWhen.op) {\n case \"equals\":\n return Array.isArray(actual) ? actual.includes(String(expected)) : String(actual) === String(expected);\n case \"lte\":\n return Number(actual) <= Number(expected);\n case \"gte\":\n return Number(actual) >= Number(expected);\n case \"in\": {\n const list = Array.isArray(expected) ? expected : [String(expected)];\n return Array.isArray(actual) ? actual.some((a) => list.includes(a)) : list.includes(String(actual));\n }\n default:\n return false;\n }\n}\n\n/** Are all required tasks done? */\nexport function isChecklistComplete(config: { tasks: Array<{ id: string; required: boolean }> }, progress: { completedTaskIds: string[] }): boolean {\n const done = new Set(progress.completedTaskIds);\n return config.tasks.filter((t) => t.required).every((t) => done.has(t.id));\n}\n","import { z } from \"zod\";\nimport { RULE_FIELDS, RULE_OPERATORS, type Rule, type RuleGroup } from \"./targeting-eval\";\n\nexport * from \"./targeting-eval\";\n\nexport const RuleSchema: z.ZodType<Rule> = z.object({\n id: z.string().min(1),\n field: z.enum(RULE_FIELDS),\n key: z.string().max(200).optional(),\n op: z.enum(RULE_OPERATORS),\n value: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]).optional(),\n negate: z.boolean().optional(),\n});\n\nexport const RuleGroupSchema: z.ZodType<RuleGroup> = z.lazy(() =>\n z.object({\n id: z.string().min(1),\n op: z.enum([\"and\", \"or\"]),\n rules: z.array(z.union([RuleSchema, RuleGroupSchema])).max(100),\n negate: z.boolean().optional(),\n }),\n);\n","/**\n * Zod-free targeting evaluation. Imported by the browser SDK via `@guidelytech/shared/runtime`\n * so the runtime bundle does not pull in zod. Schemas live in ./targeting.ts.\n */\nimport { compareVersions } from \"./platform\";\nimport { getPath, matchUrlPattern, rolloutBucket, safeRegExp } from \"./utils\";\n\nexport const RULE_OPERATORS = [\n \"equals\",\n \"not_equals\",\n \"contains\",\n \"not_contains\",\n \"starts_with\",\n \"ends_with\",\n \"exists\",\n \"not_exists\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"in\",\n \"not_in\",\n \"regex\",\n \"is_true\",\n \"is_false\",\n \"before\",\n \"after\",\n] as const;\nexport type RuleOperator = (typeof RULE_OPERATORS)[number];\n\nexport const RULE_FIELDS = [\n \"user.attribute\",\n \"account.attribute\",\n \"user.role\",\n \"user.plan\",\n \"user.identified\",\n \"url.path\",\n \"url.full\",\n \"url.query\",\n \"device.type\",\n \"device.browser\",\n \"device.os\",\n \"visitor.firstVisit\",\n \"visitor.returning\",\n \"event.seen\",\n \"guide.completed\",\n \"guide.dismissed\",\n \"guide.seen\",\n \"checklist.completed\",\n \"audience.member\",\n \"datetime.now\",\n \"datetime.dayOfWeek\",\n \"datetime.hour\",\n \"rollout.percentage\",\n /** Guide A/B tests: the visitor's 0-99 bucket for the salt in `key` (see guide-experiments.ts). */\n \"experiment.bucket\",\n \"environment\",\n \"locale\",\n \"app.platform\",\n \"app.screen\",\n \"app.version\",\n \"page.views\",\n \"feature.clicks\",\n] as const;\nexport type RuleField = (typeof RULE_FIELDS)[number];\n\nexport interface Rule {\n id: string;\n field: RuleField;\n /** For attribute/query/event fields: the attribute key, query param name, event name, guide id... */\n key?: string;\n op: RuleOperator;\n value?: string | number | boolean | string[];\n /** When true, the rule is negated (exclusion rule). */\n negate?: boolean;\n}\n\nexport type RuleGroup = {\n id: string;\n op: \"and\" | \"or\";\n rules: Array<Rule | RuleGroup>;\n negate?: boolean;\n};\n\nexport function isRuleGroup(r: Rule | RuleGroup): r is RuleGroup {\n return (r as RuleGroup).rules !== undefined;\n}\n\nexport function emptyRuleGroup(id = \"root\"): RuleGroup {\n return { id, op: \"and\", rules: [] };\n}\n\n/** Everything targeting evaluation can see. Built by the SDK (browser) or the server. */\nexport interface TargetingContext {\n userId?: string | null;\n anonymousId: string;\n userAttributes: Record<string, unknown>;\n accountAttributes: Record<string, unknown>;\n url: string;\n path: string;\n query: Record<string, string>;\n device: { type: \"desktop\" | \"tablet\" | \"mobile\"; browser?: string; os?: string };\n firstVisit: boolean;\n eventsSeen: Set<string> | string[];\n completedGuides: Set<string> | string[];\n dismissedGuides: Set<string> | string[];\n seenGuides: Set<string> | string[];\n completedChecklists: Set<string> | string[];\n audienceIds: Set<string> | string[];\n now: Date;\n environment: string;\n locale?: string;\n /** `web`, `ios` or `android`. Missing means web. */\n platform?: string;\n /** Current screen name (mobile SDKs; set via `screen()`). */\n screen?: string;\n /** Host app version (mobile SDKs), e.g. `2.4.1`. */\n appVersion?: string;\n /** Salt for rollout (guide id). Set per guide before evaluating. */\n rolloutSalt?: string;\n /**\n * Views of tagged pages / clicks on tagged features in the last 30 days, by tag id. Only the server\n * fills it (audience evaluation); in the browser `page.views` / `feature.clicks` read 0.\n */\n tagUsage?: Record<string, number>;\n}\n\nfunction has(set: Set<string> | string[] | undefined, v: string): boolean {\n if (!set) return false;\n return set instanceof Set ? set.has(v) : set.includes(v);\n}\n\nfunction resolveField(rule: Rule, ctx: TargetingContext): unknown {\n switch (rule.field) {\n case \"user.attribute\":\n return rule.key ? getPath(ctx.userAttributes, rule.key) : undefined;\n case \"account.attribute\":\n return rule.key ? getPath(ctx.accountAttributes, rule.key) : undefined;\n case \"user.role\":\n return ctx.userAttributes.role;\n case \"user.plan\":\n return ctx.userAttributes.plan ?? ctx.accountAttributes.plan;\n case \"user.identified\":\n return !!ctx.userId;\n case \"url.path\":\n return ctx.path;\n case \"url.full\":\n return ctx.url;\n case \"url.query\":\n return rule.key ? ctx.query[rule.key] : undefined;\n case \"device.type\":\n return ctx.device.type;\n case \"device.browser\":\n return ctx.device.browser;\n case \"device.os\":\n return ctx.device.os;\n case \"visitor.firstVisit\":\n return ctx.firstVisit;\n case \"visitor.returning\":\n return !ctx.firstVisit;\n case \"event.seen\":\n return rule.key ? has(ctx.eventsSeen, rule.key) : false;\n case \"guide.completed\":\n return rule.key ? has(ctx.completedGuides, rule.key) : false;\n case \"guide.dismissed\":\n return rule.key ? has(ctx.dismissedGuides, rule.key) : false;\n case \"guide.seen\":\n return rule.key ? has(ctx.seenGuides, rule.key) : false;\n case \"checklist.completed\":\n return rule.key ? has(ctx.completedChecklists, rule.key) : false;\n case \"audience.member\":\n return rule.key ? has(ctx.audienceIds, rule.key) : false;\n case \"datetime.now\":\n return ctx.now.toISOString();\n case \"datetime.dayOfWeek\":\n return ctx.now.getDay();\n case \"datetime.hour\":\n return ctx.now.getHours();\n case \"rollout.percentage\":\n return rolloutBucket(ctx.userId || ctx.anonymousId, ctx.rolloutSalt || \"guidely\");\n case \"experiment.bucket\":\n return rule.key ? rolloutBucket(ctx.userId || ctx.anonymousId, rule.key) : undefined;\n case \"environment\":\n return ctx.environment;\n case \"locale\":\n return ctx.locale;\n case \"app.platform\":\n return ctx.platform ?? \"web\";\n case \"app.screen\":\n return ctx.screen;\n case \"app.version\":\n return ctx.appVersion;\n case \"page.views\":\n case \"feature.clicks\":\n return rule.key ? (ctx.tagUsage?.[rule.key] ?? 0) : 0;\n default:\n return undefined;\n }\n}\n\nfunction toNumber(v: unknown): number | null {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\" && v.trim() !== \"\" && !Number.isNaN(Number(v))) return Number(v);\n if (v instanceof Date) return v.getTime();\n return null;\n}\n\nfunction toDateMs(v: unknown): number | null {\n if (v instanceof Date) return v.getTime();\n if (typeof v === \"string\") {\n const t = Date.parse(v);\n return Number.isNaN(t) ? null : t;\n }\n if (typeof v === \"number\") return v;\n return null;\n}\n\nexport function compare(op: RuleOperator, actual: unknown, expected: Rule[\"value\"]): boolean {\n switch (op) {\n case \"exists\":\n return actual !== undefined && actual !== null && actual !== \"\";\n case \"not_exists\":\n return actual === undefined || actual === null || actual === \"\";\n case \"is_true\":\n return actual === true || actual === \"true\";\n case \"is_false\":\n return actual === false || actual === \"false\";\n case \"equals\":\n if (typeof actual === \"boolean\") return String(actual) === String(expected);\n return String(actual ?? \"\") === String(expected ?? \"\");\n case \"not_equals\":\n return String(actual ?? \"\") !== String(expected ?? \"\");\n case \"contains\":\n return typeof actual === \"string\" && actual.toLowerCase().includes(String(expected ?? \"\").toLowerCase());\n case \"not_contains\":\n return !(typeof actual === \"string\" && actual.toLowerCase().includes(String(expected ?? \"\").toLowerCase()));\n case \"starts_with\":\n return typeof actual === \"string\" && actual.startsWith(String(expected ?? \"\"));\n case \"ends_with\":\n return typeof actual === \"string\" && actual.endsWith(String(expected ?? \"\"));\n case \"gt\":\n case \"gte\":\n case \"lt\":\n case \"lte\": {\n const a = toNumber(actual);\n const b = toNumber(expected);\n if (a === null || b === null) return false;\n return op === \"gt\" ? a > b : op === \"gte\" ? a >= b : op === \"lt\" ? a < b : a <= b;\n }\n case \"in\": {\n const list = Array.isArray(expected) ? expected : String(expected ?? \"\").split(\",\").map((s) => s.trim());\n return list.includes(String(actual ?? \"\"));\n }\n case \"not_in\": {\n const list = Array.isArray(expected) ? expected : String(expected ?? \"\").split(\",\").map((s) => s.trim());\n return !list.includes(String(actual ?? \"\"));\n }\n case \"regex\": {\n const re = safeRegExp(String(expected ?? \"\"));\n return !!re && typeof actual === \"string\" && re.test(actual);\n }\n case \"before\": {\n const a = toDateMs(actual);\n const b = toDateMs(expected);\n return a !== null && b !== null && a < b;\n }\n case \"after\": {\n const a = toDateMs(actual);\n const b = toDateMs(expected);\n return a !== null && b !== null && a > b;\n }\n default:\n return false;\n }\n}\n\nexport function evaluateRule(rule: Rule, ctx: TargetingContext): boolean {\n let result: boolean;\n if (rule.field === \"url.path\" || rule.field === \"url.full\" || rule.field === \"app.screen\") {\n const actual = String(resolveField(rule, ctx) ?? \"\");\n if (rule.op === \"equals\") result = matchUrlPattern(String(rule.value ?? \"\"), actual);\n else if (rule.op === \"not_equals\") result = !matchUrlPattern(String(rule.value ?? \"\"), actual);\n else result = compare(rule.op, actual, rule.value);\n } else if (rule.field === \"app.version\" && [\"equals\", \"not_equals\", \"gt\", \"gte\", \"lt\", \"lte\"].includes(rule.op)) {\n const c = compareVersions(resolveField(rule, ctx), rule.value);\n if (c === null) result = rule.op === \"not_equals\";\n else result = rule.op === \"equals\" ? c === 0 : rule.op === \"not_equals\" ? c !== 0 : rule.op === \"gt\" ? c > 0 : rule.op === \"gte\" ? c >= 0 : rule.op === \"lt\" ? c < 0 : c <= 0;\n } else {\n result = compare(rule.op, resolveField(rule, ctx), rule.value);\n }\n return rule.negate ? !result : result;\n}\n\n/** Evaluate a rule tree. An empty group matches everyone. */\nexport function evaluateRules(group: RuleGroup | null | undefined, ctx: TargetingContext): boolean {\n if (!group || group.rules.length === 0) return group?.negate ? false : true;\n const results = group.rules.map((r) => (isRuleGroup(r) ? evaluateRules(r, ctx) : evaluateRule(r, ctx)));\n const value = group.op === \"and\" ? results.every(Boolean) : results.some(Boolean);\n return group.negate ? !value : value;\n}\n\n/** Fields whose evaluation requires server-held data. Used by docs/UI to annotate rules. */\nexport const SERVER_ASSISTED_FIELDS: RuleField[] = [\"audience.member\", \"guide.completed\", \"guide.dismissed\", \"guide.seen\", \"checklist.completed\", \"page.views\", \"feature.clicks\"];\n\n/** Who a guide is shown to, before its targeting rules: everyone, only signed-in (identified) users, or only anonymous visitors. */\nexport const GUIDE_VISIBILITIES = [\"everyone\", \"identified\", \"anonymous\"] as const;\nexport type GuideVisibility = (typeof GUIDE_VISIBILITIES)[number];\n\n/**\n * Targeting with the visibility folded in as a `user.identified` rule. The server sends guides to SDKs\n * this way, so every SDK applies it through the rules it already evaluates (SDKs that predate the field\n * resolve it as undefined and show the guide to nobody rather than to everyone).\n */\nexport function withVisibility(targeting: RuleGroup, visibility: GuideVisibility | undefined): RuleGroup {\n if (!visibility || visibility === \"everyone\") return targeting;\n return { id: \"visibility\", op: \"and\", rules: [{ id: \"visibility-rule\", field: \"user.identified\", op: visibility === \"identified\" ? \"is_true\" : \"is_false\" }, targeting] };\n}\n\nexport function describeRule(rule: Rule): string {\n const subject = rule.key ? `${rule.field}[${rule.key}]` : rule.field;\n const v = Array.isArray(rule.value) ? rule.value.join(\", \") : rule.value === undefined ? \"\" : String(rule.value);\n return `${rule.negate ? \"NOT \" : \"\"}${subject} ${rule.op.replace(/_/g, \" \")}${v ? ` \"${v}\"` : \"\"}`;\n}\n","import { z } from \"zod\";\nimport { PLATFORMS } from \"./platform\";\nimport { GUIDE_VISIBILITIES, RuleGroupSchema, emptyRuleGroup, type RuleGroup } from \"./targeting\";\nimport { contrastIssues } from \"./contrast\";\n\nexport const GUIDE_KINDS = [\"flow\", \"modal\", \"tooltip\", \"banner\", \"checklist\", \"survey\", \"announcement\"] as const;\nexport type GuideKind = (typeof GUIDE_KINDS)[number];\n\nexport const GUIDE_STATUSES = [\"draft\", \"published\", \"paused\", \"archived\"] as const;\nexport type GuideStatus = (typeof GUIDE_STATUSES)[number];\n\nexport const STEP_TYPES = [\"modal\", \"tooltip\", \"popover\", \"spotlight\", \"hotspot\", \"banner\", \"slideout\", \"checklist\", \"custom\", \"survey\"] as const;\nexport type StepType = (typeof STEP_TYPES)[number];\n\nexport const PLACEMENTS = [\"top\", \"top-start\", \"top-end\", \"right\", \"right-start\", \"right-end\", \"bottom\", \"bottom-start\", \"bottom-end\", \"left\", \"left-start\", \"left-end\", \"auto\"] as const;\nexport type Placement = (typeof PLACEMENTS)[number];\n\n/** `guidely-id` is cross-platform: `data-guidely-id` on web, `GuidelyTarget` / `guidelyTarget()` on mobile. */\nexport const SELECTOR_KINDS = [\"css\", \"id\", \"data-attr\", \"aria\", \"text\", \"xpath\", \"guidely-id\"] as const;\nexport const SelectorStrategySchema = z.object({\n kind: z.enum(SELECTOR_KINDS),\n value: z.string().min(1).max(1000),\n /** Optional human-readable label captured at pick time. */\n label: z.string().max(200).optional(),\n});\nexport type SelectorStrategy = z.infer<typeof SelectorStrategySchema>;\n\nexport const TargetSchema = z.object({\n /** Ordered strategies; the first one resolving to exactly one element wins. */\n selectors: z.array(SelectorStrategySchema).max(10),\n /** How long to wait for the element before applying fallback. */\n waitMs: z.number().int().min(0).max(60000).default(5000),\n /** What to do when the element never shows up. */\n fallback: z.enum([\"skip\", \"show_as_modal\", \"end_guide\", \"wait\"]).default(\"skip\"),\n /** Scroll the element into view before positioning. */\n scrollIntoView: z.boolean().default(true),\n /** Text snapshot captured at pick time; used for authoring warnings. */\n textSnapshot: z.string().max(200).optional(),\n});\nexport type StepTarget = z.infer<typeof TargetSchema>;\n\nexport const BUTTON_ACTIONS = [\"next\", \"back\", \"dismiss\", \"complete\", \"skip\", \"url\", \"start_guide\", \"event\", \"open_resource_center\", \"none\"] as const;\nexport const ButtonSchema = z.object({\n id: z.string().min(1),\n label: z.string().min(1).max(80),\n action: z.enum(BUTTON_ACTIONS),\n variant: z.enum([\"primary\", \"secondary\", \"ghost\", \"link\"]).default(\"primary\"),\n /** url for `url`, guide id for `start_guide`, event name for `event`, step id for `next` branch override */\n value: z.string().max(2000).optional(),\n newTab: z.boolean().optional(),\n});\nexport type StepButton = z.infer<typeof ButtonSchema>;\n\nexport const StepBranchSchema = z.object({\n id: z.string(),\n /** Rule group evaluated against targeting context when leaving the step. */\n when: RuleGroupSchema,\n /** Step id to jump to. */\n goTo: z.string(),\n});\n\nexport const ADVANCE_ON = [\"button\", \"element_click\", \"element_visible\", \"event\", \"delay\", \"any\"] as const;\n\nexport const StepSchema = z.object({\n id: z.string().min(1).max(64),\n type: z.enum(STEP_TYPES),\n title: z.string().max(200).default(\"\"),\n /** Sanitized HTML body (links, images, lists, formatting). */\n body: z.string().max(20000).default(\"\"),\n imageUrl: z.string().url().max(2000).optional().or(z.literal(\"\")),\n /** Alternative text for `imageUrl` (screen readers); empty = decorative. */\n imageAlt: z.string().max(300).optional(),\n buttons: z.array(ButtonSchema).max(6).default([]),\n target: TargetSchema.optional(),\n placement: z.enum(PLACEMENTS).default(\"auto\"),\n /** Pixel offset between anchor and card. */\n offset: z.number().int().min(0).max(64).default(10),\n showOverlay: z.boolean().default(false),\n showProgress: z.boolean().default(true),\n showClose: z.boolean().default(true),\n dismissOnOutsideClick: z.boolean().default(false),\n /** Highlight padding for spotlight. */\n spotlightPadding: z.number().int().min(0).max(64).default(6),\n /** Banner/slideout position. */\n position: z.enum([\"top\", \"bottom\", \"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\", \"center\"]).default(\"bottom-right\"),\n /** URL pattern this step belongs to (for multi-page flows). */\n url: z.string().max(500).optional(),\n /** Automatic advancement. */\n advanceOn: z.enum(ADVANCE_ON).default(\"button\"),\n advanceValue: z.string().max(500).optional(),\n advanceDelayMs: z.number().int().min(0).max(600000).optional(),\n branches: z.array(StepBranchSchema).max(10).default([]),\n width: z.number().int().min(200).max(900).optional(),\n /** Step-level targeting: skip step when rules do not match. */\n targeting: RuleGroupSchema.optional(),\n /** Hotspot pulse dot settings. */\n hotspot: z.object({ size: z.number().int().min(8).max(40).default(14), pulse: z.boolean().default(true), openOn: z.enum([\"click\", \"hover\"]).default(\"click\") }).optional(),\n /** Custom step: arbitrary sanitized HTML with no chrome. */\n customHtml: z.string().max(50000).optional(),\n /**\n * Code block (custom steps only): JavaScript run on the web when the step shows, only while the\n * workspace allows code blocks (an admin setting, off by default). Mobile SDKs never receive it.\n */\n code: z.string().max(20000).optional(),\n});\nexport type GuideStep = z.infer<typeof StepSchema>;\nexport type GuideStepInput = z.input<typeof StepSchema>;\n\nexport const TRIGGER_TYPES = [\"page_load\", \"url_match\", \"event\", \"element_click\", \"element_visible\", \"manual\", \"delay\", \"after_guide\", \"segment_enter\"] as const;\nexport const TriggerSchema = z.object({\n type: z.enum(TRIGGER_TYPES).default(\"page_load\"),\n /** url pattern, event name, selector, guide id, audience id depending on type */\n value: z.string().max(1000).optional(),\n delayMs: z.number().int().min(0).max(600000).default(0),\n /** Also require URL to match this pattern (any trigger). */\n urlPattern: z.string().max(500).optional(),\n});\nexport type TriggerConfig = z.infer<typeof TriggerSchema>;\n\nexport const FrequencySchema = z.object({\n mode: z.enum([\"once\", \"once_per_session\", \"every_time\", \"interval\"]).default(\"once\"),\n intervalHours: z.number().int().min(1).max(8760).optional(),\n maxImpressions: z.number().int().min(1).max(1000).optional(),\n /** Hours to wait after dismissal before eligible again (when not `once`). */\n cooldownHours: z.number().int().min(0).max(8760).default(0),\n /** Lower number wins when multiple guides qualify. */\n priority: z.number().int().min(0).max(1000).default(100),\n /** Guide ids that must not be active at the same time. */\n mutuallyExclusiveWith: z.array(z.string()).max(50).default([]),\n /** Re-show if dismissed (otherwise dismissal counts as completion for frequency). */\n reshowAfterDismiss: z.boolean().default(false),\n /** Bypass the project's guide throttling (always eligible as far as throttling goes). */\n ignoreThrottling: z.boolean().optional(),\n});\nexport type FrequencyConfig = z.infer<typeof FrequencySchema>;\n\nexport const AppearanceSchema = z.object({\n theme: z.enum([\"light\", \"dark\", \"auto\"]).default(\"auto\"),\n primaryColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n backgroundColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n textColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),\n borderRadius: z.number().int().min(0).max(32).optional(),\n fontFamily: z.string().max(200).optional(),\n overlayOpacity: z.number().min(0).max(1).optional(),\n zIndex: z.number().int().min(1).max(2147483647).optional(),\n preset: z.string().max(50).optional(),\n animation: z.enum([\"fade\", \"slide\", \"none\"]).default(\"fade\"),\n /** Custom CSS scoped to this guide's container (sanitized; see custom-css.ts). Web only. */\n customCss: z.string().max(20000).optional(),\n});\nexport type Appearance = z.infer<typeof AppearanceSchema>;\n\nexport const ChecklistTaskSchema = z.object({\n id: z.string().min(1),\n title: z.string().min(1).max(200),\n description: z.string().max(2000).default(\"\"),\n /** How the task completes. */\n completion: z.enum([\"manual\", \"event\", \"guide_completed\", \"url_visited\", \"click\"]).default(\"manual\"),\n completionValue: z.string().max(500).optional(),\n /** Optional action when clicking the task. */\n action: z.enum([\"none\", \"start_guide\", \"url\", \"event\"]).default(\"none\"),\n actionValue: z.string().max(2000).optional(),\n required: z.boolean().default(true),\n});\nexport type ChecklistTask = z.infer<typeof ChecklistTaskSchema>;\n\nexport const ChecklistConfigSchema = z.object({\n tasks: z.array(ChecklistTaskSchema).min(1),\n ordered: z.boolean().default(false),\n launcherLabel: z.string().max(60).default(\"Getting started\"),\n position: z.enum([\"bottom-right\", \"bottom-left\"]).default(\"bottom-right\"),\n completionTitle: z.string().max(200).default(\"You're all set!\"),\n completionBody: z.string().max(2000).default(\"\"),\n autoOpen: z.boolean().default(true),\n dismissible: z.boolean().default(true),\n});\nexport type ChecklistConfig = z.infer<typeof ChecklistConfigSchema>;\n\nexport const SURVEY_QUESTION_TYPES = [\"nps\", \"csat\", \"thumbs\", \"single_choice\", \"multiple_choice\", \"text\", \"rating\"] as const;\nexport const SurveyQuestionSchema = z.object({\n id: z.string().min(1),\n type: z.enum(SURVEY_QUESTION_TYPES),\n title: z.string().min(1).max(500),\n description: z.string().max(1000).default(\"\"),\n required: z.boolean().default(true),\n options: z.array(z.object({ id: z.string(), label: z.string().max(200) })).max(20).default([]),\n scaleMax: z.number().int().min(2).max(10).optional(),\n lowLabel: z.string().max(60).optional(),\n highLabel: z.string().max(60).optional(),\n placeholder: z.string().max(200).optional(),\n /** Conditional follow-up: show only when a previous answer matches. */\n showWhen: z.object({ questionId: z.string(), op: z.enum([\"equals\", \"lte\", \"gte\", \"in\"]), value: z.union([z.string(), z.number(), z.array(z.string())]) }).optional(),\n});\nexport type SurveyQuestion = z.infer<typeof SurveyQuestionSchema>;\n\nexport const SurveyConfigSchema = z.object({\n questions: z.array(SurveyQuestionSchema).min(1).max(20),\n thankYouTitle: z.string().max(200).default(\"Thanks for your feedback!\"),\n thankYouBody: z.string().max(2000).default(\"\"),\n position: z.enum([\"bottom-right\", \"bottom-left\", \"center\"]).default(\"bottom-right\"),\n startAt: z.string().datetime().optional(),\n endAt: z.string().datetime().optional(),\n});\nexport type SurveyConfig = z.infer<typeof SurveyConfigSchema>;\n\n/**\n * When any guide may show: `startAt` / `endAt` are UTC instants; `timezone` (IANA, e.g.\n * `Europe/London`) is the zone they were entered in, kept for display only.\n */\nexport const GuideScheduleSchema = z.object({\n startAt: z.string().datetime().optional(),\n endAt: z.string().datetime().optional(),\n timezone: z.string().max(64).optional(),\n});\nexport type GuideSchedule = z.infer<typeof GuideScheduleSchema>;\n\n/** Locale codes: BCP 47 language tags such as `fr`, `pt-BR`, `zh-Hans`. */\nexport const LOCALE_PATTERN = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8}){0,2}$/;\nexport const LocaleSchema = z.string().regex(LOCALE_PATTERN, \"Use a language code such as fr or pt-BR\").max(20);\n\n/**\n * Translations of a guide's text: locale → translation key → text. Keys come from\n * `guideTextEntries` (e.g. `steps.<stepId>.title`); missing keys fall back to the default language.\n */\nexport const GuideLocalizationSchema = z.object({\n translations: z.record(LocaleSchema, z.record(z.string().max(200), z.string().max(50000))).default({}),\n});\nexport type GuideLocalization = z.infer<typeof GuideLocalizationSchema>;\n\n/** Project.settings.localization: the language guides are written in and the languages offered for translation. */\nexport const LocalizationSettingsSchema = z.object({\n defaultLocale: LocaleSchema.default(\"en\"),\n locales: z.array(LocaleSchema).max(50).default([]),\n /** Machine-translate new and changed text into every language automatically (needs an Anthropic key). */\n autoTranslate: z.boolean().optional(),\n /** Machine translations go live only once a teammate approves them; until then visitors see the default language. */\n requireReview: z.boolean().optional(),\n});\n\n/**\n * Project.settings.guideThrottling: limits automatically launched guides per visitor (guides\n * started by a button, a link, Help or `startGuide()` are never throttled; nor are banners,\n * checklists and hotspot-only guides, which don't interrupt).\n */\nexport const GuideThrottlingSchema = z.object({\n enabled: z.boolean().default(false),\n maxGuides: z.number().int().min(1).max(50).default(1),\n windowHours: z.number().int().min(1).max(720).default(24),\n minGapMinutes: z.number().int().min(0).max(10080).default(0),\n});\n\nexport const GuideConfigSchema = z.object({\n steps: z.array(StepSchema).max(50).default([]),\n /** Everyone, only identified (logged-in) users, or only anonymous visitors; applied on top of `targeting`. */\n visibility: z.enum(GUIDE_VISIBILITIES).default(\"everyone\"),\n targeting: RuleGroupSchema.default(() => emptyRuleGroup()),\n trigger: TriggerSchema.default({}),\n frequency: FrequencySchema.default({}),\n appearance: AppearanceSchema.default({}),\n checklist: ChecklistConfigSchema.optional(),\n survey: SurveyConfigSchema.optional(),\n /** Restrict guide to url pattern(s) (applied before trigger). On mobile these match the screen path `/<Screen>`. */\n urlPatterns: z.array(z.string().max(500)).max(20).default([]),\n /** Platforms that receive this guide. Guides created before mobile support are web-only. */\n platforms: z.array(z.enum(PLATFORMS)).max(PLATFORMS.length).default([\"web\"]),\n /** Start / end window for any guide kind (surveys also honour `survey.startAt` / `endAt`). */\n schedule: GuideScheduleSchema.optional(),\n /** Translations (see localization.ts). */\n localization: GuideLocalizationSchema.optional(),\n});\nexport type GuideConfig = z.infer<typeof GuideConfigSchema>;\nexport type GuideConfigInput = z.input<typeof GuideConfigSchema>;\n\nexport function defaultGuideConfig(kind: GuideKind): GuideConfig {\n return GuideConfigSchema.parse({\n steps: kind === \"checklist\" || kind === \"survey\" ? [] : [defaultStep(kind === \"flow\" ? \"tooltip\" : kind === \"banner\" ? \"banner\" : kind === \"tooltip\" ? \"tooltip\" : \"modal\")],\n checklist: kind === \"checklist\" ? { tasks: [{ id: \"task-1\", title: \"Complete your profile\" }] } : undefined,\n survey: kind === \"survey\" ? { questions: [{ id: \"q1\", type: \"nps\", title: \"How likely are you to recommend us to a friend?\" }] } : undefined,\n trigger: kind === \"checklist\" ? { type: \"page_load\" } : {},\n });\n}\n\nlet stepCounter = 0;\nexport function defaultStep(type: StepType, overrides: Partial<GuideStepInput> = {}): GuideStep {\n stepCounter += 1;\n const base: GuideStepInput = {\n id: `step-${Date.now().toString(36)}-${stepCounter}`,\n type,\n title: type === \"modal\" ? \"Welcome!\" : \"Step title\",\n body: \"<p>Describe what the user should do here.</p>\",\n buttons: [\n { id: \"btn-back\", label: \"Back\", action: \"back\", variant: \"ghost\" },\n { id: \"btn-next\", label: \"Next\", action: \"next\", variant: \"primary\" },\n ],\n placement: type === \"banner\" ? \"top\" : \"auto\",\n showOverlay: type === \"modal\" || type === \"spotlight\",\n ...overrides,\n };\n if ([\"tooltip\", \"popover\", \"spotlight\", \"hotspot\"].includes(type) && !base.target) {\n base.target = { selectors: [], waitMs: 5000, fallback: \"skip\", scrollIntoView: true };\n }\n return StepSchema.parse(base);\n}\n\n/** Buttons to show for a step; \"back\" buttons are hidden when there is no previous step to return to. */\nexport function visibleButtons(step: GuideStep, canGoBack: boolean): GuideStep[\"buttons\"] {\n return canGoBack ? step.buttons : step.buttons.filter((b) => b.action !== \"back\");\n}\n\n/** Validation beyond Zod shape: returns human-readable problems that block publishing. */\nexport interface ValidationIssue {\n level: \"error\" | \"warning\";\n stepId?: string;\n message: string;\n}\nexport function validateGuideConfig(kind: GuideKind, config: GuideConfig, theme?: Partial<Pick<ProjectTheme, \"primaryColor\" | \"backgroundColor\" | \"textColor\">>): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n if (kind === \"checklist\") {\n if (!config.checklist || config.checklist.tasks.length === 0) issues.push({ level: \"error\", message: \"Checklist needs at least one task.\" });\n } else if (kind === \"survey\") {\n if (!config.survey || config.survey.questions.length === 0) issues.push({ level: \"error\", message: \"Survey needs at least one question.\" });\n config.survey?.questions.forEach((q) => {\n if ((q.type === \"single_choice\" || q.type === \"multiple_choice\") && q.options.length < 2) issues.push({ level: \"error\", message: `Question \"${q.title}\" needs at least two options.` });\n });\n } else {\n if (config.steps.length === 0) issues.push({ level: \"error\", message: \"Add at least one step.\" });\n }\n if (config.platforms.length === 0) issues.push({ level: \"error\", message: \"Choose at least one platform (web, iOS or Android).\" });\n const mobile = config.platforms.some((p) => p !== \"web\");\n const ids = new Set<string>();\n config.steps.forEach((step, i) => {\n if (ids.has(step.id)) issues.push({ level: \"error\", stepId: step.id, message: `Duplicate step id \"${step.id}\".` });\n ids.add(step.id);\n const anchored = [\"tooltip\", \"popover\", \"spotlight\", \"hotspot\"].includes(step.type);\n if (anchored && (!step.target || step.target.selectors.length === 0)) issues.push({ level: \"error\", stepId: step.id, message: `Step ${i + 1} (${step.type}) needs a target element.` });\n if (mobile && anchored && step.target && step.target.selectors.length > 0 && !step.target.selectors.some((s) => s.kind === \"guidely-id\" || s.kind === \"id\"))\n issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} has no Guidely id or element id target, so mobile apps cannot find its element.` });\n if (mobile && step.type === \"custom\") issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} is a custom HTML step; mobile apps show it as a plain modal.` });\n if (!step.title && !step.body && step.type !== \"custom\") issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} has no title or body.` });\n if (step.buttons.length === 0 && step.advanceOn === \"button\" && step.type !== \"hotspot\" && step.type !== \"custom\") issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} has no buttons and advances on button; users can only close it.` });\n step.buttons.forEach((b) => {\n if (b.action === \"url\" && !/^https?:\\/\\//i.test(b.value || \"\") && !(b.value || \"\").startsWith(\"/\")) issues.push({ level: \"error\", stepId: step.id, message: `Button \"${b.label}\" needs an http(s) or relative URL.` });\n if (b.action === \"start_guide\" && !b.value) issues.push({ level: \"error\", stepId: step.id, message: `Button \"${b.label}\" needs a guide to start.` });\n });\n step.branches.forEach((br) => {\n if (!ids.has(br.goTo) && !config.steps.some((s) => s.id === br.goTo)) issues.push({ level: \"error\", stepId: step.id, message: `Branch points to unknown step \"${br.goTo}\".` });\n });\n });\n if (config.trigger.type === \"event\" && !config.trigger.value) issues.push({ level: \"error\", message: \"Event trigger needs an event name.\" });\n if (config.trigger.type === \"element_click\" && !config.trigger.value) issues.push({ level: \"error\", message: \"Element click trigger needs a selector.\" });\n if (config.trigger.type === \"url_match\" && !config.trigger.value) issues.push({ level: \"error\", message: \"URL trigger needs a pattern.\" });\n if (config.frequency.mode === \"interval\" && !config.frequency.intervalHours) issues.push({ level: \"error\", message: \"Interval frequency needs an interval in hours.\" });\n const sched = config.schedule;\n if (sched?.startAt && sched.endAt && Date.parse(sched.endAt) <= Date.parse(sched.startAt)) issues.push({ level: \"error\", message: \"The schedule ends before it starts.\" });\n if (sched?.endAt && Date.parse(sched.endAt) < Date.now()) issues.push({ level: \"warning\", message: \"The schedule has already ended, so nobody will see this guide.\" });\n config.steps.forEach((step, i) => {\n if (step.code && step.type !== \"custom\") issues.push({ level: \"error\", stepId: step.id, message: `Step ${i + 1}: code blocks can only run in custom steps.` });\n if (step.code && mobile) issues.push({ level: \"warning\", stepId: step.id, message: `Step ${i + 1} runs a code block; mobile apps skip it.` });\n });\n const colors = { primaryColor: config.appearance.primaryColor ?? theme?.primaryColor, backgroundColor: config.appearance.backgroundColor ?? theme?.backgroundColor, textColor: config.appearance.textColor ?? theme?.textColor };\n for (const c of contrastIssues(colors)) issues.push({ level: \"warning\", message: `Low contrast: ${c.message}` });\n return issues;\n}\n\nexport interface ProjectTheme {\n primaryColor: string;\n backgroundColor: string;\n textColor: string;\n borderRadius: number;\n fontFamily: string;\n logoUrl?: string;\n brandName?: string;\n customCss?: string;\n}\nexport const ProjectThemeSchema = z.object({\n primaryColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default(\"#4f46e5\"),\n backgroundColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default(\"#ffffff\"),\n textColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).default(\"#111827\"),\n borderRadius: z.number().int().min(0).max(32).default(12),\n fontFamily: z.string().max(200).default(\"Inter, system-ui, -apple-system, sans-serif\"),\n logoUrl: z.string().max(2000).optional(),\n brandName: z.string().max(100).optional(),\n /** Custom CSS applied to every guide's container (sanitized and scoped like guide CSS). Web only. */\n customCss: z.string().max(20000).optional(),\n});\n\nexport type { RuleGroup };\n","/**\n * WCAG 2.1 colour contrast (zod-free). The editor warns when a guide's colours fall below AA:\n * 4.5:1 for body text, 3:1 for large text and UI components (button outlines, the close icon).\n */\n\nexport const WCAG_AA_TEXT = 4.5;\nexport const WCAG_AA_LARGE = 3;\n\nfunction channel(c: number): number {\n const s = c / 255;\n return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n}\n\n/** `#rgb` / `#rrggbb` → [r, g, b]; null when not a hex colour. */\nexport function parseHexColor(hex: string | null | undefined): [number, number, number] | null {\n if (!hex) return null;\n const m = hex.trim().match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);\n if (!m) return null;\n const h = m[1]!.length === 3 ? m[1]!.split(\"\").map((c) => c + c).join(\"\") : m[1]!;\n return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];\n}\n\nexport function relativeLuminance(hex: string): number | null {\n const rgb = parseHexColor(hex);\n if (!rgb) return null;\n return 0.2126 * channel(rgb[0]) + 0.7152 * channel(rgb[1]) + 0.0722 * channel(rgb[2]);\n}\n\n/** Contrast ratio 1–21 between two hex colours, or null when either is not a hex colour. */\nexport function contrastRatio(a: string, b: string): number | null {\n const la = relativeLuminance(a);\n const lb = relativeLuminance(b);\n if (la === null || lb === null) return null;\n const [hi, lo] = la > lb ? [la, lb] : [lb, la];\n return Math.round(((hi + 0.05) / (lo + 0.05)) * 100) / 100;\n}\n\n/** Text colour (black or white) with the better contrast on `background`. */\nexport function readableTextOn(background: string): \"#ffffff\" | \"#111827\" {\n const white = contrastRatio(background, \"#ffffff\") ?? 0;\n const dark = contrastRatio(background, \"#111827\") ?? 0;\n return white >= dark ? \"#ffffff\" : \"#111827\";\n}\n\nexport interface ContrastIssue {\n /** What is hard to read. */\n pair: \"text\" | \"button\" | \"link\";\n ratio: number;\n required: number;\n message: string;\n}\n\n/**\n * Contrast problems of a guide's effective colours (guide appearance over the project theme).\n * Buttons use white or dark text, whichever reads better, so only a mid-tone primary colour fails.\n */\nexport function contrastIssues(colors: { primaryColor?: string; backgroundColor?: string; textColor?: string }): ContrastIssue[] {\n const issues: ContrastIssue[] = [];\n const { primaryColor, backgroundColor, textColor } = colors;\n if (textColor && backgroundColor) {\n const r = contrastRatio(textColor, backgroundColor);\n if (r !== null && r < WCAG_AA_TEXT) issues.push({ pair: \"text\", ratio: r, required: WCAG_AA_TEXT, message: `Text on the background has a contrast of ${r}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });\n }\n if (primaryColor) {\n const label = contrastRatio(primaryColor, readableTextOn(primaryColor));\n if (label !== null && label < WCAG_AA_TEXT) issues.push({ pair: \"button\", ratio: label, required: WCAG_AA_TEXT, message: `Button labels on the primary colour have a contrast of ${label}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });\n if (backgroundColor) {\n const link = contrastRatio(primaryColor, backgroundColor);\n if (link !== null && link < WCAG_AA_LARGE) issues.push({ pair: \"link\", ratio: link, required: WCAG_AA_LARGE, message: `The primary colour on the background (links, outlined buttons) has a contrast of ${link}:1; WCAG AA needs ${WCAG_AA_LARGE}:1.` });\n }\n }\n return issues;\n}\n","import { z } from \"zod\";\n\nexport const EVENT_NAMES = [\n \"guide_viewed\",\n \"guide_started\",\n \"step_viewed\",\n \"step_completed\",\n \"guide_completed\",\n \"guide_skipped\",\n \"guide_dismissed\",\n \"guide_abandoned\",\n \"checklist_task_completed\",\n \"checklist_completed\",\n \"checklist_dismissed\",\n \"survey_displayed\",\n \"survey_submitted\",\n \"survey_dismissed\",\n \"resource_center_opened\",\n \"article_viewed\",\n \"messenger_opened\",\n \"conversation_started\",\n \"conversation_handed_off\",\n \"scout_answered\",\n \"custom\",\n \"page_view\",\n \"identify\",\n // Product analytics (autocapture + error tracking)\n \"page_leave\",\n \"click\",\n \"rage_click\",\n \"exception\",\n \"heatmap\",\n // Feature flags: a user was bucketed into an experiment variation (properties: experimentKey, variationId, flagKey).\n \"experiment_viewed\",\n // Mobile app lifecycle (mobile/SPEC.md \"Product analytics\"): installs, updates, opens and backgrounding.\n \"app_install\",\n \"app_update\",\n \"app_open\",\n \"app_background\",\n] as const;\nexport type EventName = (typeof EVENT_NAMES)[number];\n\n/** Events the SDK records on its own (page analytics, click autocapture, error tracking). */\nexport const AUTOCAPTURE_EVENTS = [\"page_view\", \"page_leave\", \"click\", \"rage_click\", \"exception\", \"heatmap\", \"app_install\", \"app_update\", \"app_open\", \"app_background\"] as const;\n\n/** Mobile app lifecycle events (`autocapture.appLifecycle`). */\nexport const APP_LIFECYCLE_EVENTS = [\"app_install\", \"app_update\", \"app_open\", \"app_background\"] as const;\n\nexport const GUIDE_LIFECYCLE_EVENTS = [\"guide_viewed\", \"guide_started\", \"step_viewed\", \"step_completed\", \"guide_completed\", \"guide_skipped\", \"guide_dismissed\", \"guide_abandoned\"] as const;\n\n/** Event as produced by the SDK and accepted by POST /api/v1/sdk/events */\nexport const SdkEventSchema = z.object({\n eventId: z.string().min(8).max(64),\n name: z.enum(EVENT_NAMES),\n /** For `custom` events: the application-defined name. */\n customName: z.string().min(1).max(120).optional(),\n occurredAt: z.string().datetime({ offset: true }),\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n accountId: z.string().max(256).optional().nullable(),\n sessionId: z.string().max(128).optional(),\n guideId: z.string().max(64).optional(),\n guideVersion: z.number().int().optional(),\n stepId: z.string().max(64).optional(),\n stepIndex: z.number().int().min(0).optional(),\n url: z.string().max(2000).optional(),\n properties: z.record(z.unknown()).optional(),\n});\nexport type SdkEvent = z.infer<typeof SdkEventSchema>;\n\nexport const EventBatchSchema = z.object({\n events: z.array(SdkEventSchema).min(1).max(50),\n sentAt: z.string().datetime({ offset: true }).optional(),\n sdk: z.object({ name: z.string().max(60), version: z.string().max(30) }).optional(),\n});\nexport type EventBatch = z.infer<typeof EventBatchSchema>;\n\nexport * from \"./events-util\";\nexport * from \"./errors\";\n","/** Reserved property names that are stripped from `properties` to avoid collecting sensitive data. */\nexport const SENSITIVE_PROPERTY_PATTERN = /(password|passwd|secret|token|credit|card|cvv|ssn|iban)/i;\n\nexport const MAX_PROPERTY_BYTES = 8 * 1024;\n\nexport function sanitizeProperties(props: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!props) return {};\n const out: Record<string, unknown> = {};\n let size = 0;\n for (const [k, v] of Object.entries(props)) {\n if (SENSITIVE_PROPERTY_PATTERN.test(k)) continue;\n if (typeof v === \"function\" || typeof v === \"symbol\") continue;\n const str = typeof v === \"string\" ? v : JSON.stringify(v ?? null);\n size += k.length + (str?.length ?? 0);\n if (size > MAX_PROPERTY_BYTES) break;\n out[k.slice(0, 100)] = typeof v === \"string\" ? v.slice(0, 1000) : v;\n }\n return out;\n}\n","import { fnv1a } from \"./utils\";\n\n/** One parsed stack frame. `file` is the script URL (or path) as the browser reported it. */\nexport interface StackFrame {\n fn?: string;\n file?: string;\n line?: number;\n col?: number;\n}\n\n/** Properties carried by an `exception` event (see `docs/product-analytics.md`). */\nexport interface ExceptionProperties {\n type: string;\n message: string;\n frames: StackFrame[];\n /** `onerror` | `unhandledrejection` | `manual` (captureException) | `console`. */\n source?: string;\n handled?: boolean;\n /** App version or commit (SDK option `release`); selects the matching uploaded source maps. */\n release?: string;\n /** Set by the server at ingestion; groups occurrences into an issue. */\n fingerprint?: string;\n}\n\nexport const MAX_STACK_FRAMES = 30;\n\n// Chrome / Edge / Node: \" at fn (https://x/app.js:1:2)\" or \" at https://x/app.js:1:2\"\nconst V8 = /^\\s*at (?:(.+?) \\()?((?:[a-z][\\w+.-]*:)?[^\\s()]+?):(\\d+):(\\d+)\\)?\\s*$/i;\n// Firefox / Safari: \"fn@https://x/app.js:1:2\" or \"@https://x/app.js:1:2\"\nconst GECKO = /^\\s*(.*?)@(.+?):(\\d+):(\\d+)\\s*$/;\n\n/** Parses `Error.stack` from V8, SpiderMonkey and JavaScriptCore into frames (innermost first). */\nexport function parseStack(stack: string | undefined | null, max = MAX_STACK_FRAMES): StackFrame[] {\n if (!stack || typeof stack !== \"string\") return [];\n const frames: StackFrame[] = [];\n for (const raw of stack.split(\"\\n\")) {\n if (frames.length >= max) break;\n const line = raw.slice(0, 1000);\n const m = V8.exec(line) ?? GECKO.exec(line);\n if (!m) continue;\n const fn = (m[1] || \"\").trim();\n frames.push({ fn: fn ? fn.slice(0, 200) : undefined, file: m[2]?.slice(0, 500), line: Number(m[3]), col: Number(m[4]) });\n }\n return frames;\n}\n\n/** Replaces volatile parts of a message (numbers, ids, quoted values) so repeats group together. */\nexport function normalizeErrorMessage(message: string): string {\n return (message || \"\")\n .slice(0, 500)\n .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, \"<uuid>\")\n .replace(/([\"'`]).*?\\1/g, \"<str>\")\n .replace(/\\b0x[0-9a-f]+\\b/gi, \"<hex>\")\n .replace(/\\d+(\\.\\d+)?/g, \"<n>\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/** Strips origin, query, hash and build hashes (`main.3f2a1b9c.js` → `main.js`) from a script URL. */\nexport function normalizeFrameFile(file: string | undefined): string {\n if (!file) return \"\";\n let path = file;\n try {\n path = new URL(file).pathname;\n } catch {\n path = file.replace(/[?#].*$/, \"\");\n }\n return path.replace(/[.-][0-9a-f]{6,}(?=\\.\\w+$)/i, \"\").replace(/\\/\\d+\\//g, \"/<n>/\");\n}\n\n/** Source map upload limits (`POST /api/v1/sourcemaps/upload`). */\n/** Per map, uncompressed (the CLI uploads maps gzipped). */\nexport const SOURCEMAP_MAX_FILE_BYTES = 100 * 1024 * 1024;\nexport const SOURCEMAP_MAX_FILES_PER_UPLOAD = 200;\n\n/**\n * Stable issue key for an exception: error type + normalised message + the innermost frame that\n * has a file (path without build hash + function name, or its original source + name when a source\n * map resolved it). Line/column numbers are left out because they change with every deploy of a\n * minified bundle.\n */\nexport function fingerprintError(input: { type?: string; message?: string; frames?: StackFrame[]; original?: { source: string; name?: string | null } | null }): string {\n const top = (input.frames ?? []).find((f) => f.file);\n // With a source map the original file and function name identify the frame across deploys, even\n // when a minifier renames functions between builds.\n const frameKey = input.original ? `src:${input.original.source}:${input.original.name || \"?\"}` : top ? `${normalizeFrameFile(top.file)}:${top.fn || \"?\"}` : \"\";\n const key = [input.type || \"Error\", normalizeErrorMessage(input.message || \"\"), frameKey].join(\"|\");\n const a = fnv1a(key).toString(16).padStart(8, \"0\");\n const b = fnv1a(`guidely:${key}`).toString(16).padStart(8, \"0\");\n return a + b;\n}\n","import { z } from \"zod\";\nimport { GuideConfigSchema, ProjectThemeSchema, type GuideKind, type GuideConfig } from \"./guide\";\nimport type { RuleGroup } from \"./targeting-eval\";\nimport type { ResourceCenterModuleId } from \"./resource-center\";\nimport type { MessengerConfig } from \"./messenger\";\nimport type { AutocaptureSettings, ErrorTrackingSettings, ReplaySettings } from \"./capture\";\nimport type { TaggingSdkConfig } from \"./tagging\";\n\n/** A published guide as delivered to the SDK. Draft-only data (author, notes) is never included. */\nexport interface PublishedGuide {\n id: string;\n key: string;\n name: string;\n kind: GuideKind;\n version: number;\n config: GuideConfig;\n publishedAt: string;\n /**\n * Set while the guide is a variant of a running guide A/B test. Its targeting already carries the\n * variant's `experiment.bucket` range; SDKs record an `experiment_viewed` exposure\n * (`{ guideExperimentId, variantId, guideId }`) when it shows.\n */\n experiment?: { id: string; variantId: string };\n}\n\n/**\n * The control group of a running guide A/B test: the base guide's targeting, trigger and frequency\n * restricted to the control bucket. SDKs evaluate it like a guide but never render it; when it would\n * show they record the `experiment_viewed` exposure (variant `control`) and its local impression.\n * SDKs that don't know `guideHoldouts` ignore it (control visitors then simply see nothing).\n */\nexport interface GuideHoldout {\n experimentId: string;\n variantId: string;\n guide: PublishedGuide;\n}\n\n/** Project-wide limit on automatically shown guides (Project.settings.guideThrottling). */\nexport interface GuideThrottlingSettings {\n enabled: boolean;\n /** At most this many auto-launched guides per visitor within `windowHours`. */\n maxGuides: number;\n windowHours: number;\n /** Minimum minutes between two auto-launched guides. */\n minGapMinutes: number;\n}\n\nexport interface ResourceCenterArticle {\n id: string;\n slug: string;\n title: string;\n summary: string;\n body: string;\n /** True when `body` was left out of the config to keep it small; fetch it from `GET /sdk/articles/:id`. */\n bodyOmitted?: boolean;\n collectionId?: string | null;\n externalUrl?: string | null;\n /** Listed only for members of any of these audiences (absent = everyone). Not access control. */\n audienceIds?: string[];\n /** Guide keys of the article's \"Show me\" prompts (absent = none); the first one is offered in Help results. */\n walkthroughs?: string[];\n /** The article plays a video. */\n hasVideo?: boolean;\n updatedAt: string;\n /** Translations by locale; a `bodyOmitted` translation is fetched with `GET /sdk/articles/:id?locale=`. */\n translations?: Record<string, { title?: string; summary?: string; body?: string; bodyOmitted?: boolean }>;\n}\n\n/** A \"What's new\" entry in the resource center. */\nexport interface ResourceCenterAnnouncement {\n id: string;\n title: string;\n /** Sanitized HTML. */\n body: string;\n publishedAt: string;\n /** Guide id or key started by its \"Show me\" button. */\n guideId?: string | null;\n articleId?: string | null;\n url?: string | null;\n linkLabel?: string | null;\n /** Listed only for members of any of these audiences (absent = everyone). */\n audienceIds?: string[];\n translations?: Record<string, { title?: string; body?: string }>;\n}\n\n/** A section of the resource center, in display order; hidden when disabled or its targeting doesn't match. */\nexport interface ResourceCenterModule {\n id: ResourceCenterModuleId;\n enabled: boolean;\n /** Evaluated by the SDK like guide targeting (absent = everyone). */\n targeting?: RuleGroup | null;\n}\n\nexport interface ResourceCenterCollection {\n id: string;\n name: string;\n description: string;\n order: number;\n /** Parent collection for nested collections (absent/null = top level). */\n parentId?: string | null;\n /** Listed only for members of any of these audiences, with everything inside it (absent = everyone). */\n audienceIds?: string[];\n}\n\nexport interface ResourceCenterConfig {\n enabled: boolean;\n title: string;\n launcher: { position: \"bottom-right\" | \"bottom-left\"; label: string; showIcon: boolean };\n collections: ResourceCenterCollection[];\n articles: ResourceCenterArticle[];\n recommendedGuideIds: string[];\n checklistGuideIds: string[];\n links: Array<{ id: string; label: string; url: string }>;\n faqs: Array<{ id: string; question: string; answer: string }>;\n /** \"What's new\" (newest first). Absent from servers that predate it. */\n announcements?: ResourceCenterAnnouncement[];\n /** Section order and targeting; absent = every section in the default order. */\n modules?: ResourceCenterModule[];\n /** Translations of the strings above (see `resourceCenterTextEntries`), by locale. */\n translations?: Record<string, Record<string, string>>;\n}\n\nexport interface SdkConfigResponse {\n projectId: string;\n environment: string;\n configVersion: number;\n theme: z.infer<typeof ProjectThemeSchema>;\n guides: PublishedGuide[];\n /** Control groups of running guide A/B tests (see GuideHoldout); absent from older servers. */\n guideHoldouts?: GuideHoldout[];\n resourceCenter: ResourceCenterConfig | null;\n /** Scout messenger; absent from servers that predate it. */\n messenger?: MessengerConfig | null;\n settings: {\n analyticsEnabled: boolean;\n collectUrls: boolean;\n maskSelectors: string[];\n sessionTimeoutMinutes: number;\n /** Product analytics; absent from servers that predate it (the SDK then captures nothing extra). */\n autocapture?: AutocaptureSettings;\n errorTracking?: ErrorTrackingSettings;\n /** `retentionDays` is server-side only and not sent. */\n replay?: Omit<ReplaySettings, \"retentionDays\">;\n /** Project-wide guide throttling; absent or disabled = no limit. */\n throttling?: GuideThrottlingSettings;\n /** The language guides are written in, and the languages they may be translated into. */\n localization?: { defaultLocale: string; locales: string[] };\n };\n /** Tagged pages and features: the feature attribute and DOM event properties; absent from servers that predate them. */\n tagging?: TaggingSdkConfig;\n generatedAt: string;\n}\n\nexport const IdentifyRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().min(1).max(256).optional().nullable(),\n traits: z.record(z.unknown()).optional(),\n account: z\n .object({ id: z.string().min(1).max(256), traits: z.record(z.unknown()).optional() })\n .optional()\n .nullable(),\n sessionId: z.string().max(128).optional(),\n url: z.string().max(2000).optional(),\n});\nexport type IdentifyRequest = z.infer<typeof IdentifyRequestSchema>;\n\n/** Server-held state the SDK needs for targeting & frequency. */\nexport interface IdentifyResponse {\n endUserId: string;\n audienceIds: string[];\n guideState: Record<\n string,\n { impressions: number; completedAt?: string | null; dismissedAt?: string | null; lastShownAt?: string | null }\n >;\n /** `dismissResetAt` changes when a teammate resets the user's dismissal; SDKs then drop their cached `dismissedAt`. */\n checklistProgress: Record<string, { completedTaskIds: string[]; completedAt?: string | null; dismissedAt?: string | null; dismissResetAt?: string | null }>;\n surveysSubmitted: string[];\n firstSeenAt: string;\n}\n\nexport const ChecklistProgressRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n guideVersion: z.number().int().optional(),\n completedTaskIds: z.array(z.string().max(64)).max(100),\n dismissed: z.boolean().optional(),\n completed: z.boolean().optional(),\n});\nexport type ChecklistProgressRequest = z.infer<typeof ChecklistProgressRequestSchema>;\n\nexport const SurveyResponseRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n accountId: z.string().max(256).optional().nullable(),\n guideVersion: z.number().int(),\n answers: z.record(z.union([z.string().max(5000), z.number(), z.boolean(), z.array(z.string().max(500)).max(50)])),\n responseId: z.string().min(8).max(64),\n});\nexport type SurveyResponseRequest = z.infer<typeof SurveyResponseRequestSchema>;\n\nexport const GuideStateUpdateSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n updates: z\n .array(\n z.object({\n guideId: z.string(),\n impression: z.boolean().optional(),\n completed: z.boolean().optional(),\n dismissed: z.boolean().optional(),\n }),\n )\n .max(50),\n});\n\nexport const AuthoringPickSchema = z.object({\n stepId: z.string().max(64).optional(),\n selectors: z.array(z.object({ kind: z.string(), value: z.string().max(1000), label: z.string().max(200).optional() })).max(10),\n textSnapshot: z.string().max(200).optional(),\n url: z.string().max(2000).optional(),\n rect: z.object({ x: z.number(), y: z.number(), width: z.number(), height: z.number() }).optional(),\n /** Compact snapshot of the picked element (tag mode: feature rules are proposed from it). */\n elementSnapshot: z.record(z.unknown()).optional(),\n});\nexport type AuthoringPick = z.infer<typeof AuthoringPickSchema>;\n\n/**\n * Static, script-free copy of the page an authoring session is connected to. The SDK posts it to\n * the dashboard (never to the API) so the editor canvas can show the customer's real app.\n */\nexport interface AppSnapshot {\n /** Full HTML document (doctype included) with scripts and Guidely UI removed and a `<base>` pointing at `url`. */\n html: string;\n url: string;\n title: string;\n /** Viewport the snapshot was taken at, in CSS pixels. */\n width: number;\n height: number;\n capturedAt: string;\n}\n\nexport interface AuthoringSessionInfo {\n id: string;\n projectId: string;\n environment: string;\n guideId: string | null;\n dashboardOrigin: string;\n expiresAt: string;\n /** `tag`: the session tags pages and features (no guide); absent or `guide` for the guide editor. */\n purpose?: \"guide\" | \"tag\";\n /** Draft guide config to preview while authoring (not published). */\n draft: { id: string; key: string; name: string; kind: GuideKind; config: GuideConfig } | null;\n}\n\nexport const PublishedGuideSchema = z.object({\n id: z.string(),\n key: z.string(),\n name: z.string(),\n kind: z.string(),\n version: z.number(),\n config: GuideConfigSchema,\n publishedAt: z.string(),\n});\n\nexport interface ApiError {\n error: { code: string; message: string; details?: unknown };\n}\n","import { z } from \"zod\";\nimport type { HowToStepKind, NormalizedRect } from \"./howto\";\nimport type { ResourceCenterCollection } from \"./sdk-api\";\nimport type { MessengerComplaint, MessengerComplaintOffer, MessengerComplaintsConfig } from \"./complaints-limits\";\nimport type { MessengerIdeaOffer, MessengerIdeasConfig } from \"./feedback-limits\";\n\n/** How quickly the team usually replies, shown on the messenger home screen. */\nexport const REPLY_TIMES = [\"minutes\", \"hour\", \"hours\", \"day\"] as const;\nexport type ReplyTime = (typeof REPLY_TIMES)[number];\n\n/** Levels of the status card on the messenger home screen. */\nexport const STATUS_LEVELS = [\"operational\", \"degraded\", \"outage\", \"maintenance\"] as const;\nexport type StatusLevel = (typeof STATUS_LEVELS)[number];\n\n/** A teammate shown on the messenger home screen (first name only). */\nexport interface MessengerTeammate {\n name: string;\n avatarUrl: string | null;\n}\n\nexport interface MessengerStatus {\n level: StatusLevel;\n message: string;\n updatedAt: string;\n}\n\n/** Which personalised cards the messenger home screen shows. */\nexport interface MessengerHomeCards {\n /** Guides, how-tos, articles and common questions for the page the user is on. */\n suggestions: boolean;\n /** A guide the user started and didn't finish, and checklist progress. */\n progress: boolean;\n /** Live announcements (also the News tab). */\n news: boolean;\n}\n\n/** Messenger settings delivered to the SDK in `SdkConfigResponse.messenger`. */\nexport interface MessengerConfig {\n enabled: boolean;\n /** Display name of the AI agent (\"Scout\"). */\n name: string;\n greeting: string;\n /** Scout answers with AI; when false every conversation goes to the team inbox. */\n aiAvailable: boolean;\n handoffEnabled: boolean;\n launcher: { position: \"bottom-right\" | \"bottom-left\" };\n /** Absent from servers before the personalised home screen; SDKs fall back to their defaults. */\n replyTime?: ReplyTime | null;\n team?: MessengerTeammate[];\n status?: MessengerStatus | null;\n home?: MessengerHomeCards;\n /** Complaint categories when the project takes complaints in the messenger (absent from older servers). */\n complaints?: MessengerComplaintsConfig | null;\n /** The Ideas tab (feature requests) when the project turned it on (absent from older servers). */\n ideas?: MessengerIdeasConfig | null;\n}\n\n/** Page-matched content for the messenger, from `POST /sdk/messenger/page`. */\nexport type MessengerPageSuggestion =\n | { type: \"article\"; articleId: string; title: string; summary: string }\n /** A how-to recorded on this page, opened as its help article. */\n | { type: \"howto\"; articleId: string; title: string; steps: number };\n\nexport interface MessengerPageContent {\n /** The page as matched: its path with ids folded (`/invoices/:id`). */\n path: string;\n label: string | null;\n suggestions: MessengerPageSuggestion[];\n /** Questions people ask on this page (FAQs and learned answers); tapping one asks Scout. */\n questions: string[];\n}\n\nexport const MessengerPageRequestSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n /** Pathname only: query strings and fragments are never sent. */\n path: z.string().min(1).max(1000),\n});\nexport type MessengerPageRequest = z.infer<typeof MessengerPageRequestSchema>;\n\nexport const MESSAGE_AUTHORS = [\"user\", \"scout\", \"agent\", \"system\"] as const;\nexport type MessageAuthor = (typeof MESSAGE_AUTHORS)[number];\nexport type ConversationStatus = \"bot\" | \"open\" | \"closed\";\n\nexport interface MessengerCitation {\n articleId: string;\n title: string;\n}\n\nexport interface MessengerSuggestedGuide {\n key: string;\n name: string;\n}\n\n/** A how-to Scout relied on; the messenger opens it in place (`GET /sdk/how-tos/:id`). */\nexport interface MessengerHowToCitation {\n howToId: string;\n title: string;\n}\n\nexport interface MessengerMessage {\n id: string;\n author: MessageAuthor;\n /** Team member name for `agent` messages. */\n authorName?: string | null;\n body: string;\n citations: MessengerCitation[];\n suggestedGuides: MessengerSuggestedGuide[];\n /** How-tos Scout cited (absent when none; SDKs before how-to support ignore it). */\n howTos?: MessengerHowToCitation[];\n /** Scout offered the complaint form (absent otherwise). */\n complaintOffer?: MessengerComplaintOffer;\n /** Scout offered to file or upvote a feature request (absent otherwise). */\n ideaOffer?: MessengerIdeaOffer;\n status: \"pending\" | \"complete\" | \"failed\";\n createdAt: string;\n}\n\nexport interface MessengerConversation {\n id: string;\n status: ConversationStatus;\n subject: string;\n lastMessageAt: string;\n lastMessagePreview: string;\n unread: number;\n rating: number | null;\n /** The complaint filed in this conversation, latest first (absent when none). */\n complaint?: MessengerComplaint;\n}\n\nexport const MAX_MESSAGE_LENGTH = 4000;\nconst messageText = z.string().trim().min(1).max(MAX_MESSAGE_LENGTH);\n\nexport const StartConversationSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n message: messageText,\n pageUrl: z.string().max(2000).optional(),\n});\nexport type StartConversationRequest = z.infer<typeof StartConversationSchema>;\n\nexport interface StartConversationResponse {\n conversation: MessengerConversation;\n /** Secret that authorises this browser to read and post in the conversation. Store it; it is not shown again. */\n token: string;\n messages: MessengerMessage[];\n}\n\nexport const ConversationLookupSchema = z.object({\n tokens: z.array(z.string().min(16).max(128)).max(50),\n});\n\nexport interface ConversationLookupResponse {\n conversations: Array<MessengerConversation & { token: string }>;\n}\n\nexport const PostMessageSchema = z.object({\n message: messageText,\n /** The page the user is on now (omitted when URL collection is off and by older SDKs), so Scout answers for that page. */\n pageUrl: z.string().max(2000).optional(),\n});\n\nexport const ConversationRatingSchema = z.object({\n rating: z.number().int().min(1).max(5),\n comment: z.string().max(1000).optional(),\n});\n\nexport interface FileComplaintResponse {\n complaint: MessengerComplaint;\n conversation: MessengerConversation;\n /** Token of the conversation started for it (absent when it was filed in an existing one). */\n token?: string;\n}\n\nexport interface ConversationMessagesResponse {\n conversation: MessengerConversation;\n messages: MessengerMessage[];\n}\n\n/**\n * Server-sent events streamed by `POST /sdk/conversations` and `POST /sdk/conversations/:id/messages`\n * while Scout replies. `conversation` (start only) carries the new conversation and its token, `message`\n * each stored message, `delta` reply text as it is generated, and `done` the final stored message.\n */\nexport type ScoutStreamEvent =\n | { event: \"conversation\"; data: StartConversationResponse }\n | { event: \"message\"; data: MessengerMessage }\n | { event: \"delta\"; data: { messageId: string; text: string } }\n | { event: \"done\"; data: { message: MessengerMessage; conversation: MessengerConversation } }\n | { event: \"error\"; data: { message: string } };\n\n/** Article list entry for the messenger Help tab (bodies are fetched on demand). */\nexport interface SdkArticleSummary {\n id: string;\n slug: string;\n title: string;\n summary: string;\n collectionId: string | null;\n externalUrl: string | null;\n /** Listed only for members of these audiences (absent = everyone). */\n audienceIds?: string[];\n /** Guide keys of the article's \"Show me\" prompts (absent = none). */\n walkthroughs?: string[];\n hasVideo?: boolean;\n updatedAt: string;\n}\n\nexport interface SdkArticlesResponse {\n collections: ResourceCenterCollection[];\n articles: SdkArticleSummary[];\n}\n\n/** A how-to the team made available in the app (`GET /sdk/how-tos`). */\nexport interface SdkHowToSummary {\n id: string;\n title: string;\n description: string;\n /** Numbered (recorded) steps. */\n stepCount: number;\n /** Key of the interactive tour made from it, when that tour is live in this environment (\"Show me\"). */\n guideKey?: string;\n /** The how-to has a video. */\n hasVideo?: boolean;\n updatedAt: string;\n}\n\nexport interface SdkHowTosResponse {\n /** Every how-to available in the app, by title (at most 200). */\n howTos: SdkHowToSummary[];\n /** Ids of the ones recorded on the page in `?url=`, best match first (at most 5). */\n forPage: string[];\n}\n\n/** One step as the messenger renders it: text only, plus a screenshot with the element's highlight. */\nexport interface SdkHowToStep {\n id: string;\n kind: HowToStepKind;\n title: string;\n body: string;\n image?: {\n url: string;\n /** Show only this part of the screenshot (zoomed in on the element). */\n crop?: NormalizedRect;\n /** The element, in the coordinates of the (cropped) image. */\n highlight?: NormalizedRect;\n };\n}\n\n/** `GET /sdk/how-tos/:id`: an available how-to with its steps. */\nexport interface SdkHowTo {\n id: string;\n title: string;\n description: string;\n updatedAt: string;\n steps: SdkHowToStep[];\n /** Key of the interactive tour made from it, when that tour is live in this environment (\"Show me\"). */\n guideKey?: string;\n /** Video made from the how-to (WebM), played above the steps. */\n video?: { url: string };\n}\n","import { z } from \"zod\";\nimport { MAX_COMPLAINT_ANSWER_LENGTH, MAX_COMPLAINT_ATTACHMENT_BYTES, MAX_COMPLAINT_LENGTH } from \"./complaints-limits\";\n\nexport * from \"./complaints-limits\";\n\nexport const FileComplaintSchema = z.object({\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n categoryId: z.string().min(1).max(64),\n description: z.string().trim().min(1).max(MAX_COMPLAINT_LENGTH),\n /** Answers to the category's extra questions, by field id. */\n answers: z.record(z.string().max(64), z.string().trim().max(MAX_COMPLAINT_ANSWER_LENGTH)).default({}),\n /** Required from visitors the app hasn't identified. */\n email: z.string().trim().toLowerCase().email().max(254).optional().nullable(),\n pageUrl: z.string().max(2000).optional(),\n /** File it in this conversation (send its token in `X-Guidely-Conversation`); otherwise a new one is started. */\n conversationId: z.string().min(1).max(64).optional().nullable(),\n /** One screenshot, base64-encoded (png, jpeg, webp or gif). */\n attachment: z\n .object({\n fileName: z.string().trim().min(1).max(200),\n data: z.string().max(Math.ceil((MAX_COMPLAINT_ATTACHMENT_BYTES * 4) / 3) + 4),\n })\n .optional()\n .nullable(),\n});\nexport type FileComplaintRequest = z.infer<typeof FileComplaintSchema>;\n","/** Complaint types and limits shared by the server and the messenger runtime (zod-free). */\n\n/** Where a complaint is in its handling; the messenger shows it as Received → In review → Resolved. */\nexport const COMPLAINT_STATUSES = [\"open\", \"in_review\", \"resolved\"] as const;\nexport type ComplaintStatus = (typeof COMPLAINT_STATUSES)[number];\n\n/** Events a complaint webhook can fire on. */\nexport const COMPLAINT_EVENTS = [\"complaint.filed\", \"complaint.status_changed\", \"complaint.replied\", \"complaint.resolved\"] as const;\nexport type ComplaintEvent = (typeof COMPLAINT_EVENTS)[number];\n\n/** Extra questions a category asks for. */\nexport const COMPLAINT_FIELD_TYPES = [\"text\", \"choice\"] as const;\nexport type ComplaintFieldType = (typeof COMPLAINT_FIELD_TYPES)[number];\n\nexport const MAX_COMPLAINT_FIELDS = 8;\nexport const MAX_COMPLAINT_CHOICES = 12;\nexport const MAX_COMPLAINT_LENGTH = 4000;\nexport const MAX_COMPLAINT_ANSWER_LENGTH = 500;\n/** Largest screenshot the messenger may attach (after it scales the image down). */\nexport const MAX_COMPLAINT_ATTACHMENT_BYTES = 2 * 1024 * 1024;\n\nexport interface ComplaintField {\n /** Stable id (`invoice_number`), used as the answer's key in webhook payloads. */\n id: string;\n label: string;\n type: ComplaintFieldType;\n /** Choices for `choice` questions. */\n options?: string[];\n required: boolean;\n}\n\n/** \"CMP-1042\" for complaint number 1042. */\nexport const complaintReference = (number: number) => `CMP-${number}`;\n\n/** A category as the messenger offers it. */\nexport interface MessengerComplaintCategory {\n id: string;\n name: string;\n description: string;\n color: string;\n fields: ComplaintField[];\n}\n\n/** Complaints block of `MessengerConfig`; absent when the project doesn't take complaints. */\nexport interface MessengerComplaintsConfig {\n categories: MessengerComplaintCategory[];\n /** Visitors the app hasn't identified may file one (with an email address). */\n anonymous: boolean;\n}\n\n/** A complaint as the person who filed it sees it (on its conversation). */\nexport interface MessengerComplaint {\n id: string;\n reference: string;\n status: ComplaintStatus;\n categoryName: string;\n createdAt: string;\n}\n\n/** Scout offered the complaint form in a reply, with this category picked. */\nexport interface MessengerComplaintOffer {\n categoryId: string;\n name: string;\n}\n","import { z } from \"zod\";\nimport {\n AGENT_METADATA_MAX_BYTES,\n AGENT_METADATA_MAX_KEYS,\n AGENT_OUTCOMES,\n AGENT_TOOL_CALLS_PER_TURN,\n AGENT_TOOL_STATUSES,\n AGENT_TURN_MAX_TEXT,\n AGENT_TURN_ROLES,\n AGENT_TURNS_PER_BATCH,\n SCOUT_AGENT_ID,\n} from \"./agents-limits\";\nimport { SENSITIVE_PROPERTY_PATTERN } from \"./events-util\";\n\nexport * from \"./agents-limits\";\n\nconst ENVIRONMENTS = [\"development\", \"staging\", \"production\"] as const;\n\n/** A tool call: name, status and latency only. Anything else (arguments, results) is dropped, never stored. */\nexport const AgentToolCallSchema = z\n .object({\n name: z.string().trim().min(1).max(100),\n status: z.enum(AGENT_TOOL_STATUSES).optional(),\n latencyMs: z.number().int().min(0).max(3_600_000).optional(),\n })\n .strip();\n\n/**\n * Flat metadata: string, number, boolean or null values (others, such as nested objects, are dropped).\n * Keys starting with `$` (reserved) and keys that look sensitive (password, token, card…) are dropped;\n * strings are cut to 500 characters, and keys past the count or size limit are left out.\n */\nexport const AgentMetadataSchema = z\n .record(z.string().max(100), z.unknown())\n .transform((m) => {\n const out: Record<string, string | number | boolean | null> = {};\n let size = 0;\n for (const [k, v] of Object.entries(m)) {\n const key = k.trim();\n if (!key || key.startsWith(\"$\") || SENSITIVE_PROPERTY_PATTERN.test(key)) continue;\n if (!(typeof v === \"string\" || typeof v === \"boolean\" || v === null || (typeof v === \"number\" && Number.isFinite(v)))) continue;\n const value = typeof v === \"string\" ? v.slice(0, 500) : v;\n size += key.length + String(value).length;\n if (size > AGENT_METADATA_MAX_BYTES || Object.keys(out).length >= AGENT_METADATA_MAX_KEYS) break;\n out[key] = value;\n }\n return out;\n });\n\nconst id = (max: number) => z.string().trim().min(1).max(max);\nconst optionalId = (max: number) => z.string().trim().max(max).optional().nullable().transform((v) => v || null);\n\nexport const AgentTurnInputSchema = z.object({\n type: z.literal(\"agent.conversation\").optional(),\n conversationId: id(128),\n agentId: id(64).refine((v) => v.toLowerCase() !== SCOUT_AGENT_ID, { message: `\"${SCOUT_AGENT_ID}\" is reserved for Guidely's built-in Scout agent` }),\n agentName: z.string().trim().max(100).optional(),\n turnId: z.string().trim().min(1).max(128).optional(),\n role: z.enum(AGENT_TURN_ROLES),\n text: z.string().max(AGENT_TURN_MAX_TEXT).default(\"\"),\n toolCalls: z.array(AgentToolCallSchema).max(AGENT_TOOL_CALLS_PER_TURN).default([]),\n latencyMs: z.number().int().min(0).max(3_600_000).optional(),\n outcome: z.enum(AGENT_OUTCOMES).optional(),\n taskSuccess: z.boolean().optional(),\n occurredAt: z.string().datetime({ offset: true }).optional(),\n userId: optionalId(256),\n anonymousId: optionalId(128),\n accountId: optionalId(256),\n sessionId: optionalId(128),\n metadata: AgentMetadataSchema.default({}),\n});\nexport type AgentTurn = z.output<typeof AgentTurnInputSchema>;\n\nconst turns = z.array(AgentTurnInputSchema).min(1).max(AGENT_TURNS_PER_BATCH);\nconst sdkInfo = z.object({ name: z.string().max(60), version: z.string().max(30) }).optional();\n\n/** Body of `POST /api/v1/sdk/agent-events` (browser SDK, public key). */\nexport const SdkAgentEventsSchema = z.object({ turns, sdk: sdkInfo });\nexport type SdkAgentEvents = z.output<typeof SdkAgentEventsSchema>;\n\n/**\n * Body of `POST /api/v1/agent-events` (server to server, secret key): `{ turns: [...], environment? }`,\n * a bare array of turns, or a single turn (with `environment` beside its fields).\n */\nexport const AgentEventsRequestSchema = z.preprocess(\n (v) => {\n if (Array.isArray(v)) return { turns: v };\n if (v && typeof v === \"object\" && !(\"turns\" in v)) {\n const { environment, ...turn } = v as Record<string, unknown>;\n return { turns: [turn], environment };\n }\n return v;\n },\n z.object({ turns, environment: z.enum(ENVIRONMENTS).default(\"production\"), sdk: sdkInfo }),\n);\nexport type AgentEventsRequest = z.output<typeof AgentEventsRequestSchema>;\n","/**\n * Agent Analytics: the `agent.conversation` turn the customer's own AI agents send (zod-free, so the\n * browser SDK can use the types and limits without bundling the schema). The schema is in agents.ts.\n */\n\nexport const AGENT_TURN_ROLES = [\"user\", \"assistant\", \"tool\", \"system\"] as const;\nexport type AgentTurnRole = (typeof AGENT_TURN_ROLES)[number];\n\n/** How a conversation ended, as the agent reports it. */\nexport const AGENT_OUTCOMES = [\"success\", \"failure\", \"escalated\", \"abandoned\"] as const;\nexport type AgentOutcome = (typeof AGENT_OUTCOMES)[number];\n\nexport const AGENT_TOOL_STATUSES = [\"ok\", \"error\"] as const;\nexport type AgentToolStatus = (typeof AGENT_TOOL_STATUSES)[number];\n\n/** Longest turn text accepted (characters). */\nexport const AGENT_TURN_MAX_TEXT = 20_000;\n/** Most turns in one request. */\nexport const AGENT_TURNS_PER_BATCH = 100;\n/** Most tool calls on one turn. */\nexport const AGENT_TOOL_CALLS_PER_TURN = 50;\n/** Metadata: at most this many keys, string values up to 500 characters, 4 KB in all. */\nexport const AGENT_METADATA_MAX_KEYS = 30;\nexport const AGENT_METADATA_MAX_BYTES = 4096;\n/** The built-in Scout agent's id; customer agents can't use it. */\nexport const SCOUT_AGENT_ID = \"scout\";\n\n/** One tool the agent called in a turn. Arguments and results are never sent or stored. */\nexport interface AgentToolCallInput {\n name: string;\n status?: AgentToolStatus;\n latencyMs?: number;\n}\n\n/** One `agent.conversation` turn. */\nexport interface AgentTurnInput {\n type?: \"agent.conversation\";\n /** Your conversation (thread) id. */\n conversationId: string;\n /** Your agent's id, e.g. \"support-bot\". The agent is created on its first turn. */\n agentId: string;\n /** Display name for a new agent (defaults to agentId). */\n agentName?: string;\n /** Idempotency key: a turn sent twice with the same id is stored once. */\n turnId?: string;\n role: AgentTurnRole;\n text?: string;\n toolCalls?: AgentToolCallInput[];\n /** How long the agent took to produce this turn (assistant turns). */\n latencyMs?: number;\n /** How the conversation ended, when this turn ends it (the latest reported outcome wins). */\n outcome?: AgentOutcome;\n /** Whether the person got what they came for, when the agent knows. */\n taskSuccess?: boolean;\n /** ISO 8601 time of the turn (default: when Guidely receives it). */\n occurredAt?: string;\n userId?: string | null;\n anonymousId?: string | null;\n accountId?: string | null;\n sessionId?: string | null;\n /** Flat key/value pairs (strings, numbers, booleans), e.g. { model: \"gpt-4.1\" }. */\n metadata?: Record<string, string | number | boolean | null>;\n}\n\n/** Response of both ingestion endpoints. */\nexport interface AgentEventsResponse {\n accepted: number;\n duplicates: number;\n /** Turns refused (an agent past the per-project limit, or a conversation past its turn limit). */\n rejected?: number;\n /** Turns dropped because this month's product analytics allowance is used up. */\n overLimit?: number;\n}\n","import { z } from \"zod\";\nimport { FEEDBACK_PRIORITIES, FEEDBACK_STATUSES, MAX_FEEDBACK_COMMENT, MAX_FEEDBACK_DESCRIPTION, MAX_FEEDBACK_NOTE, MAX_FEEDBACK_TITLE } from \"./feedback-limits\";\n\nexport * from \"./feedback-limits\";\n\n/** Who is asking, as the SDK (or the portal session) knows them. Unverified unless it came from a signed link. */\nconst visitor = {\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n};\n\nexport const FeedbackListRequestSchema = z.object({\n ...visitor,\n q: z.string().trim().max(200).optional(),\n sort: z.enum([\"top\", \"new\", \"trending\"]).default(\"top\"),\n status: z.enum(FEEDBACK_STATUSES).optional(),\n /** \"open\" = not released or declined. */\n filter: z.enum([\"open\", \"all\", \"mine\", \"following\"]).default(\"open\"),\n productArea: z.string().trim().max(60).optional(),\n page: z.number().int().min(1).max(100).default(1),\n});\nexport type FeedbackListRequest = z.infer<typeof FeedbackListRequestSchema>;\n\nexport const FeedbackVisitorSchema = z.object(visitor);\nexport type FeedbackVisitorRequest = z.infer<typeof FeedbackVisitorSchema>;\n\nexport const SubmitFeedbackSchema = z.object({\n ...visitor,\n title: z.string().trim().min(3, \"Give your idea a short title\").max(MAX_FEEDBACK_TITLE),\n description: z.string().trim().max(MAX_FEEDBACK_DESCRIPTION).default(\"\"),\n productArea: z.string().trim().max(60).optional().nullable(),\n priority: z.enum(FEEDBACK_PRIORITIES).default(\"nice_to_have\"),\n /** Filed from this Scout conversation (Scout offered it). */\n conversationId: z.string().min(1).max(64).optional().nullable(),\n pageUrl: z.string().max(2000).optional(),\n});\nexport type SubmitFeedbackRequest = z.infer<typeof SubmitFeedbackSchema>;\n\nexport const FeedbackVoteSchema = z.object({\n ...visitor,\n priority: z.enum(FEEDBACK_PRIORITIES).default(\"nice_to_have\"),\n note: z.string().trim().max(MAX_FEEDBACK_NOTE).optional(),\n conversationId: z.string().min(1).max(64).optional().nullable(),\n});\nexport type FeedbackVoteRequest = z.infer<typeof FeedbackVoteSchema>;\n\nexport const FeedbackFollowSchema = z.object({ ...visitor, follow: z.boolean() });\nexport const FeedbackCommentSchema = z.object({ ...visitor, body: z.string().trim().min(1).max(MAX_FEEDBACK_COMMENT) });\nexport const FeedbackSimilarSchema = z.object({ ...visitor, title: z.string().trim().min(3).max(MAX_FEEDBACK_TITLE) });\nexport const FeedbackUpdatesReadSchema = z.object({ ...visitor, ids: z.array(z.string().min(1).max(64)).max(100).optional() });\n","/** Feedback (feature requests) types and limits shared by the server, the portal and the messenger runtime (zod-free). */\n\n/** Where a request is: shown to end users with FEEDBACK_STATUS_LABEL. */\nexport const FEEDBACK_STATUSES = [\"new\", \"under_review\", \"planned\", \"in_progress\", \"released\", \"declined\"] as const;\nexport type FeedbackStatus = (typeof FEEDBACK_STATUSES)[number];\n\nexport const FEEDBACK_STATUS_LABEL: Record<FeedbackStatus, string> = {\n new: \"New\",\n under_review: \"Under review\",\n planned: \"Planned\",\n in_progress: \"In progress\",\n released: \"Released\",\n declined: \"Declined\",\n};\n\n/** How much a voter needs it; weights 1 / 2 / 3 in the priority score. */\nexport const FEEDBACK_PRIORITIES = [\"nice_to_have\", \"important\", \"critical\"] as const;\nexport type FeedbackPriority = (typeof FEEDBACK_PRIORITIES)[number];\n\nexport const FEEDBACK_PRIORITY_LABEL: Record<FeedbackPriority, string> = { nice_to_have: \"Nice to have\", important: \"Important\", critical: \"Critical\" };\nexport const FEEDBACK_PRIORITY_WEIGHT: Record<FeedbackPriority, number> = { nice_to_have: 1, important: 2, critical: 3 };\n\n/** Events feedback integrations (Slack, webhooks) can get. */\nexport const FEEDBACK_EVENTS = [\"request.created\", \"request.status_changed\", \"request.voted\"] as const;\nexport type FeedbackEvent = (typeof FEEDBACK_EVENTS)[number];\n\nexport const MAX_FEEDBACK_TITLE = 140;\nexport const MAX_FEEDBACK_DESCRIPTION = 4000;\nexport const MAX_FEEDBACK_COMMENT = 2000;\nexport const MAX_FEEDBACK_NOTE = 500;\n\n/** \"#42\" for request number 42. */\nexport const feedbackReference = (number: number) => `#${number}`;\n\n/** A request as end users see it (messenger Ideas tab, portal). */\nexport interface PublicFeedbackRequest {\n id: string;\n number: number;\n title: string;\n description: string;\n status: FeedbackStatus;\n /** Public note shown with the status, when the team wrote one. */\n statusNote: string;\n productArea: string | null;\n votes: number;\n comments: number;\n /** This visitor's vote, if any. */\n myVote: { priority: FeedbackPriority } | null;\n following: boolean;\n /** The visitor submitted it. */\n mine: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PublicFeedbackComment {\n id: string;\n authorName: string;\n /** \"team\" replies are shown with a badge. */\n authorType: \"user\" | \"team\";\n body: string;\n createdAt: string;\n}\n\nexport interface PublicFeedbackRequestDetail extends PublicFeedbackRequest {\n thread: PublicFeedbackComment[];\n}\n\nexport interface PublicFeedbackList {\n requests: PublicFeedbackRequest[];\n hasMore: boolean;\n}\n\n/** An update about a request the visitor follows (status changed, merged). */\nexport interface FeedbackUpdate {\n id: string;\n requestId: string | null;\n kind: \"status\" | \"merged\" | \"comment\";\n title: string;\n body: string;\n read: boolean;\n createdAt: string;\n}\n\nexport interface FeedbackUpdatesResponse {\n updates: FeedbackUpdate[];\n unread: number;\n}\n\n/** Ideas block of `MessengerConfig`; absent when the project hasn't turned on the Ideas tab. */\nexport interface MessengerIdeasConfig {\n /** Tab and heading title. */\n title: string;\n /** Visitors the app hasn't identified may vote and submit (otherwise they can only browse). */\n anonymous: boolean;\n /** Votes and new ideas need a signed identity: the messenger only browses and links to the portal. */\n readOnly: boolean;\n /** Product areas people may tag new ideas with. */\n productAreas: string[];\n /** The hosted portal is on (the messenger offers \"Open the portal\"). */\n portal: boolean;\n}\n\n/** Scout offered to file or upvote a feature request in a reply. */\nexport interface MessengerIdeaOffer {\n /** The matching request to upvote, or null to suggest a new one. */\n requestId: string | null;\n title: string;\n /** Prefilled description for a new idea (the person's words, summarised). */\n description: string;\n votes?: number;\n}\n","import { z } from \"zod\";\n\n/**\n * Product-analytics capture settings. Stored on `Project.settings` (keys `autocapture`,\n * `errorTracking`, `replay`) and delivered to the SDK in `SdkConfigResponse.settings`. The project\n * setting turns a capability on; SDK options can only turn it off for one installation.\n */\nexport interface AutocaptureSettings {\n /** `page_view` on load and on every SPA navigation. */\n pageviews: boolean;\n /** `page_leave` with visible time on page and scroll depth. */\n pageLeave: boolean;\n /** `click` on buttons, links and other interactive elements. */\n clicks: boolean;\n /** `rage_click` when the same spot is clicked 3+ times within a second. */\n rageClicks: boolean;\n /** Batched click positions on every element (`heatmap` events) for click heatmaps. */\n heatmaps: boolean;\n /** Mouse-movement heatmaps: pointer position sampled while it moves, aggregated in the browser into `heatmap` events. */\n mouseMovement: boolean;\n /**\n * Mobile SDKs: `app_install`, `app_update`, `app_open` and `app_background` events (ignored on the web).\n * Optional in the type for older stored settings; `resolveCaptureSettings` always fills it.\n */\n appLifecycle?: boolean;\n}\n\nexport interface ErrorTrackingSettings {\n /** Uncaught errors and unhandled promise rejections become `exception` events. */\n enabled: boolean;\n}\n\nexport interface ReplaySettings {\n enabled: boolean;\n /** Percentage of sessions recorded (0–100), decided once per session. */\n sampleRate: number;\n /** Record console.log/warn/error output into the recording. */\n recordConsole: boolean;\n /** Record network requests (method, URL with sensitive query values redacted, status, timing, size). */\n recordNetwork: boolean;\n /** Also record request/response headers and text/JSON bodies (redacted, ≤10KB each). Off by default. */\n recordNetworkPayloads: boolean;\n /** Mask every text node (inputs are always masked). */\n maskAllText: boolean;\n /**\n * Mask every image (mobile SDKs; the web SDK gets image block selectors instead). Not a project setting: the\n * server sets it for HIPAA-mode workspaces, which also force `maskAllText` and turn console and payloads off.\n */\n maskAllImages?: boolean;\n /** Elements replaced by a placeholder box in recordings (in addition to `[data-guidely-block]`). */\n blockSelectors: string[];\n /** Days recordings are kept before the worker deletes them. */\n retentionDays: number;\n}\n\nexport interface CaptureSettings {\n autocapture: AutocaptureSettings;\n errorTracking: ErrorTrackingSettings;\n replay: ReplaySettings;\n}\n\nexport const AutocaptureSettingsSchema = z.object({ pageviews: z.boolean(), pageLeave: z.boolean(), clicks: z.boolean(), rageClicks: z.boolean(), heatmaps: z.boolean(), mouseMovement: z.boolean(), appLifecycle: z.boolean() }).partial();\nexport const ErrorTrackingSettingsSchema = z.object({ enabled: z.boolean() }).partial();\nexport const ReplaySettingsSchema = z\n .object({\n enabled: z.boolean(),\n sampleRate: z.number().int().min(0).max(100),\n recordConsole: z.boolean(),\n recordNetwork: z.boolean(),\n recordNetworkPayloads: z.boolean(),\n maskAllText: z.boolean(),\n blockSelectors: z.array(z.string().min(1).max(200)).max(50),\n retentionDays: z.number().int().min(1).max(365),\n })\n .partial();\n\nexport const DEFAULT_CAPTURE_SETTINGS: CaptureSettings = {\n autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true, appLifecycle: true },\n errorTracking: { enabled: true },\n replay: { enabled: false, sampleRate: 100, recordConsole: true, recordNetwork: true, recordNetworkPayloads: false, maskAllText: false, blockSelectors: [], retentionDays: 30 },\n};\n\n/** Fills defaults for whatever a project's stored settings leave out. */\nexport function resolveCaptureSettings(settings: unknown): CaptureSettings {\n const s = (settings && typeof settings === \"object\" ? settings : {}) as Record<string, unknown>;\n const obj = (v: unknown) => (v && typeof v === \"object\" && !Array.isArray(v) ? (v as Record<string, unknown>) : {});\n const d = DEFAULT_CAPTURE_SETTINGS;\n const a = AutocaptureSettingsSchema.safeParse(obj(s.autocapture));\n const e = ErrorTrackingSettingsSchema.safeParse(obj(s.errorTracking));\n const r = ReplaySettingsSchema.safeParse(obj(s.replay));\n return {\n autocapture: { ...d.autocapture, ...(a.success ? a.data : {}) },\n errorTracking: { ...d.errorTracking, ...(e.success ? e.data : {}) },\n replay: { ...d.replay, ...(r.success ? r.data : {}) },\n };\n}\n\n/**\n * One position in a `heatmap` event (`properties.points`). `x`/`y` are page coordinates in CSS\n * pixels; `s` is a stable selector for the element and `rx`/`ry` the position inside it (0–1), which\n * lets the dashboard place the point on the element even when layouts differ.\n *\n * Mouse movement (`k: \"m\"`) is sampled at most every 200ms while the pointer moves and binned in the\n * browser (per element at 0.1 of `rx`/`ry`, else on a 16px page grid); `w` is the number of samples\n * in the bin, so a minute of movement costs a few dozen points rather than thousands.\n */\nexport interface HeatmapPoint {\n /** `c` click, `r` part of a rage-click burst, `m` mouse movement. */\n k: \"c\" | \"r\" | \"m\";\n x: number;\n y: number;\n s?: string;\n rx?: number;\n ry?: number;\n /** Weight: samples aggregated into this point (movement only; clicks are 1). */\n w?: number;\n}\n\n/** Properties of a `heatmap` event: a batch of clicks on one page (flushed at ~40 points and on page leave). */\nexport interface HeatmapProperties {\n path?: string;\n viewportWidth: number;\n viewportHeight: number;\n /** Document scroll height when the batch was sent. */\n pageHeight: number;\n points: HeatmapPoint[];\n}\n\n/** Viewport buckets heatmaps are split by (CSS px of `viewportWidth`). */\nexport const HEATMAP_VIEWPORTS = { mobile: [0, 767], tablet: [768, 1279], desktop: [1280, 100_000] } as const;\nexport type HeatmapViewport = keyof typeof HEATMAP_VIEWPORTS;\n\n/**\n * One upload of rrweb events for a recording, `POST /api/v1/sdk/replay`. The SDK sends it as JSON,\n * or gzip-compressed JSON with `?enc=gzip`. A recording is keyed by the SDK session id; every page\n * load starts a new `windowId` whose uploads are numbered by `seq`.\n */\nexport const ReplayChunkSchema = z.object({\n sessionId: z.string().min(1).max(128),\n windowId: z.string().min(1).max(64),\n seq: z.number().int().min(0).max(1_000_000),\n anonymousId: z.string().min(1).max(128),\n userId: z.string().max(256).optional().nullable(),\n /** rrweb `eventWithTime` objects, in order. */\n events: z.array(z.object({ type: z.number().int(), timestamp: z.number() }).passthrough()).min(1).max(50_000),\n url: z.string().max(2000).optional(),\n device: z.object({ type: z.string().max(20), browser: z.string().max(40).optional(), os: z.string().max(40).optional() }).optional(),\n viewport: z.object({ width: z.number().int().min(0).max(100_000), height: z.number().int().min(0).max(100_000) }).optional(),\n sdk: z.object({ name: z.string().max(60), version: z.string().max(30) }).optional(),\n});\nexport type ReplayChunk = z.infer<typeof ReplayChunkSchema>;\n\n/** Max upload sizes for one replay chunk (bytes on the wire, and after decompression). */\nexport const REPLAY_MAX_COMPRESSED_BYTES = 2 * 1024 * 1024;\nexport const REPLAY_MAX_RAW_BYTES = 16 * 1024 * 1024;\n","/* Network requests recorded into session replays (zod-free: imported by the SDK recorder). */\n\n/** rrweb plugin name for network events in recordings (event type 6, `data.plugin`). */\nexport const NETWORK_PLUGIN = \"guidely/network@1\";\n\n/** Request kinds, from `fetch`/`XMLHttpRequest` patching or `PerformanceResourceTiming.initiatorType`. */\nexport type NetworkRequestType = \"fetch\" | \"xhr\" | \"websocket\" | \"document\" | \"script\" | \"stylesheet\" | \"image\" | \"font\" | \"media\" | \"beacon\" | \"other\";\n\n/**\n * One network request in a recording: the payload of an rrweb plugin event\n * `{ type: 6, data: { plugin: NETWORK_PLUGIN, payload: NetworkPluginPayload } }`, batched.\n * Times are epoch milliseconds (same clock as rrweb event timestamps).\n *\n * A WebSocket is a request with `type: \"websocket\"` and `method: \"GET\"`, emitted when it opens\n * (`startTime`) and again, with the same `id`, when it closes (`endTime`, `closeCode`, `closeReason`,\n * totals in `messages`). Its frames are `WebSocketMessage`s referencing that `id`.\n */\nexport interface NetworkRequest {\n /** Stable id within the recording. */\n id: string;\n type: NetworkRequestType;\n method: string;\n /** Absolute URL; values of sensitive-looking query parameters replaced with `[redacted]`. */\n url: string;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n /** HTTP status; 0 for network errors / blocked / aborted. Absent when the browser doesn't expose it. */\n status?: number;\n /** Set for failed requests: network error, abort or timeout message. */\n error?: string;\n /** Encoded bytes transferred / decoded response size, when known. */\n transferSize?: number;\n responseSize?: number;\n /** Only when `recordNetworkPayloads` is on; sensitive headers are `[redacted]`. */\n requestHeaders?: Record<string, string>;\n responseHeaders?: Record<string, string>;\n /** Text/JSON bodies, ≤10KB, sensitive JSON fields masked; `[binary]` / `[truncated]` markers otherwise. */\n requestBody?: string;\n responseBody?: string;\n /** WebSocket only: negotiated subprotocol, close details, and frame totals (all frames, including ones not recorded). */\n protocol?: string;\n closeCode?: number;\n closeReason?: string;\n messages?: { sent: number; received: number; sentBytes: number; receivedBytes: number; recorded: number };\n}\n\n/** One WebSocket frame. At most `WS_MAX_MESSAGES_PER_SOCKET` are recorded per connection per page load. */\nexport interface WebSocketMessage {\n /** The `NetworkRequest.id` of the connection. */\n socketId: string;\n dir: \"send\" | \"recv\";\n time: number;\n /** Bytes (UTF-8 length for text frames). */\n size: number;\n binary?: boolean;\n /** Only with `recordNetworkPayloads`: text ≤ 2KB (JSON with sensitive keys masked), else `[truncated]`; binary frames are `[binary <n> B]`. */\n data?: string;\n}\n\nexport interface NetworkPluginPayload {\n requests?: NetworkRequest[];\n messages?: WebSocketMessage[];\n /** Requests/frames dropped since the previous payload because a cap was reached. */\n dropped?: { requests?: number; messages?: number };\n}\n\nexport const WS_MAX_MESSAGES_PER_SOCKET = 200;\nexport const WS_MAX_MESSAGE_BYTES = 2048;\n\n/** Header names always replaced with `[redacted]` when payload capture is on. */\nexport const SENSITIVE_HEADER_PATTERN = /^(authorization|proxy-authorization|cookie|set-cookie|x-api-key|x-auth-token|x-csrf-token|x-xsrf-token|x-guidely-key|x-guidely-conversation)$/i;\n\n/** Query parameter and JSON field names whose values are redacted. */\nexport const SENSITIVE_PARAM_PATTERN = /(token|key|secret|password|passwd|pwd|auth|session|code|sig|signature|credential|ssn|card|cvv|iban)/i;\n","import { GuideConfigSchema, type GuideConfigInput, type GuideKind } from \"./guide\";\n\nexport interface GuideTemplate {\n id: string;\n name: string;\n description: string;\n kind: GuideKind;\n category: \"onboarding\" | \"feature\" | \"setup\" | \"forms\" | \"announcement\" | \"help\" | \"feedback\";\n config: GuideConfigInput;\n}\n\nconst nav = (opts: { last?: boolean; first?: boolean } = {}) =>\n [\n ...(opts.first ? [] : [{ id: \"back\", label: \"Back\", action: \"back\" as const, variant: \"ghost\" as const }]),\n opts.last\n ? { id: \"done\", label: \"Finish\", action: \"complete\" as const, variant: \"primary\" as const }\n : { id: \"next\", label: \"Next\", action: \"next\" as const, variant: \"primary\" as const },\n ];\n\nexport const GUIDE_TEMPLATES: GuideTemplate[] = [\n {\n id: \"new-user-onboarding\",\n name: \"New-user onboarding tour\",\n description: \"A welcome modal followed by three anchored steps that introduce the main navigation.\",\n kind: \"flow\",\n category: \"onboarding\",\n config: {\n steps: [\n { id: \"welcome\", type: \"modal\", title: \"Welcome aboard 👋\", body: \"<p>We'll show you around in under a minute. You can skip at any time.</p>\", showOverlay: true, buttons: [{ id: \"skip\", label: \"Skip tour\", action: \"dismiss\", variant: \"ghost\" }, { id: \"start\", label: \"Show me around\", action: \"next\" }] },\n { id: \"nav\", type: \"tooltip\", title: \"Your navigation\", body: \"<p>Everything lives in the sidebar. Switch between dashboards, contacts and settings here.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='sidebar']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", buttons: nav() },\n { id: \"create\", type: \"spotlight\", title: \"Create your first record\", body: \"<p>Use the primary button to add something new. We'll highlight it for you.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='primary-action']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", showOverlay: true, buttons: nav() },\n { id: \"help\", type: \"tooltip\", title: \"Need help later?\", body: \"<p>Open the help menu any time to replay this tour or browse the resource center.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='help']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", buttons: nav({ last: true }) },\n ],\n trigger: { type: \"page_load\" },\n frequency: { mode: \"once\", priority: 10 },\n targeting: { id: \"root\", op: \"and\", rules: [{ id: \"r1\", field: \"visitor.firstVisit\", op: \"is_true\" }] },\n },\n },\n {\n id: \"feature-discovery\",\n name: \"First-time feature discovery\",\n description: \"A hotspot that draws attention to a new capability and expands into a tooltip.\",\n kind: \"tooltip\",\n category: \"feature\",\n config: {\n steps: [{ id: \"hotspot\", type: \"hotspot\", title: \"New: smart filters\", body: \"<p>Filters now understand natural language. Try <em>“deals closing this month”</em>.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='filters']\" }], waitMs: 8000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", buttons: [{ id: \"got-it\", label: \"Got it\", action: \"complete\" }], hotspot: { size: 14, pulse: true, openOn: \"click\" }, showProgress: false }],\n trigger: { type: \"element_visible\", value: \"[data-tour='filters']\" },\n frequency: { mode: \"once\", maxImpressions: 3, priority: 50 },\n },\n },\n {\n id: \"setup-wizard\",\n name: \"Setup wizard\",\n description: \"Multi-step modal wizard that walks a new admin through initial configuration with branching.\",\n kind: \"flow\",\n category: \"setup\",\n config: {\n steps: [\n { id: \"intro\", type: \"modal\", title: \"Let's set up your workspace\", body: \"<p>Three quick steps: invite your team, connect a data source, and choose a plan.</p>\", showOverlay: true, buttons: [{ id: \"later\", label: \"Later\", action: \"dismiss\", variant: \"ghost\" }, { id: \"go\", label: \"Start setup\", action: \"next\" }] },\n { id: \"team\", type: \"popover\", title: \"Invite teammates\", body: \"<p>Guidely works best with your whole team. Add a few emails here.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='invite']\" }], waitMs: 5000, fallback: \"show_as_modal\", scrollIntoView: true }, buttons: nav() },\n { id: \"data\", type: \"popover\", title: \"Connect a data source\", body: \"<p>Import contacts from a CSV or connect your CRM.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='import']\" }], waitMs: 5000, fallback: \"show_as_modal\", scrollIntoView: true }, buttons: nav() },\n { id: \"done\", type: \"modal\", title: \"You're ready 🎉\", body: \"<p>That's it. Explore the dashboard, and open the help menu if you get stuck.</p>\", showOverlay: true, buttons: nav({ last: true }) },\n ],\n trigger: { type: \"page_load\", urlPattern: \"/dashboard\" },\n frequency: { mode: \"once\", priority: 20 },\n targeting: { id: \"root\", op: \"and\", rules: [{ id: \"r1\", field: \"user.role\", op: \"equals\", value: \"admin\" }] },\n },\n },\n {\n id: \"form-completion\",\n name: \"Form completion helper\",\n description: \"Tooltips that advance as the user fills out each field of a form.\",\n kind: \"flow\",\n category: \"forms\",\n config: {\n steps: [\n { id: \"name\", type: \"tooltip\", title: \"Name the contact\", body: \"<p>Use their full name so search works well.</p>\", target: { selectors: [{ kind: \"css\", value: \"input[name='name']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", advanceOn: \"element_click\", advanceValue: \"input[name='email']\", buttons: [] },\n { id: \"email\", type: \"tooltip\", title: \"Add an email\", body: \"<p>We'll use it for sequences and reminders.</p>\", target: { selectors: [{ kind: \"css\", value: \"input[name='email']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", buttons: nav() },\n { id: \"save\", type: \"spotlight\", title: \"Save\", body: \"<p>Hit save, and your contact appears in the list.</p>\", target: { selectors: [{ kind: \"css\", value: \"button[type='submit']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"top\", showOverlay: true, buttons: nav({ last: true }) },\n ],\n trigger: { type: \"url_match\", value: \"/contacts/new\" },\n frequency: { mode: \"once\", priority: 40 },\n },\n },\n {\n id: \"workflow-walkthrough\",\n name: \"Complex workflow walkthrough\",\n description: \"A multi-page flow that follows the user across routes with URL-aware steps.\",\n kind: \"flow\",\n category: \"onboarding\",\n config: {\n steps: [\n { id: \"start\", type: \"modal\", title: \"Close your first deal\", body: \"<p>We'll go from pipeline to closed-won in four steps.</p>\", showOverlay: true, buttons: [{ id: \"skip\", label: \"Not now\", action: \"dismiss\", variant: \"ghost\" }, { id: \"next\", label: \"Let's go\", action: \"next\" }] },\n { id: \"pipeline\", type: \"tooltip\", title: \"Open the pipeline\", body: \"<p>Click here to see your deals by stage.</p>\", url: \"/dashboard\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='nav-deals']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"right\", advanceOn: \"element_click\", advanceValue: \"[data-tour='nav-deals']\", buttons: [] },\n { id: \"drag\", type: \"spotlight\", title: \"Move a deal\", body: \"<p>Drag a card to the next stage, or use the stage menu.</p>\", url: \"/deals\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='deal-card']\" }], waitMs: 8000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", showOverlay: true, buttons: nav() },\n { id: \"won\", type: \"tooltip\", title: \"Mark as won\", body: \"<p>When it closes, mark it won to update your forecast.</p>\", url: \"/deals\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='mark-won']\" }], waitMs: 8000, fallback: \"skip\", scrollIntoView: true }, placement: \"left\", buttons: nav({ last: true }) },\n ],\n trigger: { type: \"manual\" },\n frequency: { mode: \"every_time\", priority: 30 },\n },\n },\n {\n id: \"feature-announcement\",\n name: \"New feature announcement\",\n description: \"A centered modal with an image announcing a new capability.\",\n kind: \"announcement\",\n category: \"announcement\",\n config: {\n steps: [{ id: \"announce\", type: \"modal\", title: \"Introducing Reports 2.0\", body: \"<p>Build custom reports with drag-and-drop metrics, scheduled emails and shareable links.</p><ul><li>12 new chart types</li><li>Export to CSV and PDF</li></ul>\", imageUrl: \"https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&q=60\", showOverlay: true, buttons: [{ id: \"later\", label: \"Maybe later\", action: \"dismiss\", variant: \"ghost\" }, { id: \"try\", label: \"Try it now\", action: \"url\", value: \"/reports\" }], showProgress: false }],\n trigger: { type: \"page_load\", delayMs: 1500 },\n frequency: { mode: \"once\", priority: 60 },\n },\n },\n {\n id: \"contextual-tooltip\",\n name: \"Contextual tooltip\",\n description: \"A single tooltip that appears when a specific element becomes visible.\",\n kind: \"tooltip\",\n category: \"help\",\n config: {\n steps: [{ id: \"tip\", type: \"tooltip\", title: \"Pro tip\", body: \"<p>Press <strong>⌘K</strong> to jump anywhere.</p>\", target: { selectors: [{ kind: \"data-attr\", value: \"[data-tour='search']\" }], waitMs: 5000, fallback: \"skip\", scrollIntoView: true }, placement: \"bottom\", buttons: [{ id: \"ok\", label: \"Got it\", action: \"complete\" }], showProgress: false }],\n trigger: { type: \"element_visible\", value: \"[data-tour='search']\", delayMs: 500 },\n frequency: { mode: \"once\", priority: 80 },\n },\n },\n {\n id: \"product-update-banner\",\n name: \"Product update notification\",\n description: \"A dismissible top banner linking to release notes.\",\n kind: \"banner\",\n category: \"announcement\",\n config: {\n steps: [{ id: \"banner\", type: \"banner\", title: \"\", body: \"<p><strong>Scheduled maintenance</strong> on Saturday 02:00–03:00 UTC. <a href='/status'>Read more</a>.</p>\", position: \"top\", placement: \"top\", buttons: [{ id: \"dismiss\", label: \"Dismiss\", action: \"dismiss\", variant: \"ghost\" }], showProgress: false }],\n trigger: { type: \"page_load\" },\n frequency: { mode: \"once_per_session\", priority: 90 },\n },\n },\n {\n id: \"onboarding-checklist\",\n name: \"User onboarding checklist\",\n description: \"A persistent checklist with four tasks that complete automatically from events.\",\n kind: \"checklist\",\n category: \"onboarding\",\n config: {\n steps: [],\n checklist: {\n tasks: [\n { id: \"profile\", title: \"Complete your profile\", description: \"Add a photo and your role.\", completion: \"event\", completionValue: \"profile_completed\", action: \"url\", actionValue: \"/settings/profile\" },\n { id: \"contact\", title: \"Add your first contact\", description: \"Import or create a contact.\", completion: \"event\", completionValue: \"contact_created\", action: \"url\", actionValue: \"/contacts/new\" },\n { id: \"deal\", title: \"Create a deal\", description: \"Track your first opportunity.\", completion: \"event\", completionValue: \"deal_created\", action: \"url\", actionValue: \"/deals\" },\n { id: \"tour\", title: \"Take the product tour\", description: \"A 60-second walkthrough.\", completion: \"guide_completed\", completionValue: \"new-user-onboarding\", action: \"start_guide\", actionValue: \"new-user-onboarding\", required: false },\n ],\n ordered: false,\n launcherLabel: \"Getting started\",\n position: \"bottom-right\",\n completionTitle: \"You're all set! 🎉\",\n completionBody: \"You've completed onboarding. Explore the rest of the app at your own pace.\",\n autoOpen: true,\n dismissible: true,\n },\n trigger: { type: \"page_load\" },\n frequency: { mode: \"every_time\", priority: 200 },\n },\n },\n {\n id: \"nps-survey\",\n name: \"NPS survey\",\n description: \"Net Promoter Score with a conditional follow-up question.\",\n kind: \"survey\",\n category: \"feedback\",\n config: {\n steps: [],\n survey: {\n questions: [\n { id: \"nps\", type: \"nps\", title: \"How likely are you to recommend us to a colleague?\", lowLabel: \"Not likely\", highLabel: \"Very likely\" },\n { id: \"why-low\", type: \"text\", title: \"What could we do better?\", required: false, placeholder: \"Tell us more…\", showWhen: { questionId: \"nps\", op: \"lte\", value: 6 } },\n { id: \"why-high\", type: \"text\", title: \"What do you like most?\", required: false, placeholder: \"Tell us more…\", showWhen: { questionId: \"nps\", op: \"gte\", value: 9 } },\n ],\n position: \"bottom-right\",\n },\n trigger: { type: \"page_load\", delayMs: 5000 },\n frequency: { mode: \"interval\", intervalHours: 2160, priority: 150 },\n targeting: { id: \"root\", op: \"and\", rules: [{ id: \"r1\", field: \"visitor.returning\", op: \"is_true\" }] },\n },\n },\n];\n\nexport function templateConfig(id: string) {\n const t = GUIDE_TEMPLATES.find((x) => x.id === id);\n if (!t) return null;\n return { template: t, config: GuideConfigSchema.parse(t.config) };\n}\n","/**\n * Media in article bodies: uploaded images, videos and PDFs, and video embeds from a fixed set of hosts.\n * Sanitizers (server, browser runtime) only keep an `<iframe>` whose `src` is the canonical embed URL\n * that `toEmbedUrl` produces, so authors can never point a frame anywhere else.\n *\n * An uploaded PDF reads inline, as its pages: the dashboard renders each page to an image when the\n * PDF is uploaded, and the body holds plain HTML every renderer already understands:\n *\n * <div class=\"gd-pdf\">\n * <a class=\"gd-file\" href=\"…/{id}.pdf\" target=\"_blank\">{file name}</a>\n * <div class=\"gd-pdf-pages\"><img src=\"…/{page}.webp\" alt=\"{file name}, page 1 of 12\"> …</div>\n * </div>\n *\n * Renderers that know the classes draw a swipeable page viewer with the PDF one tap away; older ones\n * show a link and the pages as images. A PDF whose pages couldn't be rendered (password-protected,\n * damaged) is just the `gd-file` link, drawn as a file card.\n */\n\nexport type EmbedProvider = \"youtube\" | \"vimeo\" | \"loom\" | \"wistia\";\n\nexport interface VideoEmbed {\n provider: EmbedProvider;\n /** Canonical player URL, safe to use as an iframe `src`. */\n src: string;\n /** Page a viewer can open instead (native SDKs show a link rather than a player). */\n watchUrl: string;\n /** Accessible iframe title. */\n title: string;\n}\n\nexport const MEDIA_IMAGE_TYPES = [\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\"] as const;\nexport const MEDIA_VIDEO_TYPES = [\"video/mp4\", \"video/webm\"] as const;\nexport const MEDIA_FILE_TYPES = [\"application/pdf\"] as const;\nexport type MediaContentType = (typeof MEDIA_IMAGE_TYPES)[number] | (typeof MEDIA_VIDEO_TYPES)[number] | (typeof MEDIA_FILE_TYPES)[number];\nexport type MediaKind = \"image\" | \"video\" | \"file\";\nexport const MEDIA_IMAGE_MAX_BYTES = 10 * 1024 * 1024;\nexport const MEDIA_VIDEO_MAX_BYTES = 200 * 1024 * 1024;\nexport const MEDIA_FILE_MAX_BYTES = 50 * 1024 * 1024;\n/** The largest upload of any type. */\nexport const MEDIA_MAX_BYTES = Math.max(MEDIA_IMAGE_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_FILE_MAX_BYTES);\n\nexport function isMediaContentType(type: string): type is MediaContentType {\n return mediaKind(type) !== null;\n}\nexport function isVideoContentType(type: string): boolean {\n return (MEDIA_VIDEO_TYPES as readonly string[]).includes(type);\n}\nexport function mediaKind(type: string): MediaKind | null {\n if ((MEDIA_IMAGE_TYPES as readonly string[]).includes(type)) return \"image\";\n if ((MEDIA_VIDEO_TYPES as readonly string[]).includes(type)) return \"video\";\n if ((MEDIA_FILE_TYPES as readonly string[]).includes(type)) return \"file\";\n return null;\n}\nexport function mediaMaxBytes(type: string): number {\n const kind = mediaKind(type);\n return kind === \"video\" ? MEDIA_VIDEO_MAX_BYTES : kind === \"file\" ? MEDIA_FILE_MAX_BYTES : MEDIA_IMAGE_MAX_BYTES;\n}\n\n/** Class marking a link as an attached file (an uploaded PDF), drawn as a file card. */\nexport const FILE_LINK_CLASS = \"gd-file\";\n/** Class of the block holding a PDF's link and its rendered pages. */\nexport const PDF_BLOCK_CLASS = \"gd-pdf\";\n/** Class of the element wrapping a PDF's page images. */\nexport const PDF_PAGES_CLASS = \"gd-pdf-pages\";\n/** Pages rendered inline per PDF; readers open the PDF itself for the rest. */\nexport const PDF_MAX_PAGES = 40;\n\n/** True for an `<a>` with the file class and an absolute http(s) `href`: render it as a file card. */\nexport function isFileLink(className: string | null | undefined, href: string | null | undefined): boolean {\n return !!className && className.split(/\\s+/).includes(FILE_LINK_CLASS) && isSafeMediaUrl(href);\n}\n\nconst YOUTUBE_ID = /^[A-Za-z0-9_-]{11}$/;\nconst VIMEO_ID = /^\\d{1,12}$/;\nconst VIMEO_HASH = /^[0-9a-f]{6,20}$/i;\nconst LOOM_ID = /^[0-9a-f]{32}$/i;\nconst WISTIA_ID = /^[a-z0-9]{10}$/i;\n\nfunction parseUrl(input: string): URL | null {\n const s = input.trim();\n if (!s) return null;\n try {\n const u = new URL(/^[a-z][a-z0-9+.-]*:/i.test(s) ? s : `https://${s}`);\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n if (u.username || u.password || (u.port && u.port !== \"443\" && u.port !== \"80\")) return null;\n return u;\n } catch {\n return null;\n }\n}\n\n/** \"1h2m3s\", \"90s\", \"90\" → seconds. */\nfunction parseStart(v: string | null): number {\n if (!v) return 0;\n if (/^\\d+$/.test(v)) return Math.min(Number(v), 86400);\n const m = /^(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?$/.exec(v);\n if (!m || !m[0]) return 0;\n return Math.min(Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0), 86400);\n}\n\nfunction youtube(id: string, start: number): VideoEmbed | null {\n if (!YOUTUBE_ID.test(id)) return null;\n return {\n provider: \"youtube\",\n src: `https://www.youtube-nocookie.com/embed/${id}${start ? `?start=${start}` : \"\"}`,\n watchUrl: `https://www.youtube.com/watch?v=${id}${start ? `&t=${start}s` : \"\"}`,\n title: \"YouTube video\",\n };\n}\n\nfunction vimeo(id: string, hash: string | null): VideoEmbed | null {\n if (!VIMEO_ID.test(id) || (hash !== null && !VIMEO_HASH.test(hash))) return null;\n const h = hash ? hash.toLowerCase() : null;\n return { provider: \"vimeo\", src: `https://player.vimeo.com/video/${id}${h ? `?h=${h}` : \"\"}`, watchUrl: `https://vimeo.com/${id}${h ? `/${h}` : \"\"}`, title: \"Vimeo video\" };\n}\n\n/**\n * Turns a pasted video page or player URL from YouTube, Vimeo, Loom or Wistia into its canonical\n * embed. Returns null for anything else, including lookalike hosts.\n */\nexport function toEmbedUrl(input: string): VideoEmbed | null {\n const u = parseUrl(input);\n if (!u) return null;\n const host = u.hostname.toLowerCase().replace(/^www\\./, \"\");\n const parts = u.pathname.split(\"/\").filter(Boolean);\n switch (host) {\n case \"youtube.com\":\n case \"m.youtube.com\":\n case \"youtube-nocookie.com\": {\n const start = parseStart(u.searchParams.get(\"start\") ?? u.searchParams.get(\"t\"));\n if (parts[0] === \"watch\" && parts.length === 1) return youtube(u.searchParams.get(\"v\") ?? \"\", start);\n if ((parts[0] === \"embed\" || parts[0] === \"shorts\" || parts[0] === \"live\") && parts.length === 2) return youtube(parts[1]!, start);\n return null;\n }\n case \"youtu.be\":\n return parts.length === 1 ? youtube(parts[0]!, parseStart(u.searchParams.get(\"t\") ?? u.searchParams.get(\"start\"))) : null;\n case \"vimeo.com\":\n if (parts.length === 1) return vimeo(parts[0]!, null);\n if (parts.length === 2 && VIMEO_ID.test(parts[0]!)) return vimeo(parts[0]!, parts[1]!);\n return null;\n case \"player.vimeo.com\":\n return parts[0] === \"video\" && parts.length === 2 ? vimeo(parts[1]!, u.searchParams.get(\"h\")) : null;\n case \"loom.com\":\n if ((parts[0] === \"share\" || parts[0] === \"embed\") && parts.length === 2 && LOOM_ID.test(parts[1]!)) {\n const id = parts[1]!.toLowerCase();\n return { provider: \"loom\", src: `https://www.loom.com/embed/${id}`, watchUrl: `https://www.loom.com/share/${id}`, title: \"Loom video\" };\n }\n return null;\n default: {\n let id: string | undefined;\n if (host === \"fast.wistia.net\" || host === \"fast.wistia.com\") id = parts[0] === \"embed\" && parts[1] === \"iframe\" && parts.length === 3 ? parts[2] : undefined;\n else if (host === \"wi.st\" || host === \"wistia.com\" || /^[a-z0-9-]+\\.wistia\\.com$/.test(host)) id = parts[0] === \"medias\" && parts.length === 2 ? parts[1] : undefined;\n if (!id || !WISTIA_ID.test(id)) return null;\n return { provider: \"wistia\", src: `https://fast.wistia.net/embed/iframe/${id}`, watchUrl: `https://fast.wistia.net/embed/iframe/${id}`, title: \"Wistia video\" };\n }\n }\n}\n\n/** True only for a canonical embed URL (exactly what `toEmbedUrl` returns), so an iframe can't be pointed elsewhere. */\nexport function isAllowedEmbedSrc(src: string | null | undefined): boolean {\n if (!src) return false;\n return toEmbedUrl(src)?.src === src;\n}\n\n/** Fixed iframe attributes for an embed; sanitizers overwrite whatever the author's HTML carried. */\nexport const EMBED_IFRAME_ATTRS: Readonly<Record<string, string>> = {\n allow: \"fullscreen; picture-in-picture; encrypted-media\",\n allowfullscreen: \"\",\n loading: \"lazy\",\n referrerpolicy: \"strict-origin-when-cross-origin\",\n sandbox: \"allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox\",\n};\n\n/** Fixed `<video>` attributes: player controls, no autoplay or loop. */\nexport const VIDEO_ATTRS: Readonly<Record<string, string>> = { controls: \"\", preload: \"metadata\", playsinline: \"\" };\n\n/** `<video src>` / `poster` must be plain http(s): no data:, blob: or relative URLs (bodies render on customer sites). */\nexport function isSafeMediaUrl(url: string | null | undefined): boolean {\n if (!url) return false;\n try {\n const u = new URL(url);\n return (u.protocol === \"https:\" || u.protocol === \"http:\") && !u.username && !u.password;\n } catch {\n return false;\n }\n}\n","/**\n * Resource center structure shared by every SDK: nested collections and audience targeting.\n *\n * Audience targeting decides what the help widget lists; it is not access control. The published\n * config (and every article body) is the same for all visitors of an environment, and end-user\n * identities are self-asserted, so never rely on it to keep an article private.\n */\n\n/** Collections nest at most this deep (a collection, its sections, and their sub-sections). */\nexport const MAX_COLLECTION_DEPTH = 3;\n\nexport interface RcCollectionLike {\n id: string;\n name: string;\n order: number;\n /** Parent collection; null/absent for a top-level collection. */\n parentId?: string | null;\n /** Shown only to members of any of these audiences; empty/absent means everyone. */\n audienceIds?: string[];\n}\n\nexport interface RcArticleLike {\n id: string;\n collectionId?: string | null;\n audienceIds?: string[];\n}\n\nexport interface RcSection<C extends RcCollectionLike, A extends RcArticleLike> {\n /** null for articles outside any (known) collection. */\n collection: C | null;\n /** Collection names from the top level down, e.g. [\"Billing\", \"Invoices\"]. */\n path: string[];\n /** 0 for a top-level collection. */\n depth: number;\n articles: A[];\n}\n\ntype Membership = ReadonlySet<string> | readonly string[] | undefined | null;\n\n/** True when an item targeted at `required` audiences is shown to someone in `member`. */\nexport function matchesAudiences(required: readonly string[] | undefined | null, member: Membership): boolean {\n if (!required || required.length === 0) return true;\n if (!member) return false;\n const has = member instanceof Set ? (id: string) => member.has(id) : (id: string) => (member as readonly string[]).includes(id);\n return required.some(has);\n}\n\n/**\n * Article sections in display order: each collection (depth first, siblings by `order`) with the\n * visible articles filed directly in it, then the uncategorized articles. A collection the viewer\n * isn't targeted by hides its whole subtree, and sections without visible articles are left out\n * (their sub-collections still appear). Unknown parents count as top level, so an old config or a\n * dangling reference never hides content.\n */\nexport function resourceCenterSections<C extends RcCollectionLike, A extends RcArticleLike>(collections: readonly C[], articles: readonly A[], member?: Membership): Array<RcSection<C, A>> {\n const byId = new Map(collections.map((c) => [c.id, c]));\n const children = new Map<string | null, C[]>();\n for (const c of collections) {\n const parent = c.parentId && c.parentId !== c.id && byId.has(c.parentId) ? c.parentId : null;\n const list = children.get(parent) ?? [];\n list.push(c);\n children.set(parent, list);\n }\n for (const list of children.values()) list.sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));\n const direct = new Map<string, A[]>();\n const uncategorized: A[] = [];\n for (const a of articles) {\n if (!matchesAudiences(a.audienceIds, member)) continue;\n if (a.collectionId && byId.has(a.collectionId)) {\n const list = direct.get(a.collectionId) ?? [];\n list.push(a);\n direct.set(a.collectionId, list);\n } else uncategorized.push(a);\n }\n\n const sections: Array<RcSection<C, A>> = [];\n const seen = new Set<string>();\n const visit = (c: C, path: string[]) => {\n // A parent cycle in bad data would otherwise recurse forever; cycle members simply don't show.\n if (seen.has(c.id)) return;\n seen.add(c.id);\n if (!matchesAudiences(c.audienceIds, member)) return;\n const here = [...path, c.name];\n const list = direct.get(c.id);\n if (list?.length) sections.push({ collection: c, path: here, depth: here.length - 1, articles: list });\n for (const child of children.get(c.id) ?? []) visit(child, here);\n };\n for (const root of children.get(null) ?? []) visit(root, []);\n if (uncategorized.length) sections.push({ collection: null, path: [], depth: 0, articles: uncategorized });\n return sections;\n}\n\n/**\n * Whether one article is listed for a viewer: its own audiences and those of every collection above\n * it must match. For articles outside a loaded list (e.g. server search results).\n */\nexport function isArticleListed(collections: readonly RcCollectionLike[], article: RcArticleLike, member?: Membership): boolean {\n if (!matchesAudiences(article.audienceIds, member)) return false;\n const byId = new Map(collections.map((c) => [c.id, c]));\n let cur = article.collectionId ? byId.get(article.collectionId) : undefined;\n for (let guard = 0; cur && guard <= MAX_COLLECTION_DEPTH * 4; guard++) {\n if (!matchesAudiences(cur.audienceIds, member)) return false;\n cur = cur.parentId ? byId.get(cur.parentId) : undefined;\n }\n return true;\n}\n\n// ---------------------------------------------------------------------------\n// Logged-in only articles\n// ---------------------------------------------------------------------------\n\n/** Who an article is listed for, besides its audiences: everyone, or logged-in (identified) visitors only. */\nexport const ARTICLE_VISIBILITIES = [\"everyone\", \"identified\"] as const;\nexport type ArticleVisibility = (typeof ARTICLE_VISIBILITIES)[number];\n\n/**\n * Reserved audience every logged-in visitor belongs to. The server folds an article's visibility into\n * the audiences it serves and adds this one to identified visitors' memberships, so every SDK (old ones\n * too) applies \"logged-in only\" through the audience matching it already does. Anonymous visitors never\n * identify, so their membership is empty and these articles stay hidden.\n */\nexport const LOGGED_IN_AUDIENCE = \"$identified\";\n\n/**\n * The audiences an article is served with. Logged-in only with no audiences becomes the reserved\n * audience; with audiences it is already implied, since audience membership only comes from identify.\n */\nexport function servedArticleAudiences(audienceIds: readonly string[], visibility: ArticleVisibility | string | null | undefined): string[] {\n return visibility === \"identified\" && audienceIds.length === 0 ? [LOGGED_IN_AUDIENCE] : [...audienceIds];\n}\n\n/** A visitor's memberships as matched against served articles: logged-in visitors are also in `LOGGED_IN_AUDIENCE`. */\nexport function visitorAudiences(audienceIds: readonly string[], identified: boolean): string[] {\n const ids = audienceIds.filter((id) => id !== LOGGED_IN_AUDIENCE);\n return identified ? [...ids, LOGGED_IN_AUDIENCE] : ids;\n}\n\n/** Ids of the articles a viewer sees (for filtering server search results the same way). */\nexport function visibleArticleIds(collections: readonly RcCollectionLike[], articles: readonly RcArticleLike[], member?: Membership): Set<string> {\n return new Set(resourceCenterSections(collections, articles, member).flatMap((s) => s.articles.map((a) => a.id)));\n}\n\n// ---------------------------------------------------------------------------\n// \"Show me\" prompts in help articles\n// ---------------------------------------------------------------------------\n\n/**\n * A \"Show me\" prompt in an article body is a plain link, `<p class=\"gd-show-me\"><a href=\"#guidely-show-me:<guide key>\">Show me how</a></p>`,\n * so it survives every sanitizer and reads as a harmless link anywhere else. The widgets turn it into a\n * button that starts the walkthrough (a live flow guide), or hide it when that guide isn't available.\n */\nexport const SHOW_ME_CLASS = \"gd-show-me\";\nexport const SHOW_ME_HREF_PREFIX = \"#guidely-show-me:\";\nconst SHOW_ME_KEY = /^[A-Za-z0-9_-]{1,64}$/;\n\nexport function showMeHref(guideKey: string): string {\n return `${SHOW_ME_HREF_PREFIX}${guideKey}`;\n}\n\n/** The guide key of a Show me link's `href`, or null. */\nexport function showMeKeyFromHref(href: string | null | undefined): string | null {\n if (!href || !href.startsWith(SHOW_ME_HREF_PREFIX)) return null;\n const key = href.slice(SHOW_ME_HREF_PREFIX.length);\n return SHOW_ME_KEY.test(key) ? key : null;\n}\n\n/** Guide keys of the Show me prompts in an article body, in order, without repeats (at most 10). */\nexport function showMeKeys(html: string | null | undefined): string[] {\n const out: string[] = [];\n for (const m of (html ?? \"\").matchAll(/href=\"#guidely-show-me:([A-Za-z0-9_-]{1,64})\"/g)) if (!out.includes(m[1]!)) out.push(m[1]!);\n return out.slice(0, 10);\n}\n\n/** The article body plays a video (uploaded, or embedded from YouTube, Vimeo, Loom or Wistia). */\nexport function hasVideoMedia(html: string | null | undefined): boolean {\n return /<(video|iframe)\\b/i.test(html ?? \"\");\n}\n\nconst words = (s: string) => s.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? [];\n\n/**\n * Help search on the device: every word of the query starts a word of the text, in any order, or the\n * query appears as typed. \"add user\" finds \"Add a new user\" and \"Users › Add\".\n */\nexport function matchesHelpQuery(text: string, query: string): boolean {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n const hay = text.toLowerCase();\n if (hay.includes(q)) return true;\n const terms = words(q);\n if (!terms.length) return false;\n const have = words(hay);\n return terms.every((t) => have.some((w) => w.startsWith(t) || (t.length > 3 && t.endsWith(\"s\") && w.startsWith(t.slice(0, -1)))));\n}\n\n// ---------------------------------------------------------------------------\n// Modules (section order + targeting) and \"What's new\"\n// ---------------------------------------------------------------------------\n\nexport const RC_MODULE_IDS = [\"announcements\", \"search\", \"checklists\", \"guides\", \"articles\", \"links\", \"faqs\"] as const;\nexport type ResourceCenterModuleId = (typeof RC_MODULE_IDS)[number];\n\nexport const RC_MODULE_LABELS: Record<ResourceCenterModuleId, string> = {\n announcements: \"What's new\",\n search: \"Search\",\n checklists: \"Checklists\",\n guides: \"Guides & tours\",\n articles: \"Articles\",\n links: \"Links\",\n faqs: \"FAQs\",\n};\n\n/**\n * The resource center's sections in display order: the configured modules (unknown ids dropped,\n * missing ones appended enabled, in the default order), so an old config shows every section.\n */\nexport function orderedModules<M extends { id: string; enabled: boolean }>(modules: readonly M[] | null | undefined): Array<M | { id: ResourceCenterModuleId; enabled: true }> {\n const known = (modules ?? []).filter((m, i, all) => (RC_MODULE_IDS as readonly string[]).includes(m.id) && all.findIndex((x) => x.id === m.id) === i);\n const missing = RC_MODULE_IDS.filter((id) => !known.some((m) => m.id === id)).map((id) => ({ id, enabled: true as const }));\n return [...known, ...missing];\n}\n\n/** Announcements a visitor sees: published (not in the future), audience-matched, newest first. */\nexport function visibleAnnouncements<A extends { publishedAt: string; audienceIds?: string[] }>(items: readonly A[] | null | undefined, member?: Membership, now: number = Date.now()): A[] {\n return (items ?? [])\n .filter((a) => {\n const t = Date.parse(a.publishedAt);\n return !Number.isNaN(t) && t <= now && matchesAudiences(a.audienceIds, member);\n })\n .sort((a, b) => Date.parse(b.publishedAt) - Date.parse(a.publishedAt));\n}\n\n/** Unread count for the launcher badge: announcements published after the visitor last opened \"What's new\". */\nexport function unreadAnnouncements(items: readonly { publishedAt: string }[], lastSeenAt: string | null | undefined): number {\n const seen = lastSeenAt ? Date.parse(lastSeenAt) : NaN;\n if (Number.isNaN(seen)) return items.length;\n return items.filter((a) => Date.parse(a.publishedAt) > seen).length;\n}\n","import { z } from \"zod\";\nimport { SelectorStrategySchema } from \"./guide\";\n\n/**\n * How-tos: step-by-step guides with screenshots, recorded by clicking through the customer's app\n * (SDK capture mode) and edited in the dashboard. Each step is either an action captured in the app\n * (click, type, select, navigate) or a block the author added (text, heading, tip, alert).\n */\n\nexport const HOWTO_STEP_KINDS = [\"action\", \"text\", \"heading\", \"tip\", \"alert\"] as const;\nexport type HowToStepKind = (typeof HOWTO_STEP_KINDS)[number];\n\nexport const HOWTO_ACTIONS = [\"click\", \"type\", \"select\", \"navigate\"] as const;\nexport type HowToAction = (typeof HOWTO_ACTIONS)[number];\n\n/** A rectangle as fractions (0–1) of its screenshot, so it survives any rendered size. */\nexport const NormalizedRectSchema = z.object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n width: z.number().min(0).max(1),\n height: z.number().min(0).max(1),\n});\nexport type NormalizedRect = z.infer<typeof NormalizedRectSchema>;\n\n/** The element an action was performed on, described for people (not for selecting it). */\nexport const CapturedElementSchema = z.object({\n /** Visible name: aria-label, associated label, text, placeholder, alt or title. */\n label: z.string().max(200).default(\"\"),\n /** button, link, tab, menuitem, checkbox, radio, field, dropdown, option, element… */\n role: z.string().max(40).default(\"element\"),\n tag: z.string().max(40).default(\"\"),\n});\nexport type CapturedElement = z.infer<typeof CapturedElementSchema>;\n\n/**\n * One action the SDK recorded, sent with its screenshot as multipart form data\n * (`step` = this JSON, `screenshot` = the image) to `POST /api/v1/sdk/capture/steps?token=`.\n * Sensitive values never arrive here: the SDK drops typed text from password, payment, one-time-code\n * and masked fields and redacts screenshots in the browser before uploading them.\n */\nexport const CaptureStepSchema = z.object({\n /** Random id from the SDK; a retried upload with the same id is stored once. */\n clientId: z.string().min(1).max(64),\n action: z.enum(HOWTO_ACTIONS),\n url: z.string().max(2000),\n pageTitle: z.string().max(300).default(\"\"),\n element: CapturedElementSchema.optional(),\n /** Typed text or chosen option; absent when it was sensitive (`valueRedacted`). */\n value: z.string().max(200).optional(),\n valueRedacted: z.boolean().default(false),\n /** Selectors for the element, so the step can later become an interactive tour step. */\n selectors: z.array(SelectorStrategySchema).max(10).default([]),\n /** Where the element sits in the screenshot. */\n highlight: NormalizedRectSchema.optional(),\n /** Number of regions the SDK blurred in the screenshot before upload. */\n redactions: z.number().int().min(0).max(1000).default(0),\n occurredAt: z.string().datetime().optional(),\n});\nexport type CaptureStep = z.infer<typeof CaptureStepSchema>;\nexport type CaptureStepInput = z.input<typeof CaptureStepSchema>;\n\n/** `GET /api/v1/sdk/capture/session?token=`: what the SDK needs to start recording. */\nexport interface CaptureSessionInfo {\n id: string;\n projectId: string;\n environment: string;\n howToId: string;\n howToTitle: string;\n /** Origin of the dashboard window that opened the app (for `postMessage`). */\n dashboardOrigin: string;\n expiresAt: string;\n /** Steps already recorded (a recording continues across full page loads). */\n stepCount: number;\n /** False when the server has no media storage: record steps without screenshots. */\n screenshots: boolean;\n}\n\nexport { CAPTURE_PARAM, CAPTURE_SCREENSHOT_MAX_BYTES } from \"./howto-limits\";\n\nfunction quoted(s: string | undefined) {\n const t = (s ?? \"\").replace(/\\s+/g, \" \").trim();\n return t.length > 60 ? `“${t.slice(0, 57)}…”` : `“${t}”`;\n}\n\n/**\n * A label as people would say it: icon glyphs and symbols at either end (\"+ New contact\", \"Next →\")\n * and required-field markers (\"Email *\", \"Name:\") removed. Falls back to the raw label when nothing\n * readable is left.\n */\nexport function cleanLabel(label: string | undefined | null): string {\n const raw = (label ?? \"\").replace(/\\s+/g, \" \").trim();\n const cleaned = raw\n .replace(/^[^\\p{L}\\p{N}“\"'(]+/u, \"\")\n .replace(/[\\s:*]+$/u, \"\")\n .replace(/[^\\p{L}\\p{N})”\"'?!.%]+$/u, \"\")\n .trim();\n return cleaned || raw;\n}\n\nconst SEPARATORS = /\\s+[·|•–—-]\\s+|\\s*[|·•]\\s*/;\nconst ID_SEGMENT = /^(?:\\d+|[0-9a-f]{8,}(?:-[0-9a-f]{4,})*|[A-Za-z0-9_-]{20,})$/i;\n\nfunction humanize(segment: string) {\n const words = decodeURIComponent(segment).replace(/[-_+]+/g, \" \").trim();\n return words ? words.charAt(0).toUpperCase() + words.slice(1) : \"\";\n}\n\n/**\n * Name of the page a navigate step opens. A title like \"Contacts · Northwind CRM\" gives \"Contacts\";\n * a title that's just the app's name (no word of the path in it) gives the path instead, so\n * \"/contacts/new\" reads \"Contacts › New\". Ids in the path are skipped.\n */\nexport function pageName(url: string, pageTitle: string | undefined | null): string {\n const title = (pageTitle ?? \"\").replace(/\\s+/g, \" \").trim();\n const parts = title.split(SEPARATORS).map((p) => p.trim()).filter(Boolean);\n if (parts.length > 1) return parts[0]!;\n let segments: string[] = [];\n try {\n segments = new URL(url).pathname.split(\"/\").filter((p) => p && !ID_SEGMENT.test(p));\n } catch {\n segments = [];\n }\n const fromPath = segments.slice(-2).map(humanize).filter(Boolean).join(\" › \");\n if (!fromPath) return title || hostAndPath(url);\n if (!title) return fromPath;\n const lower = title.toLowerCase();\n const mentionsPath = segments.some((seg) => humanize(seg).toLowerCase().split(\" \").some((w) => w.length > 2 && lower.includes(w)));\n return mentionsPath ? title : fromPath;\n}\n\nconst ROLE_NOUN: Record<string, string> = { tab: \"tab\", menuitem: \"menu item\", field: \"field\", dropdown: \"dropdown\", option: \"option\" };\n\n/** Plain-language instruction for a captured action, e.g. `Click “Save”` or `Type “Acme” into “Company”`. */\nexport function describeCaptureStep(step: Pick<CaptureStepInput, \"action\" | \"element\" | \"value\" | \"valueRedacted\" | \"pageTitle\" | \"url\">): string {\n const label = cleanLabel(step.element?.label);\n const role = step.element?.role ?? \"\";\n switch (step.action) {\n case \"navigate\": {\n const where = pageName(step.url, step.pageTitle);\n return where ? `Go to ${quoted(where)}` : \"Open the page\";\n }\n case \"type\": {\n const field = label ? quoted(label) : \"the field\";\n if (step.valueRedacted || !step.value) return `Fill in ${field}`;\n return `Type ${quoted(step.value)} into ${field}`;\n }\n case \"select\":\n if (step.value && label) return `Select ${quoted(step.value)} from ${quoted(label)}`;\n if (step.value) return `Select ${quoted(step.value)}`;\n return label ? `Choose an option in ${quoted(label)}` : \"Choose an option\";\n case \"click\":\n default:\n if (role === \"checkbox\") return label ? `Check ${quoted(label)}` : \"Check the box\";\n if (role === \"switch\") return label ? `Turn ${quoted(label)} on or off` : \"Flip the switch\";\n if (role === \"radio\") return label ? `Select ${quoted(label)}` : \"Select the option\";\n if (role === \"menuitem\") return label ? `Choose ${quoted(label)} from the menu` : \"Choose the menu item\";\n if (role === \"tab\") return label ? `Open the ${quoted(label)} tab` : \"Open the tab\";\n if (label) return `Click ${quoted(label)}`;\n return ROLE_NOUN[role] ? `Click the ${ROLE_NOUN[role]}` : role === \"link\" ? \"Click the link\" : \"Click the button\";\n }\n}\n\nfunction hostAndPath(url: string) {\n try {\n const u = new URL(url);\n return `${u.host}${u.pathname === \"/\" ? \"\" : u.pathname}`;\n } catch {\n return url.slice(0, 80);\n }\n}\n\n/** A point as fractions (0–1) of a screenshot. */\nexport const NormalizedPointSchema = z.object({ x: z.number().min(0).max(1), y: z.number().min(0).max(1) });\nexport const ANNOTATION_COLORS = [\"brand\", \"red\", \"amber\", \"green\", \"black\", \"white\"] as const;\nexport type AnnotationColor = (typeof ANNOTATION_COLORS)[number];\n\n/**\n * A mark drawn over a step's screenshot, in fractions of the full image so it survives cropping and\n * any rendered size: an arrow, a text label or a box. `brand` uses the project's primary colour.\n */\nexport const HowToAnnotationSchema = z.discriminatedUnion(\"type\", [\n z.object({ id: z.string().min(1).max(32), type: z.literal(\"arrow\"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: z.enum(ANNOTATION_COLORS).default(\"brand\") }),\n z.object({ id: z.string().min(1).max(32), type: z.literal(\"text\"), at: NormalizedPointSchema, text: z.string().trim().min(1).max(120), color: z.enum(ANNOTATION_COLORS).default(\"brand\") }),\n z.object({ id: z.string().min(1).max(32), type: z.literal(\"box\"), rect: NormalizedRectSchema, color: z.enum(ANNOTATION_COLORS).default(\"brand\") }),\n]);\nexport type HowToAnnotation = z.infer<typeof HowToAnnotationSchema>;\nexport const MAX_ANNOTATIONS = 30;\n","/** How-to capture constants the browser SDK needs without zod (also exported from `@guidelytech/shared/runtime`). */\n\n/** Query parameter that starts capture mode in the SDK (separate from `guidely_authoring`, so SDKs without capture ignore it). */\nexport const CAPTURE_PARAM = \"guidely_capture\";\n/** Largest screenshot the capture endpoint accepts. */\nexport const CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;\n","/**\n * Page helpers shared by the SDK (page-aware messenger) and the server (page matching, analytics).\n * Pure and zod-free.\n */\n\n/**\n * One path segment that looks like an identifier: digits, a UUID, or a long hex string (hashes,\n * Mongo ids). Written so the same source works as a JS RegExp and a Postgres ARE (`regexp_replace`\n * with flags `gi`), which keeps id folding identical in SQL and in code. A segment may be followed\n * by the page query parameters a project keeps in its paths (`/contacts/42?tab=notes`).\n */\nexport const PATH_ID_PATTERN = \"/([0-9]+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[0-9a-f]{12,})(?=[/?]|$)\";\n\n/** `/contacts/42/notes/9f8e…` → `/contacts/:id/notes/:id`; `/contacts/42?tab=notes` → `/contacts/:id?tab=notes`. */\nexport function foldPathIds(path: string): string {\n return path.replace(new RegExp(PATH_ID_PATTERN, \"gi\"), \"/:id\");\n}\n\n/** Path segments that say nothing about what a page is for. */\nconst GENERIC_SEGMENTS = new Set([\"\", \":id\", \"app\", \"apps\", \"dashboard\", \"home\", \"index\", \"main\", \"new\", \"edit\", \"view\", \"show\", \"details\", \"detail\", \"overview\", \"list\", \"all\", \"page\", \"pages\", \"en\", \"v1\", \"v2\"]);\n\nfunction segmentsOf(path: string): string[] {\n const clean = foldPathIds((path.split(/[?#]/)[0] || \"/\").toLowerCase());\n return clean\n .split(\"/\")\n .map((s) => s.replace(/\\.(html?|php|aspx?)$/, \"\"))\n .filter((s) => !GENERIC_SEGMENTS.has(s) && /[a-z]/.test(s) && s.length <= 40);\n}\n\n/** Words describing a page, from its path (`/settings/billing-plans/42` → `settings billing plans`). */\nexport function pageTerms(path: string): string[] {\n const words = segmentsOf(path).flatMap((s) => s.split(/[-_.+\\s]+/).filter((w) => w.length > 1 && /[a-z]/.test(w)));\n return [...new Set(words)].slice(0, 8);\n}\n\n/** A short human name for a page (`/app/invoices/42` → `Invoices`), or null for the root and unnamed pages. */\nexport function pageLabel(path: string): string | null {\n const last = segmentsOf(path).at(-1);\n if (!last) return null;\n const words = last.split(/[-_.+\\s]+/).filter(Boolean);\n if (!words.length) return null;\n const label = words.join(\" \");\n return label.charAt(0).toUpperCase() + label.slice(1);\n}\n\n/** The first name in a user's traits (`firstName`, `first_name`, or the first word of `name`), or null. */\nexport function firstNameFromTraits(traits: Record<string, unknown> | null | undefined): string | null {\n if (!traits) return null;\n const pick = (v: unknown) => (typeof v === \"string\" ? v.trim() : \"\");\n const first = pick(traits.firstName) || pick(traits.first_name) || pick(traits.firstname) || pick(traits.name).split(/\\s+/)[0] || \"\";\n // Never greet someone by an email address or an id.\n if (!first || first.length > 40 || first.includes(\"@\") || !/\\p{L}/u.test(first)) return null;\n return first;\n}\n","/**\n * Tagged pages and features (named rules over the URLs and clicks the SDK captures), shared by the server (retroactive\n * matching, SQL generation), the dashboard (previews) and the SDK (event properties). Pure and zod-free.\n *\n * - An `ElementSnapshot` is the compact description of a clicked element the SDK attaches to `click`\n * events (`properties.el`): tag, id, classes, a few safe attributes, nth-of-type, ~5 ancestors and\n * the shadow hosts above it. CSS selector rules are evaluated against it with {@link matchCssSelector},\n * so a rule written today also matches clicks stored before it existed.\n * - Older clicks carry only a selector string; {@link snapshotFromSelector} turns that string into a\n * partial snapshot so CSS rules still match them where the string says enough.\n */\n\n// ---------------------------------------------------------------------------\n// Element snapshots\n// ---------------------------------------------------------------------------\n\n/** One element in a snapshot: tag, id, classes, safe attributes and its 1-based nth-of-type. */\nexport interface ElementNode {\n t: string;\n id?: string;\n c?: string[];\n a?: Record<string, string>;\n n?: number;\n}\n\n/** A clicked element (`click.properties.el`): the element, its ancestors (`p`, parent first) and shadow hosts (`h`, nearest first). */\nexport interface ElementSnapshot extends ElementNode {\n p?: ElementNode[];\n h?: ElementNode[];\n}\n\nexport const SNAPSHOT_LIMITS = { classes: 8, className: 60, attrs: 6, attrValue: 100, ancestors: 5, hosts: 3, tag: 40, id: 80 } as const;\n\n/** Attributes a snapshot may carry besides `data-*` ones. Never `value`, never event handlers. */\nexport const SNAPSHOT_ATTRS = [\"role\", \"name\", \"type\", \"aria-label\", \"title\", \"alt\", \"for\", \"href\"] as const;\n\n/** Framework and state `data-*` attributes that say nothing stable about an element. */\nexport const NOISY_DATA_ATTR = /^data-(state|v-|react|radix|headlessui|svelte|orientation|highlighted|focus|key|index|side|align|disabled|selected|active|open|rbd|dnd|sveltekit|guidely-(mask|ignore|block))/i;\n\n/** The custom attribute that names a feature by default (`<button data-guidely-feature=\"Export CSV\">`). */\nexport const DEFAULT_FEATURE_ATTRIBUTE = \"data-guidely-feature\";\nexport const FEATURE_ATTRIBUTE_PATTERN = /^data-[a-z0-9][a-z0-9_.-]{0,60}$/;\n\nfunction str(v: unknown, max: number): string | undefined {\n return typeof v === \"string\" && v ? v.slice(0, max) : undefined;\n}\n\nfunction cleanNode(raw: unknown): ElementNode | null {\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n const t = str(r.t, SNAPSHOT_LIMITS.tag)?.toLowerCase();\n if (!t || !/^[a-z][a-z0-9-]*$/.test(t)) return null;\n const node: ElementNode = { t };\n const id = str(r.id, SNAPSHOT_LIMITS.id);\n if (id) node.id = id;\n if (Array.isArray(r.c)) {\n const c = r.c.filter((x): x is string => typeof x === \"string\" && !!x && x.length <= SNAPSHOT_LIMITS.className && !/\\s/.test(x)).slice(0, SNAPSHOT_LIMITS.classes);\n if (c.length) node.c = c;\n }\n if (r.a && typeof r.a === \"object\" && !Array.isArray(r.a)) {\n const a: Record<string, string> = {};\n for (const [k, v] of Object.entries(r.a as Record<string, unknown>)) {\n if (Object.keys(a).length >= SNAPSHOT_LIMITS.attrs) break;\n const key = k.toLowerCase();\n if (typeof v !== \"string\" || !(key.startsWith(\"data-\") || (SNAPSHOT_ATTRS as readonly string[]).includes(key)) || key === \"value\" || key.length > 60) continue;\n a[key] = v.slice(0, SNAPSHOT_LIMITS.attrValue);\n }\n if (Object.keys(a).length) node.a = a;\n }\n if (typeof r.n === \"number\" && Number.isInteger(r.n) && r.n >= 1 && r.n <= 10_000) node.n = r.n;\n return node;\n}\n\n/** Validates and trims a snapshot sent by an SDK (server side); null when it is not one. */\nexport function normalizeSnapshot(raw: unknown): ElementSnapshot | null {\n const el = cleanNode(raw);\n if (!el) return null;\n const r = raw as Record<string, unknown>;\n const out: ElementSnapshot = el;\n if (Array.isArray(r.p)) {\n const p = r.p.slice(0, SNAPSHOT_LIMITS.ancestors).map(cleanNode);\n // Ancestors are consecutive; stop at the first unusable one rather than skipping it.\n const cut = p.indexOf(null);\n const list = (cut === -1 ? p : p.slice(0, cut)) as ElementNode[];\n if (list.length) out.p = list;\n }\n if (Array.isArray(r.h)) {\n const h = r.h.slice(0, SNAPSHOT_LIMITS.hosts).map(cleanNode).filter((x): x is ElementNode => !!x);\n if (h.length) out.h = h;\n }\n return out;\n}\n\n/** JSON with sorted keys, so equal snapshots hash the same whatever order the SDK wrote them in. */\nexport function stableStringify(v: unknown): string {\n if (Array.isArray(v)) return `[${v.map(stableStringify).join(\",\")}]`;\n if (v && typeof v === \"object\") {\n const o = v as Record<string, unknown>;\n return `{${Object.keys(o)\n .filter((k) => o[k] !== undefined)\n .sort()\n .map((k) => `${JSON.stringify(k)}:${stableStringify(o[k])}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(v ?? null);\n}\n\n// ---------------------------------------------------------------------------\n// CSS selector subset: parse + match against a snapshot\n// ---------------------------------------------------------------------------\n\nexport type AttrOp = \"exists\" | \"=\" | \"^=\" | \"$=\" | \"*=\" | \"~=\" | \"|=\";\n\nexport interface AttrTest {\n name: string;\n op: AttrOp;\n value?: string;\n /** `[attr=\"x\" i]` */\n insensitive?: boolean;\n}\n\nexport interface Compound {\n tag?: string;\n id?: string;\n classes: string[];\n attrs: AttrTest[];\n /** `:nth-of-type(n)`; `odd`/`even` as `{ a: 2, b: 1|0 }`; `:first-of-type` is `{ a: 0, b: 1 }`. */\n nth?: { a: number; b: number };\n}\n\n/** A complex selector: compounds left to right and the combinator before each (index 0 has none). */\nexport interface ComplexSelector {\n compounds: Compound[];\n combinators: Array<\" \" | \">\" | \">>>\">;\n}\n\nexport class SelectorSyntaxError extends Error {}\n\nconst IDENT_START = /[A-Za-z_\\u00a0-\\uffff-]/;\nconst IDENT_CHAR = /[A-Za-z0-9_\\u00a0-\\uffff-]/;\n\n/**\n * Parses the supported subset: type and universal selectors, `#id`, `.class`, `[attr]`,\n * `[attr=v]`, `^=`, `$=`, `*=`, `~=`, `|=` (optionally `i`), `:nth-of-type(n|odd|even)`,\n * `:first-of-type`, descendant and child combinators, `>>>` (shadow host) and selector lists.\n * Throws {@link SelectorSyntaxError} on anything else.\n */\nexport function parseCssSelector(input: string): ComplexSelector[] {\n const s = input.trim();\n if (!s) throw new SelectorSyntaxError(\"Empty selector\");\n if (s.length > 1000) throw new SelectorSyntaxError(\"Selector is too long\");\n let i = 0;\n const peek = () => s[i];\n const eof = () => i >= s.length;\n const fail = (msg: string): never => {\n throw new SelectorSyntaxError(`${msg} at position ${i + 1}`);\n };\n const ws = () => {\n let any = false;\n while (!eof() && /\\s/.test(s[i]!)) {\n i++;\n any = true;\n }\n return any;\n };\n const escape = (): string => {\n // after the backslash\n i++;\n const hex = /^[0-9a-fA-F]{1,6}/.exec(s.slice(i));\n if (hex) {\n i += hex[0].length;\n if (s[i] === \" \") i++;\n return String.fromCodePoint(parseInt(hex[0], 16));\n }\n if (eof()) fail(\"Unfinished escape\");\n return s[i++]!;\n };\n const ident = (): string => {\n let out = \"\";\n if (s[i] === \"\\\\\") out += escape();\n else if (!eof() && IDENT_START.test(s[i]!)) out += s[i++];\n else fail(\"Expected a name\");\n while (!eof()) {\n if (s[i] === \"\\\\\") out += escape();\n else if (IDENT_CHAR.test(s[i]!)) out += s[i++];\n else break;\n }\n return out;\n };\n const quoted = (): string => {\n const q = s[i++];\n let out = \"\";\n while (!eof() && s[i] !== q) {\n if (s[i] === \"\\\\\") out += escape();\n else out += s[i++];\n }\n if (eof()) fail(\"Unterminated string\");\n i++;\n return out;\n };\n const compound = (): Compound | null => {\n const c: Compound = { classes: [], attrs: [] };\n let any = false;\n if (peek() === \"*\") {\n i++;\n any = true;\n } else if (!eof() && (IDENT_START.test(peek()!) || peek() === \"\\\\\")) {\n c.tag = ident().toLowerCase();\n any = true;\n }\n for (;;) {\n const ch = peek();\n if (ch === \"#\") {\n i++;\n c.id = ident();\n } else if (ch === \".\") {\n i++;\n c.classes.push(ident());\n } else if (ch === \"[\") {\n i++;\n ws();\n const name = ident().toLowerCase();\n ws();\n let op: AttrOp = \"exists\";\n let value: string | undefined;\n let insensitive = false;\n if (peek() !== \"]\") {\n const m = /^(=|\\^=|\\$=|\\*=|~=|\\|=)/.exec(s.slice(i));\n if (!m) fail(\"Unsupported attribute operator\");\n op = m![1] as AttrOp;\n i += m![1]!.length;\n ws();\n value = peek() === '\"' || peek() === \"'\" ? quoted() : ident();\n ws();\n if (peek() === \"i\" || peek() === \"I\") {\n i++;\n insensitive = true;\n ws();\n } else if (peek() === \"s\" || peek() === \"S\") {\n i++;\n ws();\n }\n }\n if (peek() !== \"]\") fail(\"Expected ]\");\n i++;\n c.attrs.push({ name, op, ...(value !== undefined ? { value } : {}), ...(insensitive ? { insensitive } : {}) });\n } else if (ch === \":\") {\n i++;\n if (peek() === \":\") fail(\"Pseudo-elements are not supported\");\n const name = ident().toLowerCase();\n if (name === \"first-of-type\") c.nth = { a: 0, b: 1 };\n else if (name === \"nth-of-type\") {\n if (peek() !== \"(\") fail(\"Expected (\");\n i++;\n ws();\n const m = /^(odd|even|\\d+)/i.exec(s.slice(i));\n if (!m) fail(\"Only :nth-of-type(n), odd or even are supported\");\n i += m![0].length;\n ws();\n if (peek() !== \")\") fail(\"Expected )\");\n i++;\n const v = m![0].toLowerCase();\n c.nth = v === \"odd\" ? { a: 2, b: 1 } : v === \"even\" ? { a: 2, b: 0 } : { a: 0, b: Number(v) };\n } else fail(`Unsupported pseudo-class :${name}`);\n } else break;\n any = true;\n }\n return any ? c : null;\n };\n\n const list: ComplexSelector[] = [];\n for (;;) {\n ws();\n const sel: ComplexSelector = { compounds: [], combinators: [] };\n const first = compound();\n if (!first) fail(\"Expected a selector\");\n sel.compounds.push(first!);\n for (;;) {\n const hadWs = ws();\n if (eof() || peek() === \",\") break;\n let comb: \" \" | \">\" | \">>>\" = \" \";\n if (s.startsWith(\">>>\", i)) {\n comb = \">>>\";\n i += 3;\n ws();\n } else if (peek() === \">\") {\n comb = \">\";\n i++;\n ws();\n } else if (peek() === \"+\" || peek() === \"~\") fail(\"Sibling combinators are not supported\");\n else if (!hadWs) fail(\"Unexpected character\");\n const next = compound();\n if (!next) fail(\"Expected a selector after the combinator\");\n sel.compounds.push(next!);\n sel.combinators.push(comb);\n }\n list.push(sel);\n if (eof()) break;\n i++; // \",\"\n }\n return list;\n}\n\n/** Is the selector inside the supported subset? Returns the error message, or null when it parses. */\nexport function cssSelectorError(selector: string): string | null {\n try {\n parseCssSelector(selector);\n return null;\n } catch (e) {\n return e instanceof Error ? e.message : \"Invalid selector\";\n }\n}\n\nfunction attrMatches(test: AttrTest, node: ElementNode): boolean {\n let actual: string | undefined;\n if (test.name === \"id\") actual = node.id;\n else if (test.name === \"class\") actual = node.c?.join(\" \");\n else actual = node.a?.[test.name];\n if (actual === undefined) return false;\n if (test.op === \"exists\") return true;\n let v = test.value ?? \"\";\n if (test.insensitive) {\n actual = actual.toLowerCase();\n v = v.toLowerCase();\n }\n switch (test.op) {\n case \"=\":\n return actual === v;\n case \"^=\":\n return !!v && actual.startsWith(v);\n case \"$=\":\n return !!v && actual.endsWith(v);\n case \"*=\":\n return !!v && actual.includes(v);\n case \"~=\":\n return !!v && actual.split(/\\s+/).includes(v);\n case \"|=\":\n return actual === v || actual.startsWith(`${v}-`);\n default:\n return false;\n }\n}\n\n/** Does one compound match one node? An unknown nth-of-type fails `:nth-of-type` tests. */\nexport function compoundMatches(c: Compound, node: ElementNode): boolean {\n if (c.tag && c.tag !== node.t) return false;\n if (c.id !== undefined && node.id !== c.id) return false;\n for (const cls of c.classes) if (!node.c?.includes(cls)) return false;\n for (const a of c.attrs) if (!attrMatches(a, node)) return false;\n if (c.nth) {\n if (!node.n) return false;\n const { a, b } = c.nth;\n if (a === 0 ? node.n !== b : (node.n - b) % a !== 0 || (node.n - b) / a < 0) return false;\n }\n return true;\n}\n\n/** Matches compounds (right to left) against a chain of nodes: index 0 is the element, then its ancestors. */\nfunction chainMatches(compounds: Compound[], combinators: Array<\" \" | \">\">, nodes: ElementNode[], ci = compounds.length - 1, ni = 0): boolean {\n if (!compoundMatches(compounds[ci]!, nodes[ni]!)) return false;\n if (ci === 0) return true;\n const comb = combinators[ci - 1]!;\n if (comb === \">\") return ni + 1 < nodes.length && chainMatches(compounds, combinators, nodes, ci - 1, ni + 1);\n for (let k = ni + 1; k < nodes.length; k++) if (chainMatches(compounds, combinators, nodes, ci - 1, k)) return true;\n return false;\n}\n\nfunction complexMatches(sel: ComplexSelector, snap: ElementSnapshot): boolean {\n // Split at `>>>`: the last segment is matched inside the element's own tree, each earlier\n // segment's last compound against a shadow host further out (any depth, like the runtime).\n const segments: Array<{ compounds: Compound[]; combinators: Array<\" \" | \">\"> }> = [{ compounds: [sel.compounds[0]!], combinators: [] }];\n sel.combinators.forEach((comb, k) => {\n const next = sel.compounds[k + 1]!;\n if (comb === \">>>\") segments.push({ compounds: [next], combinators: [] });\n else {\n const seg = segments[segments.length - 1]!;\n seg.compounds.push(next);\n seg.combinators.push(comb);\n }\n });\n const last = segments.pop()!;\n const nodes: ElementNode[] = [snap, ...(snap.p ?? [])];\n if (!chainMatches(last.compounds, last.combinators, nodes)) return false;\n const hosts = snap.h ?? [];\n let from = 0;\n for (let k = segments.length - 1; k >= 0; k--) {\n const target = segments[k]!.compounds[segments[k]!.compounds.length - 1]!;\n let found = -1;\n for (let j = from; j < hosts.length; j++) {\n if (compoundMatches(target, hosts[j]!)) {\n found = j;\n break;\n }\n }\n if (found === -1) return false;\n from = found + 1;\n }\n return true;\n}\n\nconst parsedCache = new Map<string, ComplexSelector[] | null>();\n\n/** Does a CSS selector (subset, see {@link parseCssSelector}) match the snapshot? Invalid selectors match nothing. */\nexport function matchCssSelector(selector: string | ComplexSelector[], snap: ElementSnapshot): boolean {\n let list: ComplexSelector[] | null;\n if (typeof selector === \"string\") {\n if (!parsedCache.has(selector)) {\n if (parsedCache.size > 500) parsedCache.clear();\n try {\n parsedCache.set(selector, parseCssSelector(selector));\n } catch {\n parsedCache.set(selector, null);\n }\n }\n list = parsedCache.get(selector)!;\n } else list = selector;\n return !!list && list.some((sel) => complexMatches(sel, snap));\n}\n\nfunction nodeOfCompound(c: Compound): ElementNode {\n const node: ElementNode = { t: c.tag ?? \"*\" };\n if (c.id) node.id = c.id;\n if (c.classes.length) node.c = c.classes.slice(0, SNAPSHOT_LIMITS.classes);\n const a: Record<string, string> = {};\n for (const t of c.attrs) if (t.op === \"=\" && t.value !== undefined) a[t.name] = t.value;\n if (Object.keys(a).length) node.a = a;\n if (c.nth && c.nth.a === 0) node.n = c.nth.b;\n return node;\n}\n\n/**\n * A partial snapshot read from a stored selector string (clicks captured before snapshots existed):\n * `#form > div:nth-of-type(2) > button[data-testid=\"save\"]` becomes a `button` with that attribute,\n * nth 1-unknown, and two ancestors. Shadow steps (`c-app >>> button`) become hosts. Null when the\n * string is not a selector in the supported subset.\n */\nexport function snapshotFromSelector(selector: string, tag?: string | null): ElementSnapshot | null {\n let list: ComplexSelector[];\n try {\n list = parseCssSelector(selector);\n } catch {\n return null;\n }\n if (list.length !== 1) return null;\n const sel = list[0]!;\n const segments: Compound[][] = [[sel.compounds[0]!]];\n sel.combinators.forEach((comb, k) => {\n if (comb === \">>>\") segments.push([sel.compounds[k + 1]!]);\n else segments[segments.length - 1]!.push(sel.compounds[k + 1]!);\n });\n const own = segments.pop()!;\n const el = nodeOfCompound(own[own.length - 1]!);\n if (el.t === \"*\" && tag && /^[a-z][a-z0-9-]*$/i.test(tag)) el.t = tag.toLowerCase();\n const snap: ElementSnapshot = el;\n const p = own.slice(0, -1).reverse().map(nodeOfCompound);\n if (p.length) snap.p = p.slice(0, SNAPSHOT_LIMITS.ancestors);\n const h = segments.reverse().map((seg) => nodeOfCompound(seg[seg.length - 1]!));\n if (h.length) snap.h = h.slice(0, SNAPSHOT_LIMITS.hosts);\n return snap;\n}\n\n// ---------------------------------------------------------------------------\n// Page rules\n// ---------------------------------------------------------------------------\n\nexport type QueryParamOp = \"exists\" | \"absent\" | \"equals\" | \"contains\";\nexport interface QueryParamCondition {\n name: string;\n op: QueryParamOp;\n value?: string;\n}\n\n/**\n * One way a URL belongs to a page. `url`: a pattern (`/accounts/:id/settings`, `/reports/*`,\n * `/docs/**`, `//*\\/billing`, `https://app.acme.com/x`) plus optional query conditions; `regex`: a\n * regular expression over the path; `title`: the document title (`equals` / `contains`). With\n * `exclude`, matching URLs are taken out of the page instead.\n */\nexport interface PageRule {\n id?: string;\n type: \"url\" | \"regex\" | \"title\";\n value: string;\n op?: \"equals\" | \"contains\";\n query?: QueryParamCondition[];\n exclude?: boolean;\n}\n\nexport const PAGE_RULE_LIMITS = { rules: 20, value: 500, query: 5 } as const;\n\nexport interface PagePattern {\n /** Anchored regex source, valid both as a JS RegExp (flag `i`) and a Postgres ARE (`~*`). */\n source: string;\n /** What it runs against: the path (query removed) or the full URL without query and hash. */\n target: \"path\" | \"url\";\n /** Query conditions written into the pattern (`/search?tab=people`). */\n query: QueryParamCondition[];\n}\n\nconst escapeRe = (s: string) => s.replace(/[.+?^${}()|[\\]\\\\*]/g, \"\\\\$&\");\n\nfunction globToRegex(pattern: string): string {\n let out = \"\";\n for (let k = 0; k < pattern.length; k++) {\n const ch = pattern[k]!;\n if (ch === \"*\") {\n if (pattern[k + 1] === \"*\") {\n out += \".*\";\n k++;\n } else out += \"[^/]*\";\n } else if (ch === \":\" && (k === 0 || pattern[k - 1] === \"/\") && /[A-Za-z_]/.test(pattern[k + 1] ?? \"\")) {\n // `:name` path parameter: one whole segment.\n let j = k + 1;\n while (j < pattern.length && /[\\w]/.test(pattern[j]!)) j++;\n out += \"[^/]+\";\n k = j - 1;\n } else out += escapeRe(ch);\n }\n return out;\n}\n\n/** Turns a URL rule pattern into a regex. Query parameters in the pattern become conditions. */\nexport function pagePattern(raw: string): PagePattern {\n let p = raw.trim();\n const query: QueryParamCondition[] = [];\n const hash = p.indexOf(\"#\");\n if (hash !== -1) p = p.slice(0, hash);\n const q = p.indexOf(\"?\");\n if (q !== -1) {\n for (const part of p.slice(q + 1).split(\"&\")) {\n if (!part) continue;\n const eq = part.indexOf(\"=\");\n const name = decodeSafe(eq === -1 ? part : part.slice(0, eq));\n const value = eq === -1 ? undefined : decodeSafe(part.slice(eq + 1));\n if (!name) continue;\n query.push(value === undefined || value === \"*\" ? { name, op: \"exists\" } : { name, op: \"equals\", value });\n }\n p = p.slice(0, q);\n }\n let target: \"path\" | \"url\" = \"path\";\n // `//*` means any domain: keep only the path.\n if (p.startsWith(\"//*\")) p = p.slice(3);\n let prefix = \"\";\n const abs = /^(https?:)?\\/\\/([^/]+)(.*)$/i.exec(p);\n if (abs) {\n target = \"url\";\n prefix = `https?://${globToRegex(abs[2]!.toLowerCase())}`;\n p = abs[3] || \"/\";\n }\n if (!p.startsWith(\"/\")) p = `/${p}`;\n // A trailing slash is optional, as on most sites.\n const body = p.length > 1 && p.endsWith(\"/\") ? p.slice(0, -1) : p;\n const src = body === \"/\" ? \"/?\" : `${globToRegex(body)}/?`;\n return { source: `^${prefix}${src}$`, target, query: query.slice(0, PAGE_RULE_LIMITS.query) };\n}\n\nfunction decodeSafe(s: string): string {\n try {\n return decodeURIComponent(s.replace(/\\+/g, \" \"));\n } catch {\n return s;\n }\n}\n\n/** Regex (JS + Postgres) for a query condition over a raw URL. */\nexport function queryConditionRegex(c: QueryParamCondition): string {\n const name = escapeRe(c.name);\n switch (c.op) {\n case \"equals\":\n return `[?&]${name}=${escapeRe(encodeLoose(c.value ?? \"\"))}(&|#|$)`;\n case \"contains\":\n return `[?&]${name}=[^&#]*${escapeRe(encodeLoose(c.value ?? \"\"))}`;\n default:\n return `[?&]${name}(=|&|#|$)`;\n }\n}\n\n/** URL-encodes what browsers encode in query values, leaving the common safe characters alone. */\nfunction encodeLoose(v: string): string {\n return encodeURIComponent(v).replace(/%2F/gi, \"/\").replace(/%3A/gi, \":\").replace(/%2C/gi, \",\").replace(/%40/gi, \"@\");\n}\n\nexport interface PageContext {\n /** Full URL (with query) when known. */\n url?: string | null;\n /** Path as stored (`/a/b`, or `/a/b?section=x` with kept page parameters). */\n path?: string | null;\n title?: string | null;\n}\n\nfunction pathOnly(ctx: PageContext): string | null {\n if (ctx.path) return ctx.path.split(\"?\")[0] || \"/\";\n if (!ctx.url) return null;\n try {\n return new URL(ctx.url, \"http://x.invalid\").pathname;\n } catch {\n return null;\n }\n}\n\nfunction regexOrNull(source: string): RegExp | null {\n try {\n return new RegExp(source, \"i\");\n } catch {\n return null;\n }\n}\n\n/** JS twin of the SQL a page rule compiles to (server `pageRuleSql`). */\nexport function pageRuleMatches(rule: PageRule, ctx: PageContext): boolean {\n const path = pathOnly(ctx);\n if (rule.type === \"title\") {\n const t = (ctx.title ?? \"\").toLowerCase();\n const v = rule.value.toLowerCase();\n return !!t && (rule.op === \"contains\" ? t.includes(v) : t === v);\n }\n if (rule.type === \"regex\") {\n const re = regexOrNull(rule.value);\n return !!re && path !== null && re.test(path);\n }\n const pat = pagePattern(rule.value);\n const re = regexOrNull(pat.source);\n if (!re) return false;\n let subject: string | null = path;\n if (pat.target === \"url\") {\n if (!ctx.url) return false;\n subject = ctx.url.split(/[?#]/)[0]!;\n }\n if (subject === null || !re.test(subject)) return false;\n const conds = [...pat.query, ...(rule.query ?? [])];\n for (const c of conds) {\n const hit = !!ctx.url && new RegExp(queryConditionRegex(c), \"i\").test(ctx.url);\n if (c.op === \"absent\" ? hit : !hit) return false;\n }\n return true;\n}\n\n/** Included by any include rule and excluded by no exclude rule. */\nexport function pageRulesMatch(rules: PageRule[], ctx: PageContext): boolean {\n const include = rules.filter((r) => !r.exclude);\n if (!include.length || !include.some((r) => pageRuleMatches(r, ctx))) return false;\n return !rules.some((r) => r.exclude && pageRuleMatches(r, ctx));\n}\n\n/** Validation message for a page rule, or null. */\nexport function pageRuleError(rule: PageRule): string | null {\n const v = rule.value?.trim();\n if (!v) return \"A rule needs a value\";\n if (v.length > PAGE_RULE_LIMITS.value) return \"The rule is too long\";\n if (rule.type === \"regex\") {\n if (!regexOrNull(v)) return `\"${v}\" is not a valid regular expression`;\n if (/\\(\\?[<=!]/.test(v) || /\\\\[1-9]/.test(v)) return \"Look-arounds and back-references are not supported\";\n }\n if (rule.type === \"url\" && !regexOrNull(pagePattern(v).source)) return `\"${v}\" is not a valid URL rule`;\n for (const q of rule.query ?? []) if (!/^[A-Za-z0-9_.\\-[\\]]{1,60}$/.test(q.name)) return `\"${q.name}\" is not a query parameter name`;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Feature rules\n// ---------------------------------------------------------------------------\n\nexport type SelectorOp = \"exact\" | \"prefix\" | \"contains\" | \"glob\" | \"css\";\n\n/**\n * One way a click belongs to a feature. Every condition present must hold. `selector.op = \"css\"`\n * evaluates a CSS selector against the element snapshot (or, for old clicks, the snapshot read from\n * the stored selector string); the other selector operators compare the stored selector string —\n * mobile taps store the accessibility id / `data-guidely-id` there, so `exact` works for them too.\n */\nexport interface FeatureRule {\n id?: string;\n selector?: { op: SelectorOp; value: string };\n text?: { op: \"equals\" | \"contains\"; value: string };\n tag?: string;\n href?: { op: \"equals\" | \"prefix\" | \"contains\"; value: string };\n /** Only clicks on this tagged page / URL pattern. */\n page?: { pageId?: string; pattern?: string };\n /** `web`, `ios`, `android` (mobile autocapture sets `properties.platform`). */\n platform?: string;\n exclude?: boolean;\n}\n\nexport const FEATURE_RULE_LIMITS = { rules: 20, value: 1000 } as const;\n\nexport interface ClickFacts {\n selector?: string | null;\n text?: string | null;\n tag?: string | null;\n href?: string | null;\n platform?: string | null;\n}\n\nfunction globMatch(pattern: string, value: string): boolean {\n const re = new RegExp(`^${pattern.split(\"*\").map(escapeRe).join(\".*\")}$`, \"s\");\n return re.test(value);\n}\n\n/** Does a click (facts + a CSS test) satisfy one rule's element conditions? Page scope is checked by the caller. */\nexport function featureRuleMatchesClick(rule: FeatureRule, click: ClickFacts, css: (selector: string) => boolean): boolean {\n if (!rule.selector && !rule.text && !rule.tag && !rule.href) return false;\n if (rule.selector) {\n const sel = click.selector ?? \"\";\n const v = rule.selector.value;\n const ok =\n rule.selector.op === \"css\" ? css(v) : rule.selector.op === \"exact\" ? sel === v : rule.selector.op === \"prefix\" ? sel.startsWith(v) : rule.selector.op === \"contains\" ? sel.includes(v) : globMatch(v, sel);\n if (!ok) return false;\n }\n if (rule.text) {\n const t = (click.text ?? \"\").toLowerCase();\n const v = rule.text.value.toLowerCase();\n if (rule.text.op === \"contains\" ? !t.includes(v) : t !== v) return false;\n }\n if (rule.tag && (click.tag ?? \"\").toLowerCase() !== rule.tag.toLowerCase()) return false;\n if (rule.href) {\n const h = click.href ?? \"\";\n const v = rule.href.value;\n if (rule.href.op === \"equals\" ? h !== v : rule.href.op === \"prefix\" ? !h.startsWith(v) : !h.includes(v)) return false;\n }\n if (rule.platform && (click.platform ?? \"web\") !== rule.platform) return false;\n return true;\n}\n\n/** Validation message for a feature rule, or null. */\nexport function featureRuleError(rule: FeatureRule): string | null {\n if (!rule.selector && !rule.text && !rule.tag && !rule.href) return \"A feature rule needs a selector, text, tag or link condition\";\n if (rule.selector) {\n const v = rule.selector.value?.trim();\n if (!v) return \"The selector is empty\";\n if (v.length > FEATURE_RULE_LIMITS.value) return \"The selector is too long\";\n if (rule.selector.op === \"css\") {\n const err = cssSelectorError(v);\n if (err) return `Unsupported CSS selector: ${err}`;\n }\n }\n if (rule.text && !rule.text.value.trim()) return \"The text condition is empty\";\n if (rule.href && !rule.href.value.trim()) return \"The link condition is empty\";\n if (rule.tag && !/^[a-z][a-z0-9-]{0,40}$/i.test(rule.tag)) return \"The tag is not an element name\";\n if (rule.page?.pattern) return pageRuleError({ type: \"url\", value: rule.page.pattern });\n return null;\n}\n\n/** Selector to find a feature's elements on a page (dashboard overlays, SDK property capture), when the rules give one. */\nexport function featureCssSelectors(rules: FeatureRule[]): string[] {\n const out: string[] = [];\n for (const r of rules) {\n if (r.exclude || !r.selector) continue;\n if ((r.selector.op === \"css\" || r.selector.op === \"exact\") && !cssSelectorError(r.selector.value)) out.push(r.selector.value);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Event properties captured from the DOM (configured per page / feature, sent in the SDK config)\n// ---------------------------------------------------------------------------\n\nexport interface TagPropertyDefinition {\n id: string;\n name: string;\n /** Element to read: CSS selector (may use `>>>`); empty = the clicked element itself (features only). */\n selector?: string;\n source: \"text\" | \"attribute\";\n /** Attribute name for `source: \"attribute\"`; `value` is never read. */\n attribute?: string;\n}\n\n/** One tag's capture config in the SDK payload (`SdkConfigResponse.tagging.properties`). */\nexport interface TagPropertyConfig {\n kind: \"page\" | \"feature\";\n tagId: string;\n /** Page rules (pages) or feature rules (features), evaluated in the browser. */\n pageRules?: PageRule[];\n featureRules?: FeatureRule[];\n properties: TagPropertyDefinition[];\n}\n\nexport interface TaggingSdkConfig {\n /** Attribute that names features automatically (null = off). */\n featureAttribute: string | null;\n properties: TagPropertyConfig[];\n}\n\nexport const TAG_PROPERTY_LIMITS = { perTag: 10, total: 50, value: 100 } as const;\n\n/** Attribute names an event property may read. */\nexport function propertyAttributeAllowed(name: string): boolean {\n const n = name.toLowerCase();\n if (n === \"value\" || n.startsWith(\"on\") || n === \"style\" || n === \"srcdoc\") return false;\n return /^[a-z][a-z0-9_:.-]{0,60}$/.test(n);\n}\n","/**\n * The script-tag install snippet's stub. It defines `window.Guidely` before the SDK has loaded, so\n * the page can call `Guidely.init(…)` and `Guidely.get().identify(…)` straight away: calls are\n * queued and replayed by the SDK when it arrives (`packages/embed`). If the SDK can't load at all\n * (Guidely unreachable, blocked by an extension), the calls simply do nothing and the page carries on.\n *\n * Queued calls are `[onClient, method, args]` in `Guidely._q`; `Guidely.get()` returns `Guidely._c`,\n * which the SDK upgrades in place to forward to the real client. Flag reads return their fallback\n * until then. ES5 only: it runs on the customer's page before anything else.\n */\nexport const SCRIPT_STUB_METHODS = [\n \"identify\",\n \"track\",\n \"page\",\n \"reset\",\n \"setAccount\",\n \"updateTraits\",\n \"setConsent\",\n \"setLocale\",\n \"startGuide\",\n \"stopGuide\",\n \"dismissGuide\",\n \"openMessenger\",\n \"closeMessenger\",\n \"showNewMessage\",\n \"openResourceCenter\",\n \"closeResourceCenter\",\n \"openChecklist\",\n \"closeChecklist\",\n \"completeChecklistTask\",\n \"openComplaint\",\n \"openIdeas\",\n \"captureException\",\n \"agentConversation\",\n \"trackAgentTurn\",\n \"on\",\n] as const;\n\nexport const SCRIPT_STUB = `!function(w){if(w.Guidely)return;var g=w.Guidely={_q:[]},c=g._c={};function q(o,k){o[k]=function(){g._q.push([o===c?1:0,k,[].slice.call(arguments)])}}q(g,\"init\");\"${SCRIPT_STUB_METHODS.join(\" \")}\".split(\" \").forEach(function(k){q(c,k)});c.isFeatureEnabled=function(k,f){return!!f};c.getFeatureValue=function(k,f){return f};g.get=function(){return c}}(window);`;\n\n/** The full script-tag install: stub, init (queued until the SDK loads), then the async SDK script. */\nexport function scriptSnippet(scriptUrl: string, initOptions: string): string {\n return `<script>\n ${SCRIPT_STUB}\n Guidely.init(${initOptions});\n</script>\n<script src=\"${scriptUrl}\" async></script>`;\n}\n","/**\n * Guide and resource-center localization (zod-free, so the browser SDK can import it).\n *\n * Every translatable text field has a stable key derived from ids, never from positions, so\n * reordering steps keeps translations attached: `steps.<stepId>.title`,\n * `steps.<stepId>.buttons.<buttonId>.label`, `checklist.tasks.<taskId>.title`,\n * `survey.questions.<questionId>.options.<optionId>.label`, …\n *\n * A visitor's language comes from (in order) an explicit SDK locale, the `language` / `locale`\n * trait, then the browser / device language. `resolveLocale` matches it against the languages a\n * guide is translated into (exact tag first, then the base language) and falls back to the\n * project's default language, in which the guide is written.\n */\nimport type { GuideConfig } from \"./guide\";\nimport type { PublishedGuide, ResourceCenterAnnouncement, ResourceCenterArticle, ResourceCenterConfig } from \"./sdk-api\";\n\nexport type TextKind = \"text\" | \"html\";\n\nexport interface TextEntry {\n key: string;\n /** Default-language text. */\n source: string;\n kind: TextKind;\n /** Human-readable location for translators (\"Step 2 · Title\"). */\n label: string;\n}\n\n/** Project-level language settings (Project.settings.localization). */\nexport interface LocalizationSettings {\n /** Language the content is written in. */\n defaultLocale: string;\n /** Additional languages offered for translation. */\n locales: string[];\n /** Machine-translate new and changed text into every language automatically. */\n autoTranslate?: boolean;\n /** Machine translations need a teammate's approval before visitors see them. */\n requireReview?: boolean;\n}\n\n/**\n * Review state of one translated text. `machine` texts were written by AI translation; `human`\n * ones were typed or imported by a teammate (approved by doing so). `outdated` means the source\n * text changed after the translation was written or approved.\n */\nexport interface TranslationReviewState {\n origin: \"machine\" | \"human\";\n approved: boolean;\n outdated: boolean;\n reviewedBy?: string | null;\n reviewedAt?: string | null;\n}\n\n/** locale → key → review state. Texts without a state are human translations from before review existed. */\nexport type TranslationReviewMap = Record<string, Record<string, TranslationReviewState>>;\n\n/** Does this translation still need a teammate to look at it? */\nexport function needsReview(state: TranslationReviewState | undefined): boolean {\n return !!state && ((state.origin === \"machine\" && !state.approved) || state.outdated);\n}\n\nexport const DEFAULT_LOCALE = \"en\";\n\n/** Common languages offered in the dashboard's language picker (any BCP 47 tag is accepted). */\nexport const COMMON_LOCALES: Array<{ code: string; name: string }> = [\n { code: \"en\", name: \"English\" },\n { code: \"en-GB\", name: \"English (UK)\" },\n { code: \"fr\", name: \"French\" },\n { code: \"fr-CA\", name: \"French (Canada)\" },\n { code: \"de\", name: \"German\" },\n { code: \"es\", name: \"Spanish\" },\n { code: \"es-MX\", name: \"Spanish (Mexico)\" },\n { code: \"it\", name: \"Italian\" },\n { code: \"pt\", name: \"Portuguese\" },\n { code: \"pt-BR\", name: \"Portuguese (Brazil)\" },\n { code: \"nl\", name: \"Dutch\" },\n { code: \"sv\", name: \"Swedish\" },\n { code: \"da\", name: \"Danish\" },\n { code: \"nb\", name: \"Norwegian\" },\n { code: \"fi\", name: \"Finnish\" },\n { code: \"pl\", name: \"Polish\" },\n { code: \"cs\", name: \"Czech\" },\n { code: \"tr\", name: \"Turkish\" },\n { code: \"ru\", name: \"Russian\" },\n { code: \"uk\", name: \"Ukrainian\" },\n { code: \"ar\", name: \"Arabic\" },\n { code: \"he\", name: \"Hebrew\" },\n { code: \"hi\", name: \"Hindi\" },\n { code: \"ja\", name: \"Japanese\" },\n { code: \"ko\", name: \"Korean\" },\n { code: \"zh-Hans\", name: \"Chinese (Simplified)\" },\n { code: \"zh-Hant\", name: \"Chinese (Traditional)\" },\n { code: \"id\", name: \"Indonesian\" },\n { code: \"th\", name: \"Thai\" },\n { code: \"vi\", name: \"Vietnamese\" },\n];\n\nexport function localeName(code: string): string {\n const exact = COMMON_LOCALES.find((l) => l.code.toLowerCase() === code.toLowerCase());\n if (exact) return exact.name;\n const base = COMMON_LOCALES.find((l) => l.code.toLowerCase() === baseLanguage(code));\n return base ? `${base.name} (${code})` : code;\n}\n\n/** `fr_FR` / `FR-fr` → `fr-FR`; script subtags keep title case (`zh-hans` → `zh-Hans`). Invalid input → \"\". */\nexport function normalizeLocale(input: unknown): string {\n if (typeof input !== \"string\") return \"\";\n const parts = input.trim().replace(/_/g, \"-\").split(\"-\").filter(Boolean);\n if (!parts.length || !/^[a-zA-Z]{2,3}$/.test(parts[0]!)) return \"\";\n return parts\n .slice(0, 3)\n .map((p, i) => (i === 0 ? p.toLowerCase() : p.length === 4 ? p[0]!.toUpperCase() + p.slice(1).toLowerCase() : p.length === 2 ? p.toUpperCase() : p))\n .join(\"-\");\n}\n\nexport function baseLanguage(locale: string): string {\n return normalizeLocale(locale).split(\"-\")[0] ?? \"\";\n}\n\n/**\n * Picks the language to show: for each requested locale in order, an exact match among\n * `available`, else one sharing its base language (`fr-CA` → `fr`, `fr` → `fr-FR`). Falls back to\n * `defaultLocale`. Matching ignores case.\n */\nexport function resolveLocale(requested: ReadonlyArray<string | null | undefined>, available: readonly string[], defaultLocale: string = DEFAULT_LOCALE): string {\n const def = normalizeLocale(defaultLocale) || DEFAULT_LOCALE;\n const avail = available.map(normalizeLocale).filter(Boolean);\n const all = [def, ...avail.filter((a) => a.toLowerCase() !== def.toLowerCase())];\n for (const raw of requested) {\n const want = normalizeLocale(raw);\n if (!want) continue;\n const exact = all.find((a) => a.toLowerCase() === want.toLowerCase());\n if (exact) return exact;\n const base = baseLanguage(want);\n const sameBase = all.find((a) => a.toLowerCase() === base) ?? all.find((a) => baseLanguage(a) === base);\n if (sameBase) return sameBase;\n }\n return def;\n}\n\n/** Locale candidates for a visitor: explicit option, traits (`language`, `locale`), then the platform's languages. */\nexport function visitorLocales(explicit: string | null | undefined, traits: Record<string, unknown> | null | undefined, platform: ReadonlyArray<string | null | undefined> = []): string[] {\n const out: string[] = [];\n const push = (v: unknown) => {\n const n = normalizeLocale(v);\n if (n && !out.includes(n)) out.push(n);\n };\n push(explicit);\n push(traits?.language);\n push(traits?.locale);\n for (const p of platform) push(p);\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Guides\n// ---------------------------------------------------------------------------\n\n/** Every translatable text in a guide config, in display order. Empty texts are skipped. */\nexport function guideTextEntries(config: Pick<GuideConfig, \"steps\" | \"checklist\" | \"survey\">): TextEntry[] {\n const out: TextEntry[] = [];\n const add = (key: string, source: string | undefined | null, kind: TextKind, label: string) => {\n if (source && source.trim()) out.push({ key, source, kind, label });\n };\n config.steps.forEach((s, i) => {\n const at = `Step ${i + 1}`;\n add(`steps.${s.id}.title`, s.title, \"text\", `${at} · Title`);\n add(`steps.${s.id}.body`, s.body, \"html\", `${at} · Body`);\n add(`steps.${s.id}.customHtml`, s.customHtml, \"html\", `${at} · Custom HTML`);\n add(`steps.${s.id}.imageAlt`, s.imageAlt, \"text\", `${at} · Image description`);\n s.buttons.forEach((b) => add(`steps.${s.id}.buttons.${b.id}.label`, b.label, \"text\", `${at} · Button “${b.label}”`));\n });\n const c = config.checklist;\n if (c) {\n add(\"checklist.launcherLabel\", c.launcherLabel, \"text\", \"Checklist · Launcher label\");\n add(\"checklist.completionTitle\", c.completionTitle, \"text\", \"Checklist · Completion title\");\n add(\"checklist.completionBody\", c.completionBody, \"html\", \"Checklist · Completion message\");\n c.tasks.forEach((t, i) => {\n add(`checklist.tasks.${t.id}.title`, t.title, \"text\", `Task ${i + 1} · Title`);\n add(`checklist.tasks.${t.id}.description`, t.description, \"html\", `Task ${i + 1} · Description`);\n });\n }\n const sv = config.survey;\n if (sv) {\n sv.questions.forEach((q, i) => {\n const at = `Question ${i + 1}`;\n add(`survey.questions.${q.id}.title`, q.title, \"text\", `${at} · Question`);\n add(`survey.questions.${q.id}.description`, q.description, \"text\", `${at} · Description`);\n add(`survey.questions.${q.id}.placeholder`, q.placeholder, \"text\", `${at} · Placeholder`);\n add(`survey.questions.${q.id}.lowLabel`, q.lowLabel, \"text\", `${at} · Low label`);\n add(`survey.questions.${q.id}.highLabel`, q.highLabel, \"text\", `${at} · High label`);\n q.options.forEach((o) => add(`survey.questions.${q.id}.options.${o.id}.label`, o.label, \"text\", `${at} · Option “${o.label}”`));\n });\n add(\"survey.thankYouTitle\", sv.thankYouTitle, \"text\", \"Survey · Thank-you title\");\n add(\"survey.thankYouBody\", sv.thankYouBody, \"html\", \"Survey · Thank-you message\");\n }\n return out;\n}\n\n/** Locales a guide has any translation for. */\nexport function guideLocales(config: Pick<GuideConfig, \"localization\">): string[] {\n const t = config.localization?.translations ?? {};\n return Object.keys(t).filter((l) => Object.values(t[l] ?? {}).some((v) => typeof v === \"string\" && v.trim() !== \"\"));\n}\n\nfunction pick(map: Record<string, string> | undefined, key: string, fallback: string): string;\nfunction pick(map: Record<string, string> | undefined, key: string, fallback: string | undefined): string | undefined;\nfunction pick(map: Record<string, string> | undefined, key: string, fallback: string | undefined): string | undefined {\n const v = map?.[key];\n return typeof v === \"string\" && v.trim() !== \"\" ? v : fallback;\n}\n\n/** The config with one language's translations applied (untranslated texts keep the default language). */\nexport function applyGuideTranslations<C extends Pick<GuideConfig, \"steps\" | \"checklist\" | \"survey\">>(config: C, map: Record<string, string> | undefined): C {\n if (!map || !Object.keys(map).length) return config;\n return {\n ...config,\n steps: config.steps.map((s) => ({\n ...s,\n title: pick(map, `steps.${s.id}.title`, s.title),\n body: pick(map, `steps.${s.id}.body`, s.body),\n customHtml: pick(map, `steps.${s.id}.customHtml`, s.customHtml),\n imageAlt: pick(map, `steps.${s.id}.imageAlt`, s.imageAlt),\n buttons: s.buttons.map((b) => ({ ...b, label: pick(map, `steps.${s.id}.buttons.${b.id}.label`, b.label) })),\n })),\n checklist: config.checklist\n ? {\n ...config.checklist,\n launcherLabel: pick(map, \"checklist.launcherLabel\", config.checklist.launcherLabel),\n completionTitle: pick(map, \"checklist.completionTitle\", config.checklist.completionTitle),\n completionBody: pick(map, \"checklist.completionBody\", config.checklist.completionBody),\n tasks: config.checklist.tasks.map((t) => ({ ...t, title: pick(map, `checklist.tasks.${t.id}.title`, t.title), description: pick(map, `checklist.tasks.${t.id}.description`, t.description) })),\n }\n : config.checklist,\n survey: config.survey\n ? {\n ...config.survey,\n thankYouTitle: pick(map, \"survey.thankYouTitle\", config.survey.thankYouTitle),\n thankYouBody: pick(map, \"survey.thankYouBody\", config.survey.thankYouBody),\n questions: config.survey.questions.map((q) => ({\n ...q,\n title: pick(map, `survey.questions.${q.id}.title`, q.title),\n description: pick(map, `survey.questions.${q.id}.description`, q.description),\n placeholder: pick(map, `survey.questions.${q.id}.placeholder`, q.placeholder),\n lowLabel: pick(map, `survey.questions.${q.id}.lowLabel`, q.lowLabel),\n highLabel: pick(map, `survey.questions.${q.id}.highLabel`, q.highLabel),\n options: q.options.map((o) => ({ ...o, label: pick(map, `survey.questions.${q.id}.options.${o.id}.label`, o.label) })),\n })),\n }\n : config.survey,\n };\n}\n\n/**\n * The guide as a visitor speaking `requested` should see it, with `locale` set to the language\n * chosen (the default language when none of the guide's translations match).\n */\nexport function localizeGuide(guide: PublishedGuide, requested: readonly string[], defaultLocale: string = DEFAULT_LOCALE): PublishedGuide & { locale: string } {\n const translations = guide.config.localization?.translations ?? {};\n const locale = resolveLocale(requested, guideLocales(guide.config), defaultLocale);\n const key = Object.keys(translations).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());\n if (!key) return { ...guide, locale };\n return { ...guide, locale, config: applyGuideTranslations(guide.config, translations[key]) };\n}\n\nexport interface TranslationCoverage {\n locale: string;\n total: number;\n translated: number;\n /** Keys with no translation. */\n missing: string[];\n /** Keys whose translation exists but whose key no longer matches any text (stale). */\n stale: string[];\n}\n\nexport function translationCoverage(entries: readonly TextEntry[], map: Record<string, string> | undefined, locale: string): TranslationCoverage {\n const keys = new Set(entries.map((e) => e.key));\n const missing = entries.filter((e) => !pick(map, e.key, undefined)).map((e) => e.key);\n const stale = Object.keys(map ?? {}).filter((k) => !keys.has(k) && (map?.[k] ?? \"\").trim() !== \"\");\n return { locale, total: entries.length, translated: entries.length - missing.length, missing, stale };\n}\n\n// ---------------------------------------------------------------------------\n// Resource center\n// ---------------------------------------------------------------------------\n\n/** Translations carried by the published resource center (texts other than articles and announcements). */\nexport type ResourceCenterTranslations = Record<string, Record<string, string>>;\n\n/** Translatable resource-center texts (title, launcher label, links, FAQs, collections). */\nexport function resourceCenterTextEntries(rc: Pick<ResourceCenterConfig, \"title\" | \"launcher\" | \"links\" | \"faqs\" | \"collections\">): TextEntry[] {\n const out: TextEntry[] = [];\n const add = (key: string, source: string | undefined | null, kind: TextKind, label: string) => {\n if (source && source.trim()) out.push({ key, source, kind, label });\n };\n add(\"title\", rc.title, \"text\", \"Title\");\n add(\"launcher.label\", rc.launcher?.label, \"text\", \"Launcher label\");\n rc.collections.forEach((c) => {\n add(`collections.${c.id}.name`, c.name, \"text\", `Collection “${c.name}”`);\n add(`collections.${c.id}.description`, c.description, \"text\", `Collection “${c.name}” · Description`);\n });\n rc.links.forEach((l) => add(`links.${l.id}.label`, l.label, \"text\", `Link “${l.label}”`));\n rc.faqs.forEach((f, i) => {\n add(`faqs.${f.id}.question`, f.question, \"text\", `FAQ ${i + 1} · Question`);\n add(`faqs.${f.id}.answer`, f.answer, \"html\", `FAQ ${i + 1} · Answer`);\n });\n return out;\n}\n\n/** Article texts, keyed `title` / `summary` / `body`. */\nexport function articleTextEntries(a: { title: string; summary?: string | null; body?: string | null }): TextEntry[] {\n const out: TextEntry[] = [];\n if (a.title.trim()) out.push({ key: \"title\", source: a.title, kind: \"text\", label: \"Title\" });\n if (a.summary?.trim()) out.push({ key: \"summary\", source: a.summary, kind: \"text\", label: \"Summary\" });\n if (a.body?.trim()) out.push({ key: \"body\", source: a.body, kind: \"html\", label: \"Body\" });\n return out;\n}\n\n/** Locales the resource center offers (its own strings, articles or announcements). */\nexport function resourceCenterLocales(rc: ResourceCenterConfig): string[] {\n const set = new Set<string>(Object.keys(rc.translations ?? {}));\n for (const a of rc.articles) for (const l of Object.keys(a.translations ?? {})) set.add(l);\n for (const a of rc.announcements ?? []) for (const l of Object.keys(a.translations ?? {})) set.add(l);\n return [...set];\n}\n\nfunction translationFor<T>(map: Record<string, T> | undefined, locale: string): T | undefined {\n if (!map) return undefined;\n const key = Object.keys(map).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());\n return key ? map[key] : undefined;\n}\n\nexport function localizeArticle(a: ResourceCenterArticle, locale: string): ResourceCenterArticle {\n const t = translationFor(a.translations, locale);\n if (!t) return a;\n const body = t.body?.trim() ? t.body : a.body;\n // A translated body that was left out of the snapshot is fetched with `?locale=`.\n return { ...a, title: t.title?.trim() ? t.title : a.title, summary: t.summary?.trim() ? t.summary : a.summary, body, ...(t.bodyOmitted ? { bodyOmitted: true } : {}) };\n}\n\nexport function localizeAnnouncement(a: ResourceCenterAnnouncement, locale: string): ResourceCenterAnnouncement {\n const t = translationFor(a.translations, locale);\n if (!t) return a;\n return { ...a, title: t.title?.trim() ? t.title : a.title, body: t.body?.trim() ? t.body : a.body };\n}\n\n/** The resource center in the visitor's language (with `locale` = the language chosen). */\nexport function localizeResourceCenter(rc: ResourceCenterConfig, requested: readonly string[], defaultLocale: string = DEFAULT_LOCALE): ResourceCenterConfig & { locale: string } {\n const locale = resolveLocale(requested, resourceCenterLocales(rc), defaultLocale);\n if (locale.toLowerCase() === normalizeLocale(defaultLocale).toLowerCase()) return { ...rc, locale };\n const map = translationFor(rc.translations, locale);\n return {\n ...rc,\n locale,\n title: pick(map, \"title\", rc.title),\n launcher: { ...rc.launcher, label: pick(map, \"launcher.label\", rc.launcher.label) },\n collections: rc.collections.map((c) => ({ ...c, name: pick(map, `collections.${c.id}.name`, c.name), description: pick(map, `collections.${c.id}.description`, c.description) })),\n links: rc.links.map((l) => ({ ...l, label: pick(map, `links.${l.id}.label`, l.label) })),\n faqs: rc.faqs.map((f) => ({ ...f, question: pick(map, `faqs.${f.id}.question`, f.question), answer: pick(map, `faqs.${f.id}.answer`, f.answer) })),\n articles: rc.articles.map((a) => localizeArticle(a, locale)),\n announcements: rc.announcements?.map((a) => localizeAnnouncement(a, locale)),\n };\n}\n","/**\n * Guide A/B tests (zod-free; shared by the server, the web SDK and the mobile SDK ports).\n *\n * Each visitor falls into a bucket 0–99: `rolloutBucket(userId || anonymousId, salt)` (FNV-1a,\n * see utils.ts), with `salt = experimentSalt(experimentId)`. Variants own consecutive bucket ranges\n * in their listed order, sized by their integer weights (which sum to 100). The server folds each\n * variant's range into the targeting it serves as two `experiment.bucket` rules, so every SDK\n * applies the split with the rule engine it already has, and assignment is the same everywhere:\n * the server's `assignGuideVariant` and an SDK evaluating the served rules always agree.\n */\nimport { rolloutBucket } from \"./utils\";\nimport type { Rule, RuleGroup } from \"./targeting-eval\";\n\n/** The \"no guide\" variant: visitors in it see nothing, and are measured against the guide variants. */\nexport const CONTROL_VARIANT_ID = \"control\";\n\nexport const GUIDE_EXPERIMENT_STATUSES = [\"draft\", \"running\", \"completed\"] as const;\nexport type GuideExperimentStatus = (typeof GUIDE_EXPERIMENT_STATUSES)[number];\n\nexport const GUIDE_EXPERIMENT_GOALS = [\"guide_completed\", \"event\", \"page_visit\", \"click_text\"] as const;\nexport type GuideExperimentGoalKind = (typeof GUIDE_EXPERIMENT_GOALS)[number];\n\nexport const GUIDE_EXPERIMENT_GOAL_LABELS: Record<GuideExperimentGoalKind, string> = {\n guide_completed: \"Completes the guide\",\n event: \"Tracks an event\",\n page_visit: \"Visits a page\",\n click_text: \"Clicks an element with text\",\n};\n\nexport interface GuideExperimentGoal {\n kind: GuideExperimentGoalKind;\n /** Event name, page path pattern (`/billing/*`) or click text, depending on `kind`. */\n value?: string;\n}\n\nexport interface GuideExperimentVariant {\n id: string;\n name: string;\n /** The guide shown to this variant; null for the control group (no guide). */\n guideId: string | null;\n /** Share of visitors, a whole percentage; all weights sum to 100. */\n weight: number;\n}\n\nexport function experimentSalt(experimentId: string): string {\n return `gx:${experimentId}`;\n}\n\n/** Bucket ranges `[from, to)` per variant, in order. */\nexport function variantRanges(variants: ReadonlyArray<Pick<GuideExperimentVariant, \"id\" | \"weight\">>): Array<{ id: string; from: number; to: number }> {\n let at = 0;\n return variants.map((v) => {\n const from = at;\n at = Math.min(100, at + Math.max(0, Math.round(v.weight)));\n return { id: v.id, from, to: at };\n });\n}\n\n/** The variant a visitor is in, or null when weights leave their bucket unassigned. */\nexport function assignGuideVariant(variants: ReadonlyArray<Pick<GuideExperimentVariant, \"id\" | \"weight\">>, experimentId: string, subject: string): string | null {\n const bucket = rolloutBucket(subject, experimentSalt(experimentId));\n return variantRanges(variants).find((r) => bucket >= r.from && bucket < r.to)?.id ?? null;\n}\n\n/** Rules restricting targeting to bucket range `[from, to)` of `salt`. */\nexport function experimentBucketRules(salt: string, from: number, to: number): Rule[] {\n return [\n { id: \"experiment-from\", field: \"experiment.bucket\", key: salt, op: \"gte\", value: from },\n { id: \"experiment-to\", field: \"experiment.bucket\", key: salt, op: \"lt\", value: to },\n ];\n}\n\n/** Targeting with a variant's bucket range folded in (an SDK without `experiment.bucket` shows the guide to nobody). */\nexport function withExperimentBucket(targeting: RuleGroup, salt: string, from: number, to: number): RuleGroup {\n return { id: \"experiment\", op: \"and\", rules: [...experimentBucketRules(salt, from, to), targeting] };\n}\n\n/** Problems with a variant list; empty when it can run. */\nexport function variantProblems(variants: ReadonlyArray<GuideExperimentVariant>): string[] {\n const problems: string[] = [];\n if (variants.length < 2) problems.push(\"An A/B test needs at least two variants.\");\n if (variants.length > 5) problems.push(\"An A/B test can have at most five variants.\");\n const guides = variants.filter((v) => v.guideId);\n if (guides.length === 0) problems.push(\"At least one variant must show a guide.\");\n if (variants.filter((v) => !v.guideId).length > 1) problems.push(\"Only one variant can be the control group (no guide).\");\n if (new Set(guides.map((v) => v.guideId)).size !== guides.length) problems.push(\"Each variant needs its own guide.\");\n if (new Set(variants.map((v) => v.id)).size !== variants.length) problems.push(\"Variant ids must be unique.\");\n if (variants.some((v) => !Number.isInteger(v.weight) || v.weight < 1)) problems.push(\"Every variant needs a whole-number share of at least 1%.\");\n const total = variants.reduce((s, v) => s + v.weight, 0);\n if (total !== 100) problems.push(`Traffic shares must add up to 100% (now ${total}%).`);\n return problems;\n}\n\n/** Splits 100% as evenly as possible across `n` variants (first ones get the remainder). */\nexport function evenWeights(n: number): number[] {\n if (n <= 0) return [];\n const base = Math.floor(100 / n);\n return Array.from({ length: n }, (_, i) => base + (i < 100 - base * n ? 1 : 0));\n}\n","/**\n * Custom CSS for guides and themes (zod-free; the server sanitizes on save, the web runtime\n * sanitizes again and scopes before injecting).\n *\n * Guides render inside the SDK's Shadow DOM, so page styles and guide styles never mix. Within the\n * shadow root, every rule is additionally prefixed with the guide's own container selector, so one\n * guide's CSS can't restyle another guide, the resource center or the messenger. Sanitizing removes\n * what could reach outside the container or load anything: `@import`, `:host` / `::slotted` rules,\n * `url()`s other than https images and `data:image/…`, legacy script hooks (`expression()`,\n * `behavior`, `-moz-binding`, `javascript:`) and any markup.\n */\n\nexport const MAX_CUSTOM_CSS = 20000;\n\nconst BLOCKED_AT_RULES = /^@(import|charset|namespace|document|-moz-document)\\b/i;\nconst ALLOWED_AT_RULES = /^@(media|supports|container|layer|keyframes|-webkit-keyframes|font-face)\\b/i;\n\ninterface Block {\n /** Selector or at-rule prelude; \"\" for a bare declaration list. */\n prelude: string;\n /** Declarations (for rules) or nested CSS (for grouping at-rules). */\n body: string;\n}\n\n/** Splits CSS into top-level `prelude { body }` blocks, respecting strings and nesting. Statements without a block are dropped. */\nfunction splitBlocks(css: string): Block[] {\n const out: Block[] = [];\n let i = 0;\n const n = css.length;\n while (i < n) {\n let prelude = \"\";\n let quote: string | null = null;\n while (i < n) {\n const ch = css[i]!;\n if (quote) {\n prelude += ch;\n if (ch === \"\\\\\") prelude += css[++i] ?? \"\";\n else if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n prelude += ch;\n } else if (ch === \"{\") break;\n else if (ch === \";\") {\n prelude = \"\"; // a statement (e.g. @import) – dropped\n } else if (ch === \"}\") {\n prelude = \"\"; // stray brace\n } else prelude += ch;\n i++;\n }\n if (i >= n) break;\n // css[i] === \"{\"\n i++;\n let depth = 1;\n let body = \"\";\n quote = null;\n while (i < n && depth > 0) {\n const ch = css[i]!;\n if (quote) {\n body += ch;\n if (ch === \"\\\\\") body += css[++i] ?? \"\";\n else if (ch === quote) quote = null;\n } else if (ch === '\"' || ch === \"'\") {\n quote = ch;\n body += ch;\n } else if (ch === \"{\") {\n depth++;\n body += ch;\n } else if (ch === \"}\") {\n depth--;\n if (depth > 0) body += ch;\n } else body += ch;\n i++;\n }\n out.push({ prelude: prelude.trim(), body });\n }\n return out;\n}\n\n/** Splits a selector list on top-level commas. */\nfunction splitSelectors(list: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let cur = \"\";\n for (const ch of list) {\n if (ch === \"(\" || ch === \"[\") depth++;\n else if (ch === \")\" || ch === \"]\") depth = Math.max(0, depth - 1);\n if (ch === \",\" && depth === 0) {\n out.push(cur.trim());\n cur = \"\";\n } else cur += ch;\n }\n if (cur.trim()) out.push(cur.trim());\n return out;\n}\n\nfunction safeUrl(raw: string): boolean {\n const u = raw.trim().replace(/^['\"]|['\"]$/g, \"\").trim();\n return /^https:\\/\\//i.test(u) || /^data:image\\/(png|jpe?g|gif|webp|svg\\+xml)[;,]/i.test(u);\n}\n\n/** Cleans one declaration list. */\nfunction cleanDeclarations(body: string): string {\n return body\n .replace(/url\\(([^)]*)\\)/gi, (m, inner: string) => (safeUrl(inner) ? m : \"none\"))\n .replace(/expression\\s*\\(/gi, \"(\")\n .replace(/javascript\\s*:/gi, \"\")\n .replace(/(^|[;{\\s])(-moz-binding|behavior)\\s*:[^;]*;?/gi, \"$1\")\n .replace(/[{}]/g, \"\")\n .trim();\n}\n\n/** Removes everything unsafe; keeps the rule structure. */\nexport function sanitizeCustomCss(input: string | null | undefined): string {\n if (!input) return \"\";\n let css = String(input).slice(0, MAX_CUSTOM_CSS);\n css = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/<(script|style)\\b[^>]*>[\\s\\S]*?<\\/\\1\\s*>/gi, \"\").replace(/<\\/?[a-z!][^>]*>/gi, \"\").replace(/</g, \"\");\n return render(splitBlocks(css), 0);\n}\n\nfunction render(blocks: Block[], depth: number): string {\n const parts: string[] = [];\n for (const b of blocks) {\n if (!b.prelude) continue;\n if (b.prelude.startsWith(\"@\")) {\n if (BLOCKED_AT_RULES.test(b.prelude) || !ALLOWED_AT_RULES.test(b.prelude)) continue;\n if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) {\n // Keyframe selectors (from/to/50%) and font-face descriptors are declarations-like.\n const inner = /^@font-face/i.test(b.prelude) ? cleanDeclarations(b.body) : splitBlocks(b.body).map((k) => `${k.prelude}{${cleanDeclarations(k.body)}}`).join(\"\");\n parts.push(`${b.prelude}{${inner}}`);\n } else if (depth < 3) parts.push(`${b.prelude}{${render(splitBlocks(b.body), depth + 1)}}`);\n continue;\n }\n const selectors = splitSelectors(b.prelude).filter((s) => !/:host|::slotted|::part/i.test(s));\n if (!selectors.length) continue;\n parts.push(`${selectors.join(\",\")}{${cleanDeclarations(b.body)}}`);\n }\n return parts.join(\"\\n\");\n}\n\n/**\n * Prefixes every selector with `scope` (e.g. `.g-scope[data-guide=\"abc\"]`). `:root`, `html`,\n * `body`, `:scope` and `&` at the start of a selector refer to the container itself.\n */\nexport function scopeCustomCss(css: string, scope: string): string {\n return scopeBlocks(splitBlocks(sanitizeCustomCss(css)), scope, 0);\n}\n\nfunction scopeBlocks(blocks: Block[], scope: string, depth: number): string {\n const parts: string[] = [];\n for (const b of blocks) {\n if (b.prelude.startsWith(\"@\")) {\n if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) parts.push(`${b.prelude}{${b.body}}`);\n else if (depth < 3) parts.push(`${b.prelude}{${scopeBlocks(splitBlocks(b.body), scope, depth + 1)}}`);\n continue;\n }\n const sels = splitSelectors(b.prelude).map((s) => {\n const self = s.match(/^(:root|html|body|:scope|&)(?![\\w-])(.*)$/i);\n if (self) return `${scope}${self[2] ?? \"\"}`;\n return `${scope} ${s}`;\n });\n parts.push(`${sels.join(\",\")}{${b.body}}`);\n }\n return parts.join(\"\\n\");\n}\n","/**\n * Translation exchange files: XLIFF 1.2 (what translation tools and agencies expect) and CSV (for\n * spreadsheets). Both carry one target language; units are identified by their translation key.\n * Import reads XLIFF 1.2 and 2.x (`<trans-unit>` / `<unit>`) and CSVs with a `key` column plus a\n * `target` (or locale-named) column.\n */\n\nexport interface TranslationUnit {\n key: string;\n source: string;\n target: string;\n /** Where the text appears, for translators. */\n note?: string;\n}\n\nexport interface ParsedTranslations {\n targetLocale?: string;\n /** key → translated text (empty translations are left out). */\n entries: Record<string, string>;\n}\n\nfunction xmlEscape(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n}\n\nfunction xmlUnescape(s: string): string {\n return s\n .replace(/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>/g, (_, c: string) => c.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\"))\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&#(\\d+);/g, (_, d: string) => String.fromCodePoint(Number(d)))\n .replace(/&#x([0-9a-f]+);/gi, (_, h: string) => String.fromCodePoint(parseInt(h, 16)))\n .replace(/&amp;/g, \"&\");\n}\n\nexport function toXliff(units: readonly TranslationUnit[], opts: { sourceLocale: string; targetLocale: string; original: string }): string {\n const body = units\n .map(\n (u) =>\n ` <trans-unit id=\"${xmlEscape(u.key)}\">\\n <source>${xmlEscape(u.source)}</source>\\n <target${u.target ? \"\" : ' state=\"needs-translation\"'}>${xmlEscape(u.target)}</target>${u.note ? `\\n <note>${xmlEscape(u.note)}</note>` : \"\"}\\n </trans-unit>`,\n )\n .join(\"\\n\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<xliff version=\"1.2\" xmlns=\"urn:oasis:names:tc:xliff:document:1.2\">\\n <file original=\"${xmlEscape(opts.original)}\" source-language=\"${xmlEscape(opts.sourceLocale)}\" target-language=\"${xmlEscape(opts.targetLocale)}\" datatype=\"html\">\\n <body>\\n${body}\\n </body>\\n </file>\\n</xliff>\\n`;\n}\n\nexport function parseXliff(xml: string): ParsedTranslations {\n const target = xml.match(/target-language=\"([^\"]+)\"/)?.[1] ?? xml.match(/\\btrgLang=\"([^\"]+)\"/)?.[1];\n const entries: Record<string, string> = {};\n for (const m of xml.matchAll(/<(trans-unit|unit)\\b[^>]*\\bid=\"([^\"]*)\"[^>]*>([\\s\\S]*?)<\\/\\1>/g)) {\n const key = xmlUnescape(m[2]!);\n const t = m[3]!.match(/<target\\b[^>]*>([\\s\\S]*?)<\\/target>/);\n const text = t ? xmlUnescape(t[1]!) : \"\";\n if (key && text.trim()) entries[key] = text;\n }\n return { targetLocale: target ? xmlUnescape(target) : undefined, entries };\n}\n\nfunction csvCell(s: string): string {\n return /[\",\\n\\r]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\n}\n\n/** CSV with columns key, context, source, <targetLocale>. */\nexport function toTranslationCsv(units: readonly TranslationUnit[], targetLocale: string): string {\n const rows = [[\"key\", \"context\", \"source\", targetLocale], ...units.map((u) => [u.key, u.note ?? \"\", u.source, u.target])];\n return rows.map((r) => r.map(csvCell).join(\",\")).join(\"\\r\\n\") + \"\\r\\n\";\n}\n\n/** RFC 4180 CSV parsing (quoted fields, doubled quotes, CRLF/LF). */\nexport function parseCsvRows(text: string): string[][] {\n const rows: string[][] = [];\n let row: string[] = [];\n let cell = \"\";\n let quoted = false;\n const src = text.replace(/^\\uFEFF/, \"\");\n for (let i = 0; i < src.length; i++) {\n const ch = src[i]!;\n if (quoted) {\n if (ch === '\"') {\n if (src[i + 1] === '\"') {\n cell += '\"';\n i++;\n } else quoted = false;\n } else cell += ch;\n } else if (ch === '\"') quoted = true;\n else if (ch === \",\") {\n row.push(cell);\n cell = \"\";\n } else if (ch === \"\\n\" || ch === \"\\r\") {\n if (ch === \"\\r\" && src[i + 1] === \"\\n\") i++;\n row.push(cell);\n rows.push(row);\n row = [];\n cell = \"\";\n } else cell += ch;\n }\n if (cell !== \"\" || row.length) {\n row.push(cell);\n rows.push(row);\n }\n return rows.filter((r) => r.some((c) => c.trim() !== \"\"));\n}\n\n/** Reads a translation CSV: the `key` column and the `target` column, else the last column not named key/context/source/label. */\nexport function parseTranslationCsv(text: string): ParsedTranslations {\n const [header, ...rows] = parseCsvRows(text);\n if (!header) return { entries: {} };\n const names = header.map((h) => h.trim());\n const lower = names.map((h) => h.toLowerCase());\n const keyCol = lower.indexOf(\"key\");\n if (keyCol < 0) return { entries: {} };\n let targetCol = lower.indexOf(\"target\");\n if (targetCol < 0) {\n for (let i = names.length - 1; i >= 0; i--) {\n if (![\"key\", \"context\", \"source\", \"label\", \"note\"].includes(lower[i]!)) {\n targetCol = i;\n break;\n }\n }\n }\n if (targetCol < 0) return { entries: {} };\n const entries: Record<string, string> = {};\n for (const r of rows) {\n const key = (r[keyCol] ?? \"\").trim();\n const value = r[targetCol] ?? \"\";\n if (key && value.trim()) entries[key] = value;\n }\n return { targetLocale: lower[targetCol] === \"target\" ? undefined : names[targetCol], entries };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["id","import_zod","import_zod","str","import_zod","import_zod","import_zod","import_zod","import_zod","import_zod","id","id","has","id","import_zod","words","words","pick","id","quoted","re","quoted"]}