@mrrocket/sdk 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,10 +2,18 @@
2
2
 
3
3
  All notable changes to this package. It follows semantic versioning; before 1.0 a minor version may change an API.
4
4
 
5
+ ## 0.23.0 (not published yet)
6
+
7
+ - `setConsent("off")` (or the `consent` prop turning off) while someone is signed in sends one `$consent_off` with their id and nothing else. MRRocket stores no event for it: it marks the person, so lists by rule stop sorting them by what they do. Anonymous visitors send nothing, as before.
8
+
5
9
  ## 0.22.0 (not published yet)
6
10
 
7
11
  - **Onboarding in your own code (web, script tag and React Native):** `useOnboardingReport(name, { order, type })` (script tag `mrrocket.onboarding.report(name, options)`) with `saw(step, title)`, `answered(question, answer, label)`, `done(step)` and `closed(step)`. Nothing to set up in MRRocket: the first report makes the item under Onboarding, marked "From your code". MRRocket shows who saw each step and what they answered, and keeps the answers on the contact. It follows the visitor's consent like any other event.
8
12
  - `useOnboarding(id)` for items already drawn by the app keeps working.
13
+ - **The messenger opens with what it knows (web and script tag):** a visitor's conversations and the Help and Updates tabs show at once from what the browser kept for that visitor, and the read brings them up to date. Home has no grey bar any more: what is still coming shows as the shape of its rows, and a tab appears only once there is something in it, so none shows and then goes away.
14
+ - **The AI agent is named beside its answers (web, script tag and React Native):** an answer shows "Cass · AI agent" under it instead of a line at the end of its text. A custom agent name always keeps "AI agent" beside it. Older versions of the SDK keep the line.
15
+ - **A slow or failed read of the chat is asked again soon** instead of at the panel's next 30 s turn, and whoever signs in after the page loaded gets their conversations at once.
16
+ - **A message the team takes back leaves the count and the preview too (web, script tag and React Native):** an open chat already drops it at the next read, on any version; the launcher's count and preview card now do as well.
9
17
  - Version reported in event batches: `0.22.0`.
10
18
 
11
19
  ## 0.21.0 (not published yet, together with 0.20.0)
@@ -230,6 +230,16 @@ export interface ChatThread {
230
230
  /** The visitor gave an email already: the messenger stops asking. */
231
231
  hasEmail: boolean;
232
232
  }
233
+ /**
234
+ * For the count and the preview of unread answers, after a read: an answer the team took back and a conversation it
235
+ * archived leave them. Of a conversation that is not on screen the list brings only the newest message, so an answer
236
+ * newer than that one is gone.
237
+ */
238
+ export declare const stillThere: (t: ChatThread, chats: ChatSummary[]) => (m: {
239
+ id: string;
240
+ at: string;
241
+ chat: string;
242
+ }) => boolean;
233
243
  export declare class ApiError extends Error {
234
244
  status: number;
235
245
  constructor(message: string, status: number);
@@ -282,7 +292,10 @@ export declare const createApi: (c: Conn) => {
282
292
  completed: boolean;
283
293
  seconds: number;
284
294
  }) => Promise<unknown>;
285
- /** One chat by id, else the visitor's newest; `conversations` lists them all. */
295
+ /**
296
+ * One chat by id, else the visitor's newest; `conversations` lists them all. `aiLabel`: the messenger says "AI agent"
297
+ * beside an answer's name, so the answer comes without its AI notice line (from 0.22.0).
298
+ */
286
299
  chat: (signal?: AbortSignal, conversation?: string) => Promise<ChatThread>;
287
300
  /**
288
301
  * A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). `conversation` is
@@ -34,6 +34,11 @@ var inkOn = (hex) => {
34
34
  });
35
35
  return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.45 ? "#111214" : "#ffffff";
36
36
  };
37
+ var stillThere = (t2, chats) => (m) => {
38
+ if (m.chat === t2.conversation?.id) return t2.messages.some((x) => x.id === m.id);
39
+ const last = chats.find((c) => c.id === m.chat)?.last;
40
+ return !!last && m.at <= last.at;
41
+ };
37
42
  var ApiError = class extends Error {
38
43
  status;
39
44
  constructor(message, status) {
@@ -87,13 +92,16 @@ var createApi = (c) => {
87
92
  survey: (url, signal) => call(`${base}/surveys?${qs({ ...me, url })}`, void 0, signal),
88
93
  seen: (id) => post(`/surveys/${encodeURIComponent(id)}/seen`, { user: void 0 }),
89
94
  respond: (id, r) => post(`/surveys/${encodeURIComponent(id)}/respond`, r),
90
- /** One chat by id, else the visitor's newest; `conversations` lists them all. */
91
- chat: (signal, conversation) => call(`${base}/messages?${qs({ ...me, conversation })}`, void 0, signal),
95
+ /**
96
+ * One chat by id, else the visitor's newest; `conversations` lists them all. `aiLabel`: the messenger says "AI agent"
97
+ * beside an answer's name, so the answer comes without its AI notice line (from 0.22.0).
98
+ */
99
+ chat: (signal, conversation) => call(`${base}/messages?${qs({ ...me, conversation, aiLabel: "1" })}`, void 0, signal),
92
100
  /**
93
101
  * A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). `conversation` is
94
102
  * the chat it answers, or "new" to start one; without it, the running chat or else a new one.
95
103
  */
96
- sendChat: (m) => post("/messages", m),
104
+ sendChat: (m) => post("/messages", { ...m, aiLabel: true }),
97
105
  /** Uploads one picked file for the next message (pictures and PDFs, at most 10 MB); answers its upload id. */
98
106
  uploadChatFile: (file, signal) => {
99
107
  const form = new FormData();
@@ -122,6 +130,7 @@ export {
122
130
  STATUS_LABEL,
123
131
  createApi,
124
132
  inkOn,
125
- replyLine
133
+ replyLine,
134
+ stillThere
126
135
  };
127
136
  //# sourceMappingURL=api-client.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api-client.ts"],"sourcesContent":["/**\n * The SDK's fetch client and the shapes it reads, without React, so the script tag's widgets (src/script) use it too.\n * `./api` re-exports all of it with the `useApi` hook.\n */\nimport { warnUnsigned } from \"./identity\";\nimport { currentLocale, t } from \"./i18n\";\n\nexport type PostStatus = \"review\" | \"planned\" | \"progress\" | \"shipped\";\n\n/** Read at the moment it is shown, so it follows the visitor's language. */\nexport const STATUS_LABEL: Record<PostStatus, string> = {\n get review() {\n return t(\"Under review\");\n },\n get planned() {\n return t(\"Planned\");\n },\n get progress() {\n return t(\"In progress\");\n },\n get shipped() {\n return t(\"Shipped\");\n },\n};\n\nexport interface FeedbackBoardInfo {\n id: string;\n label: string;\n}\n\nexport interface FeedbackPost {\n id: string;\n title: string;\n body: string;\n board: string;\n status: PostStatus;\n votes: number;\n comments: number;\n voted: boolean;\n createdAt: string;\n /** \"Lena K.\", \"Anonymous\" or \"Team\". Missing from servers before SDK 0.6. */\n author?: string;\n}\n\n/** The product's public face for the board's header. */\nexport interface FeedbackProduct {\n name: string;\n logo: string | null;\n /** The domain's favicon, tried when `logo` does not load. Older servers leave it out. */\n logoFallback?: string | null;\n}\n\nexport interface FeedbackList {\n boards: FeedbackBoardInfo[];\n posts: FeedbackPost[];\n product?: FeedbackProduct;\n}\n\nexport interface FeedbackRoadmap {\n /** `review` (Backlog) comes from servers of SDK 0.6 on. */\n columns: { review?: FeedbackPost[]; planned: FeedbackPost[]; progress: FeedbackPost[]; shipped: FeedbackPost[] };\n}\n\nexport interface ChangelogEntry {\n id: string;\n title: string;\n body: string;\n publishedAt: string;\n}\n\nexport interface FeedbackComment {\n id: string;\n body: string;\n author: string;\n isTeam: boolean;\n postedAt: string;\n}\n\nexport type SurveyQuestionKind = \"nps\" | \"rating\" | \"single\" | \"multi\" | \"text\";\n\nexport interface SurveyQuestion {\n key: string;\n kind: SurveyQuestionKind;\n title: string;\n description?: string;\n required: boolean;\n options?: string[];\n /**\n * 0.21.0: what each option says in the visitor's language, parallel to `options`. An answer is still recorded as the\n * `options` value, so rules and numbers do not split by language.\n */\n labels?: string[];\n scale?: number;\n low?: string;\n high?: string;\n placeholder?: string;\n}\n\nexport interface SurveyDefinition {\n id: string;\n name: string;\n type: string;\n thanks: string;\n questions: SurveyQuestion[];\n}\n\nexport type SurveyAnswer = number | string | string[];\n\n/** A file in the messenger's chat: a screenshot, a photo or a PDF the visitor sent (servers from SDK 0.15 on). */\nexport interface ChatFile {\n /** From an upload: the signed id a message sends. In a message: the file's own id (`attachmentUrl` reads it). */\n id: string;\n name: string;\n type: \"image/png\" | \"image/jpeg\" | \"image/webp\" | \"image/gif\" | \"application/pdf\";\n /** Bytes. */\n size: number;\n}\n\n/** What the messenger can send: pictures and PDFs, at most 10 MB each, 4 per message. */\nexport const CHAT_FILE_TYPES = [\"image/png\", \"image/jpeg\", \"image/webp\", \"image/gif\", \"application/pdf\"] as const;\nexport const CHAT_FILE_MAX_BYTES = 10 * 1024 * 1024;\nexport const CHAT_FILES_PER_MESSAGE = 4;\n\n/** A file to upload: a Blob or File on the web, the image picker's `{ uri, name, type }` in React Native. */\nexport type ChatUpload = Blob | { uri: string; name: string; type: string };\n\n/** The bug context a visitor message carries; the server fills browser and system from the user agent when left out. */\nexport interface ChatContext {\n browser?: string;\n os?: string;\n /** \"1440×900\". */\n viewport?: string;\n}\n\n/** One message of the messenger's chat. \"visitor\" is the person on the site; the rest come from the product's team. */\nexport interface ChatMessage {\n id: string;\n from: \"visitor\" | \"team\" | \"ai\" | \"auto\";\n body: string;\n at: string;\n /** Help articles an answer drew on (servers from SDK 0.9 on). */\n articles?: { id: string; title: string }[];\n /** Files sent with it (servers from SDK 0.15 on). */\n attachments?: ChatFile[];\n}\n\n/** A published help article in a list (the messenger's Help tab). */\nexport interface ArticleSummary {\n id: string;\n title: string;\n collection: string;\n excerpt: string;\n updatedAt: string;\n}\n\n/** A run of text inside an article block. Links are http(s), mailto or tel only. */\nexport interface ArticleSpan {\n text: string;\n href?: string;\n bold?: boolean;\n italic?: boolean;\n code?: boolean;\n}\n\n/** An article's content as blocks, written with textContent (never parsed as HTML). */\nexport type ArticleBlock =\n | { type: \"h2\" | \"h3\" | \"p\" | \"quote\"; spans: ArticleSpan[] }\n | { type: \"ul\" | \"ol\"; items: ArticleSpan[][] }\n | { type: \"code\"; text: string }\n | { type: \"hr\" };\n\nexport interface Article {\n id: string;\n title: string;\n collection: string;\n updatedAt: string;\n blocks: ArticleBlock[];\n}\n\n/** Where the chat button sits: a corner, the middle of the top or bottom edge, or the middle of a side. */\nexport type MessengerPosition = \"top-left\" | \"top-center\" | \"top-right\" | \"middle-left\" | \"middle-right\" | \"bottom-left\" | \"bottom-center\" | \"bottom-right\";\n\n/** How round the messenger is. */\nexport type MessengerCorners = \"round\" | \"soft\" | \"square\";\n\n/** The radii per corner style, in px: the panel or sheet, message bubbles (and their tail), cards, fields and buttons. */\nexport const CORNERS: Record<MessengerCorners, { panel: number; bubble: number; tail: number; card: number; field: number }> = {\n round: { panel: 22, bubble: 18, tail: 6, card: 16, field: 20 },\n soft: { panel: 14, bubble: 12, tail: 4, card: 10, field: 10 },\n square: { panel: 6, bubble: 6, tail: 2, card: 4, field: 4 },\n};\n\n/** The messenger's look and texts as set in MRRocket › Support › Messenger (servers from SDK 0.9 on). */\nexport interface MessengerLook {\n accent: string;\n /** Up to two more colors blended into Home's background glow (MRRocket from 0.16; older servers leave it out). */\n glow?: string[];\n theme: \"light\" | \"dark\" | \"auto\";\n position: MessengerPosition;\n title: string;\n greeting: string;\n label: string;\n /** How soon the team usually answers (MRRocket from 0.10; older servers leave it out). */\n replyTime?: \"minutes\" | \"hours\" | \"day\";\n /** A round chat button in the app (React Native) too. */\n appLauncher?: boolean;\n help: boolean;\n /** The Updates tab with the published changelog (MRRocket from 0.22; older servers leave it out). */\n updates?: boolean;\n sound: boolean;\n preview: boolean;\n askEmail: boolean;\n /** How round panel, bubbles, cards and fields are (MRRocket from 0.15; older servers leave it out: round). */\n corners?: MessengerCorners;\n /** The site's own font (the default) or the system's (web only; from 0.15). */\n font?: \"site\" | \"system\";\n /** Home's top: plain like the rest, or in the accent color (from 0.15; older servers leave it out: plain). */\n header?: \"plain\" | \"color\";\n /** \"Powered by MRRocket\" at the bottom; the server sends false only on plans that may hide it (from 0.15). */\n branding?: boolean;\n /** The logo at the top left of Home: the one uploaded in MRRocket, else the product's favicon; without it the title's first letter. */\n logo?: string;\n /** The product's favicon, the round mark in the chat's head (from 0.17; without it the title's first letter). */\n icon?: string;\n /** The AI agent's name on its answers (from 0.17; empty or left out: \"AI agent\"). */\n agentName?: string;\n /** The AI agent's picture beside its answers (from 0.17). */\n agentPhoto?: string;\n}\n\n/** The link behind \"Powered by MRRocket\". */\nexport const BRAND_URL = \"https://mrrocket.dev/?utm_source=messenger&utm_medium=powered-by\";\n\n/** The line under \"Send us a message\" and in the chat's head. */\nexport const replyLine = (time: MessengerLook[\"replyTime\"]) =>\n time === \"minutes\" ? t(\"We usually reply in a few minutes\") : time === \"day\" ? t(\"We usually reply within a day\") : t(\"We usually reply in a few hours\");\n\n/** Black or white, whichever reads better on the accent (a light custom color gets dark text). */\nexport const inkOn = (hex: string) => {\n const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);\n if (!m) return \"#ffffff\";\n const [r, g, b] = [m[1], m[2], m[3]].map((x) => {\n const c = parseInt(x, 16) / 255;\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.45 ? \"#111214\" : \"#ffffff\";\n};\n\n/** One of the visitor's conversations in their list (0.19). */\nexport interface ChatSummary {\n id: string;\n status: \"open\" | \"solved\";\n /** The visitor's first words. */\n subject: string;\n /** The newest message, its body cut to a preview. */\n last: ChatMessage | null;\n}\n\n/** One chat (the one asked for, else the visitor's newest, open or closed) and its messages. */\nexport interface ChatThread {\n conversation: { id: string; status: \"open\" | \"solved\" } | null;\n messages: ChatMessage[];\n /** All the visitor's conversations, the latest activity first (0.19). */\n conversations?: ChatSummary[];\n /** The visitor gave an email already: the messenger stops asking. */\n hasEmail: boolean;\n}\n\nexport class ApiError extends Error {\n status: number;\n constructor(message: string, status: number) {\n super(message);\n this.status = status;\n }\n}\n\ninterface Conn {\n host: string;\n apiKey: string;\n distinctId: string;\n user?: { id?: string; [key: string]: unknown };\n /**\n * The identity hash of `distinctId` (0.16.0, see identity.ts), sent with every request that names the visitor: a\n * JSON field next to `distinctId`, a query parameter, a form field. Leave it out for any other id.\n */\n userHash?: string;\n}\n\n// Not URLSearchParams: React Native's lacks `set` in older versions, and the apps use this client too.\n// `lang` goes along so the answer's words can be in the visitor's language; \"\" leaves it out.\nconst qs = (params: Record<string, string | undefined>, lang = currentLocale()) =>\n Object.entries({ ...params, lang })\n .filter((e): e is [string, string] => !!e[1])\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n/** A POST's address: its body names the visitor, the query only the language of the words in its answer. */\nconst withLang = (url: string) => {\n const q = qs({});\n return q ? `${url}?${q}` : url;\n};\n\nconst call = async <T>(url: string, init: RequestInit | undefined, signal?: AbortSignal): Promise<T> => {\n let res: Response;\n try {\n res = await fetch(url, {\n ...init,\n signal,\n // A form (a file upload) sets its own multipart type with the boundary.\n headers: typeof init?.body === \"string\" ? { \"content-type\": \"application/json\" } : undefined,\n });\n } catch (e) {\n if ((e as Error).name === \"AbortError\") throw e;\n throw new ApiError(t(\"Could not reach the server. Check your connection and try again.\"), 0);\n }\n if (!res.ok) {\n // A missing or wrong identity hash: the console says once how to sign the user id.\n warnUnsigned(res.status);\n let detail = \"\";\n try {\n detail = ((await res.json()) as { error?: string }).error ?? \"\";\n } catch {\n // Not JSON; the status is enough.\n }\n throw new ApiError(detail || (res.status === 429 ? t(\"Too many requests. Try again in a minute.\") : t(\"Something went wrong. Please try again.\")), res.status);\n }\n return (await res.json()) as T;\n};\n\n/** The small fetch client behind the widgets. Every read takes an AbortSignal so unmounting cancels it. */\nexport const createApi = (c: Conn) => {\n const base = `${c.host}/api/sdk`;\n const who = { key: c.apiKey, distinctId: c.distinctId, user: c.user, userHash: c.userHash };\n // Every query that names the visitor names its hash too.\n const me = { key: c.apiKey, distinctId: c.distinctId, userHash: c.userHash };\n const post = <T>(path: string, body: Record<string, unknown>, signal?: AbortSignal) =>\n call<T>(withLang(`${base}${path}`), { method: \"POST\", body: JSON.stringify({ ...who, ...body }) }, signal);\n return {\n list: (o: { board?: string; sort?: \"top\" | \"new\"; q?: string }, signal?: AbortSignal) =>\n call<FeedbackList>(`${base}/feedback?${qs({ ...me, board: o.board, sort: o.sort, q: o.q })}`, undefined, signal),\n post: (id: string, signal?: AbortSignal) =>\n call<FeedbackPost>(`${base}/feedback/${encodeURIComponent(id)}?${qs(me)}`, undefined, signal),\n roadmap: (signal?: AbortSignal) => call<FeedbackRoadmap>(`${base}/feedback/roadmap?${qs(me)}`, undefined, signal),\n changelog: (signal?: AbortSignal) => call<{ entries: ChangelogEntry[] }>(`${base}/feedback/changelog?${qs({ key: c.apiKey })}`, undefined, signal),\n submit: (p: { title: string; body?: string; board: string }) => post<FeedbackPost>(\"/feedback\", p),\n vote: (id: string) => post<{ voted: boolean; votes: number }>(`/feedback/${encodeURIComponent(id)}/vote`, {}),\n comments: (id: string, signal?: AbortSignal) =>\n call<{ comments: FeedbackComment[] }>(`${base}/feedback/${encodeURIComponent(id)}/comments?${qs({ key: c.apiKey })}`, undefined, signal),\n comment: (id: string, body: string) => post<FeedbackComment>(`/feedback/${encodeURIComponent(id)}/comments`, { body }),\n survey: (url: string, signal?: AbortSignal) =>\n call<{ survey: SurveyDefinition | null }>(`${base}/surveys?${qs({ ...me, url })}`, undefined, signal),\n seen: (id: string) => post<unknown>(`/surveys/${encodeURIComponent(id)}/seen`, { user: undefined }),\n respond: (id: string, r: { answers: Record<string, SurveyAnswer>; completed: boolean; seconds: number }) =>\n post<unknown>(`/surveys/${encodeURIComponent(id)}/respond`, r),\n /** One chat by id, else the visitor's newest; `conversations` lists them all. */\n chat: (signal?: AbortSignal, conversation?: string) => call<ChatThread>(`${base}/messages?${qs({ ...me, conversation })}`, undefined, signal),\n /**\n * A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). `conversation` is\n * the chat it answers, or \"new\" to start one; without it, the running chat or else a new one.\n */\n sendChat: (m: { body: string; conversation?: string; email?: string; url?: string; attachments?: string[]; context?: ChatContext }) => post<ChatThread>(\"/messages\", m),\n /** Uploads one picked file for the next message (pictures and PDFs, at most 10 MB); answers its upload id. */\n uploadChatFile: (file: ChatUpload, signal?: AbortSignal) => {\n const form = new FormData();\n form.append(\"key\", c.apiKey);\n form.append(\"distinctId\", c.distinctId);\n if (c.userHash) form.append(\"userHash\", c.userHash);\n if (\"uri\" in file) form.append(\"file\", file as unknown as Blob);\n else form.append(\"file\", file, (file as Blob & { name?: string }).name || \"file\");\n return call<ChatFile>(withLang(`${base}/messages/attachments`), { method: \"POST\", body: form }, signal);\n },\n /** Where a sent file of this visitor's chat is read (an image's src, a PDF's link). */\n attachmentUrl: (id: string) => `${base}/messages/attachments/${encodeURIComponent(id)}?${qs(me, \"\")}`,\n articles: (q?: string, signal?: AbortSignal) => call<{ articles: ArticleSummary[] }>(`${base}/articles?${qs({ key: c.apiKey, q })}`, undefined, signal),\n article: (id: string, signal?: AbortSignal) =>\n call<Article>(`${base}/articles/${encodeURIComponent(id)}?${qs(me)}`, undefined, signal),\n messengerLook: (signal?: AbortSignal) => call<MessengerLook>(`${base}/messenger?${qs({ key: c.apiKey })}`, undefined, signal),\n rateArticle: (id: string, helpful: boolean) => post<{ counted: boolean }>(`/articles/${encodeURIComponent(id)}/rate`, { helpful }),\n };\n};\n\nexport type Api = ReturnType<typeof createApi>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/api-client.ts"],"sourcesContent":["/**\n * The SDK's fetch client and the shapes it reads, without React, so the script tag's widgets (src/script) use it too.\n * `./api` re-exports all of it with the `useApi` hook.\n */\nimport { warnUnsigned } from \"./identity\";\nimport { currentLocale, t } from \"./i18n\";\n\nexport type PostStatus = \"review\" | \"planned\" | \"progress\" | \"shipped\";\n\n/** Read at the moment it is shown, so it follows the visitor's language. */\nexport const STATUS_LABEL: Record<PostStatus, string> = {\n get review() {\n return t(\"Under review\");\n },\n get planned() {\n return t(\"Planned\");\n },\n get progress() {\n return t(\"In progress\");\n },\n get shipped() {\n return t(\"Shipped\");\n },\n};\n\nexport interface FeedbackBoardInfo {\n id: string;\n label: string;\n}\n\nexport interface FeedbackPost {\n id: string;\n title: string;\n body: string;\n board: string;\n status: PostStatus;\n votes: number;\n comments: number;\n voted: boolean;\n createdAt: string;\n /** \"Lena K.\", \"Anonymous\" or \"Team\". Missing from servers before SDK 0.6. */\n author?: string;\n}\n\n/** The product's public face for the board's header. */\nexport interface FeedbackProduct {\n name: string;\n logo: string | null;\n /** The domain's favicon, tried when `logo` does not load. Older servers leave it out. */\n logoFallback?: string | null;\n}\n\nexport interface FeedbackList {\n boards: FeedbackBoardInfo[];\n posts: FeedbackPost[];\n product?: FeedbackProduct;\n}\n\nexport interface FeedbackRoadmap {\n /** `review` (Backlog) comes from servers of SDK 0.6 on. */\n columns: { review?: FeedbackPost[]; planned: FeedbackPost[]; progress: FeedbackPost[]; shipped: FeedbackPost[] };\n}\n\nexport interface ChangelogEntry {\n id: string;\n title: string;\n body: string;\n publishedAt: string;\n}\n\nexport interface FeedbackComment {\n id: string;\n body: string;\n author: string;\n isTeam: boolean;\n postedAt: string;\n}\n\nexport type SurveyQuestionKind = \"nps\" | \"rating\" | \"single\" | \"multi\" | \"text\";\n\nexport interface SurveyQuestion {\n key: string;\n kind: SurveyQuestionKind;\n title: string;\n description?: string;\n required: boolean;\n options?: string[];\n /**\n * 0.21.0: what each option says in the visitor's language, parallel to `options`. An answer is still recorded as the\n * `options` value, so rules and numbers do not split by language.\n */\n labels?: string[];\n scale?: number;\n low?: string;\n high?: string;\n placeholder?: string;\n}\n\nexport interface SurveyDefinition {\n id: string;\n name: string;\n type: string;\n thanks: string;\n questions: SurveyQuestion[];\n}\n\nexport type SurveyAnswer = number | string | string[];\n\n/** A file in the messenger's chat: a screenshot, a photo or a PDF the visitor sent (servers from SDK 0.15 on). */\nexport interface ChatFile {\n /** From an upload: the signed id a message sends. In a message: the file's own id (`attachmentUrl` reads it). */\n id: string;\n name: string;\n type: \"image/png\" | \"image/jpeg\" | \"image/webp\" | \"image/gif\" | \"application/pdf\";\n /** Bytes. */\n size: number;\n}\n\n/** What the messenger can send: pictures and PDFs, at most 10 MB each, 4 per message. */\nexport const CHAT_FILE_TYPES = [\"image/png\", \"image/jpeg\", \"image/webp\", \"image/gif\", \"application/pdf\"] as const;\nexport const CHAT_FILE_MAX_BYTES = 10 * 1024 * 1024;\nexport const CHAT_FILES_PER_MESSAGE = 4;\n\n/** A file to upload: a Blob or File on the web, the image picker's `{ uri, name, type }` in React Native. */\nexport type ChatUpload = Blob | { uri: string; name: string; type: string };\n\n/** The bug context a visitor message carries; the server fills browser and system from the user agent when left out. */\nexport interface ChatContext {\n browser?: string;\n os?: string;\n /** \"1440×900\". */\n viewport?: string;\n}\n\n/** One message of the messenger's chat. \"visitor\" is the person on the site; the rest come from the product's team. */\nexport interface ChatMessage {\n id: string;\n from: \"visitor\" | \"team\" | \"ai\" | \"auto\";\n body: string;\n at: string;\n /** Help articles an answer drew on (servers from SDK 0.9 on). */\n articles?: { id: string; title: string }[];\n /** Files sent with it (servers from SDK 0.15 on). */\n attachments?: ChatFile[];\n}\n\n/** A published help article in a list (the messenger's Help tab). */\nexport interface ArticleSummary {\n id: string;\n title: string;\n collection: string;\n excerpt: string;\n updatedAt: string;\n}\n\n/** A run of text inside an article block. Links are http(s), mailto or tel only. */\nexport interface ArticleSpan {\n text: string;\n href?: string;\n bold?: boolean;\n italic?: boolean;\n code?: boolean;\n}\n\n/** An article's content as blocks, written with textContent (never parsed as HTML). */\nexport type ArticleBlock =\n | { type: \"h2\" | \"h3\" | \"p\" | \"quote\"; spans: ArticleSpan[] }\n | { type: \"ul\" | \"ol\"; items: ArticleSpan[][] }\n | { type: \"code\"; text: string }\n | { type: \"hr\" };\n\nexport interface Article {\n id: string;\n title: string;\n collection: string;\n updatedAt: string;\n blocks: ArticleBlock[];\n}\n\n/** Where the chat button sits: a corner, the middle of the top or bottom edge, or the middle of a side. */\nexport type MessengerPosition = \"top-left\" | \"top-center\" | \"top-right\" | \"middle-left\" | \"middle-right\" | \"bottom-left\" | \"bottom-center\" | \"bottom-right\";\n\n/** How round the messenger is. */\nexport type MessengerCorners = \"round\" | \"soft\" | \"square\";\n\n/** The radii per corner style, in px: the panel or sheet, message bubbles (and their tail), cards, fields and buttons. */\nexport const CORNERS: Record<MessengerCorners, { panel: number; bubble: number; tail: number; card: number; field: number }> = {\n round: { panel: 22, bubble: 18, tail: 6, card: 16, field: 20 },\n soft: { panel: 14, bubble: 12, tail: 4, card: 10, field: 10 },\n square: { panel: 6, bubble: 6, tail: 2, card: 4, field: 4 },\n};\n\n/** The messenger's look and texts as set in MRRocket › Support › Messenger (servers from SDK 0.9 on). */\nexport interface MessengerLook {\n accent: string;\n /** Up to two more colors blended into Home's background glow (MRRocket from 0.16; older servers leave it out). */\n glow?: string[];\n theme: \"light\" | \"dark\" | \"auto\";\n position: MessengerPosition;\n title: string;\n greeting: string;\n label: string;\n /** How soon the team usually answers (MRRocket from 0.10; older servers leave it out). */\n replyTime?: \"minutes\" | \"hours\" | \"day\";\n /** A round chat button in the app (React Native) too. */\n appLauncher?: boolean;\n help: boolean;\n /** The Updates tab with the published changelog (MRRocket from 0.22; older servers leave it out). */\n updates?: boolean;\n sound: boolean;\n preview: boolean;\n askEmail: boolean;\n /** How round panel, bubbles, cards and fields are (MRRocket from 0.15; older servers leave it out: round). */\n corners?: MessengerCorners;\n /** The site's own font (the default) or the system's (web only; from 0.15). */\n font?: \"site\" | \"system\";\n /** Home's top: plain like the rest, or in the accent color (from 0.15; older servers leave it out: plain). */\n header?: \"plain\" | \"color\";\n /** \"Powered by MRRocket\" at the bottom; the server sends false only on plans that may hide it (from 0.15). */\n branding?: boolean;\n /** The logo at the top left of Home: the one uploaded in MRRocket, else the product's favicon; without it the title's first letter. */\n logo?: string;\n /** The product's favicon, the round mark in the chat's head (from 0.17; without it the title's first letter). */\n icon?: string;\n /** The AI agent's name on its answers (from 0.17; empty or left out: \"AI agent\"). */\n agentName?: string;\n /** The AI agent's picture beside its answers (from 0.17). */\n agentPhoto?: string;\n}\n\n/** The link behind \"Powered by MRRocket\". */\nexport const BRAND_URL = \"https://mrrocket.dev/?utm_source=messenger&utm_medium=powered-by\";\n\n/** The line under \"Send us a message\" and in the chat's head. */\nexport const replyLine = (time: MessengerLook[\"replyTime\"]) =>\n time === \"minutes\" ? t(\"We usually reply in a few minutes\") : time === \"day\" ? t(\"We usually reply within a day\") : t(\"We usually reply in a few hours\");\n\n/** Black or white, whichever reads better on the accent (a light custom color gets dark text). */\nexport const inkOn = (hex: string) => {\n const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);\n if (!m) return \"#ffffff\";\n const [r, g, b] = [m[1], m[2], m[3]].map((x) => {\n const c = parseInt(x, 16) / 255;\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.45 ? \"#111214\" : \"#ffffff\";\n};\n\n/** One of the visitor's conversations in their list (0.19). */\nexport interface ChatSummary {\n id: string;\n status: \"open\" | \"solved\";\n /** The visitor's first words. */\n subject: string;\n /** The newest message, its body cut to a preview. */\n last: ChatMessage | null;\n}\n\n/** One chat (the one asked for, else the visitor's newest, open or closed) and its messages. */\nexport interface ChatThread {\n conversation: { id: string; status: \"open\" | \"solved\" } | null;\n messages: ChatMessage[];\n /** All the visitor's conversations, the latest activity first (0.19). */\n conversations?: ChatSummary[];\n /** The visitor gave an email already: the messenger stops asking. */\n hasEmail: boolean;\n}\n\n/**\n * For the count and the preview of unread answers, after a read: an answer the team took back and a conversation it\n * archived leave them. Of a conversation that is not on screen the list brings only the newest message, so an answer\n * newer than that one is gone.\n */\nexport const stillThere = (t: ChatThread, chats: ChatSummary[]) => (m: { id: string; at: string; chat: string }) => {\n if (m.chat === t.conversation?.id) return t.messages.some((x) => x.id === m.id);\n const last = chats.find((c) => c.id === m.chat)?.last;\n return !!last && m.at <= last.at;\n};\n\nexport class ApiError extends Error {\n status: number;\n constructor(message: string, status: number) {\n super(message);\n this.status = status;\n }\n}\n\ninterface Conn {\n host: string;\n apiKey: string;\n distinctId: string;\n user?: { id?: string; [key: string]: unknown };\n /**\n * The identity hash of `distinctId` (0.16.0, see identity.ts), sent with every request that names the visitor: a\n * JSON field next to `distinctId`, a query parameter, a form field. Leave it out for any other id.\n */\n userHash?: string;\n}\n\n// Not URLSearchParams: React Native's lacks `set` in older versions, and the apps use this client too.\n// `lang` goes along so the answer's words can be in the visitor's language; \"\" leaves it out.\nconst qs = (params: Record<string, string | undefined>, lang = currentLocale()) =>\n Object.entries({ ...params, lang })\n .filter((e): e is [string, string] => !!e[1])\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n\n/** A POST's address: its body names the visitor, the query only the language of the words in its answer. */\nconst withLang = (url: string) => {\n const q = qs({});\n return q ? `${url}?${q}` : url;\n};\n\nconst call = async <T>(url: string, init: RequestInit | undefined, signal?: AbortSignal): Promise<T> => {\n let res: Response;\n try {\n res = await fetch(url, {\n ...init,\n signal,\n // A form (a file upload) sets its own multipart type with the boundary.\n headers: typeof init?.body === \"string\" ? { \"content-type\": \"application/json\" } : undefined,\n });\n } catch (e) {\n if ((e as Error).name === \"AbortError\") throw e;\n throw new ApiError(t(\"Could not reach the server. Check your connection and try again.\"), 0);\n }\n if (!res.ok) {\n // A missing or wrong identity hash: the console says once how to sign the user id.\n warnUnsigned(res.status);\n let detail = \"\";\n try {\n detail = ((await res.json()) as { error?: string }).error ?? \"\";\n } catch {\n // Not JSON; the status is enough.\n }\n throw new ApiError(detail || (res.status === 429 ? t(\"Too many requests. Try again in a minute.\") : t(\"Something went wrong. Please try again.\")), res.status);\n }\n return (await res.json()) as T;\n};\n\n/** The small fetch client behind the widgets. Every read takes an AbortSignal so unmounting cancels it. */\nexport const createApi = (c: Conn) => {\n const base = `${c.host}/api/sdk`;\n const who = { key: c.apiKey, distinctId: c.distinctId, user: c.user, userHash: c.userHash };\n // Every query that names the visitor names its hash too.\n const me = { key: c.apiKey, distinctId: c.distinctId, userHash: c.userHash };\n const post = <T>(path: string, body: Record<string, unknown>, signal?: AbortSignal) =>\n call<T>(withLang(`${base}${path}`), { method: \"POST\", body: JSON.stringify({ ...who, ...body }) }, signal);\n return {\n list: (o: { board?: string; sort?: \"top\" | \"new\"; q?: string }, signal?: AbortSignal) =>\n call<FeedbackList>(`${base}/feedback?${qs({ ...me, board: o.board, sort: o.sort, q: o.q })}`, undefined, signal),\n post: (id: string, signal?: AbortSignal) =>\n call<FeedbackPost>(`${base}/feedback/${encodeURIComponent(id)}?${qs(me)}`, undefined, signal),\n roadmap: (signal?: AbortSignal) => call<FeedbackRoadmap>(`${base}/feedback/roadmap?${qs(me)}`, undefined, signal),\n changelog: (signal?: AbortSignal) => call<{ entries: ChangelogEntry[] }>(`${base}/feedback/changelog?${qs({ key: c.apiKey })}`, undefined, signal),\n submit: (p: { title: string; body?: string; board: string }) => post<FeedbackPost>(\"/feedback\", p),\n vote: (id: string) => post<{ voted: boolean; votes: number }>(`/feedback/${encodeURIComponent(id)}/vote`, {}),\n comments: (id: string, signal?: AbortSignal) =>\n call<{ comments: FeedbackComment[] }>(`${base}/feedback/${encodeURIComponent(id)}/comments?${qs({ key: c.apiKey })}`, undefined, signal),\n comment: (id: string, body: string) => post<FeedbackComment>(`/feedback/${encodeURIComponent(id)}/comments`, { body }),\n survey: (url: string, signal?: AbortSignal) =>\n call<{ survey: SurveyDefinition | null }>(`${base}/surveys?${qs({ ...me, url })}`, undefined, signal),\n seen: (id: string) => post<unknown>(`/surveys/${encodeURIComponent(id)}/seen`, { user: undefined }),\n respond: (id: string, r: { answers: Record<string, SurveyAnswer>; completed: boolean; seconds: number }) =>\n post<unknown>(`/surveys/${encodeURIComponent(id)}/respond`, r),\n /**\n * One chat by id, else the visitor's newest; `conversations` lists them all. `aiLabel`: the messenger says \"AI agent\"\n * beside an answer's name, so the answer comes without its AI notice line (from 0.22.0).\n */\n chat: (signal?: AbortSignal, conversation?: string) => call<ChatThread>(`${base}/messages?${qs({ ...me, conversation, aiLabel: \"1\" })}`, undefined, signal),\n /**\n * A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). `conversation` is\n * the chat it answers, or \"new\" to start one; without it, the running chat or else a new one.\n */\n sendChat: (m: { body: string; conversation?: string; email?: string; url?: string; attachments?: string[]; context?: ChatContext }) => post<ChatThread>(\"/messages\", { ...m, aiLabel: true }),\n /** Uploads one picked file for the next message (pictures and PDFs, at most 10 MB); answers its upload id. */\n uploadChatFile: (file: ChatUpload, signal?: AbortSignal) => {\n const form = new FormData();\n form.append(\"key\", c.apiKey);\n form.append(\"distinctId\", c.distinctId);\n if (c.userHash) form.append(\"userHash\", c.userHash);\n if (\"uri\" in file) form.append(\"file\", file as unknown as Blob);\n else form.append(\"file\", file, (file as Blob & { name?: string }).name || \"file\");\n return call<ChatFile>(withLang(`${base}/messages/attachments`), { method: \"POST\", body: form }, signal);\n },\n /** Where a sent file of this visitor's chat is read (an image's src, a PDF's link). */\n attachmentUrl: (id: string) => `${base}/messages/attachments/${encodeURIComponent(id)}?${qs(me, \"\")}`,\n articles: (q?: string, signal?: AbortSignal) => call<{ articles: ArticleSummary[] }>(`${base}/articles?${qs({ key: c.apiKey, q })}`, undefined, signal),\n article: (id: string, signal?: AbortSignal) =>\n call<Article>(`${base}/articles/${encodeURIComponent(id)}?${qs(me)}`, undefined, signal),\n messengerLook: (signal?: AbortSignal) => call<MessengerLook>(`${base}/messenger?${qs({ key: c.apiKey })}`, undefined, signal),\n rateArticle: (id: string, helpful: boolean) => post<{ counted: boolean }>(`/articles/${encodeURIComponent(id)}/rate`, { helpful }),\n };\n};\n\nexport type Api = ReturnType<typeof createApi>;\n"],"mappings":";AAIA,SAAS,oBAAoB;AAC7B,SAAS,eAAe,SAAS;AAK1B,IAAM,eAA2C;AAAA,EACpD,IAAI,SAAS;AACT,WAAO,EAAE,cAAc;AAAA,EAC3B;AAAA,EACA,IAAI,UAAU;AACV,WAAO,EAAE,SAAS;AAAA,EACtB;AAAA,EACA,IAAI,WAAW;AACX,WAAO,EAAE,aAAa;AAAA,EAC1B;AAAA,EACA,IAAI,UAAU;AACV,WAAO,EAAE,SAAS;AAAA,EACtB;AACJ;AAgGO,IAAM,kBAAkB,CAAC,aAAa,cAAc,cAAc,aAAa,iBAAiB;AAChG,IAAM,sBAAsB,KAAK,OAAO;AACxC,IAAM,yBAAyB;AAiE/B,IAAM,UAAkH;AAAA,EAC3H,OAAO,EAAE,OAAO,IAAI,QAAQ,IAAI,MAAM,GAAG,MAAM,IAAI,OAAO,GAAG;AAAA,EAC7D,MAAM,EAAE,OAAO,IAAI,QAAQ,IAAI,MAAM,GAAG,MAAM,IAAI,OAAO,GAAG;AAAA,EAC5D,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE;AAC9D;AAyCO,IAAM,YAAY;AAGlB,IAAM,YAAY,CAAC,SACtB,SAAS,YAAY,EAAE,mCAAmC,IAAI,SAAS,QAAQ,EAAE,+BAA+B,IAAI,EAAE,iCAAiC;AAGpJ,IAAM,QAAQ,CAAC,QAAgB;AAClC,QAAM,IAAI,8CAA8C,KAAK,GAAG;AAChE,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM;AAC5C,UAAM,IAAI,SAAS,GAAG,EAAE,IAAI;AAC5B,WAAO,KAAK,UAAU,IAAI,UAAU,IAAI,SAAS,UAAU;AAAA,EAC/D,CAAC;AACD,SAAO,SAAS,IAAI,SAAS,IAAI,SAAS,IAAI,OAAO,YAAY;AACrE;AA2BO,IAAM,aAAa,CAACA,IAAe,UAAyB,CAAC,MAAgD;AAChH,MAAI,EAAE,SAASA,GAAE,cAAc,GAAI,QAAOA,GAAE,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;AAC9E,QAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG;AACjD,SAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK;AAClC;AAEO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAChC;AAAA,EACA,YAAY,SAAiB,QAAgB;AACzC,UAAM,OAAO;AACb,SAAK,SAAS;AAAA,EAClB;AACJ;AAgBA,IAAM,KAAK,CAAC,QAA4C,OAAO,cAAc,MACzE,OAAO,QAAQ,EAAE,GAAG,QAAQ,KAAK,CAAC,EAC7B,OAAO,CAAC,MAA6B,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3C,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,mBAAmB,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,EACnE,KAAK,GAAG;AAGjB,IAAM,WAAW,CAAC,QAAgB;AAC9B,QAAM,IAAI,GAAG,CAAC,CAAC;AACf,SAAO,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK;AAC/B;AAEA,IAAM,OAAO,OAAU,KAAa,MAA+B,WAAqC;AACpG,MAAI;AACJ,MAAI;AACA,UAAM,MAAM,MAAM,KAAK;AAAA,MACnB,GAAG;AAAA,MACH;AAAA;AAAA,MAEA,SAAS,OAAO,MAAM,SAAS,WAAW,EAAE,gBAAgB,mBAAmB,IAAI;AAAA,IACvF,CAAC;AAAA,EACL,SAAS,GAAG;AACR,QAAK,EAAY,SAAS,aAAc,OAAM;AAC9C,UAAM,IAAI,SAAS,EAAE,kEAAkE,GAAG,CAAC;AAAA,EAC/F;AACA,MAAI,CAAC,IAAI,IAAI;AAET,iBAAa,IAAI,MAAM;AACvB,QAAI,SAAS;AACb,QAAI;AACA,gBAAW,MAAM,IAAI,KAAK,GAA0B,SAAS;AAAA,IACjE,QAAQ;AAAA,IAER;AACA,UAAM,IAAI,SAAS,WAAW,IAAI,WAAW,MAAM,EAAE,2CAA2C,IAAI,EAAE,yCAAyC,IAAI,IAAI,MAAM;AAAA,EACjK;AACA,SAAQ,MAAM,IAAI,KAAK;AAC3B;AAGO,IAAM,YAAY,CAAC,MAAY;AAClC,QAAM,OAAO,GAAG,EAAE,IAAI;AACtB,QAAM,MAAM,EAAE,KAAK,EAAE,QAAQ,YAAY,EAAE,YAAY,MAAM,EAAE,MAAM,UAAU,EAAE,SAAS;AAE1F,QAAM,KAAK,EAAE,KAAK,EAAE,QAAQ,YAAY,EAAE,YAAY,UAAU,EAAE,SAAS;AAC3E,QAAM,OAAO,CAAI,MAAc,MAA+B,WAC1D,KAAQ,SAAS,GAAG,IAAI,GAAG,IAAI,EAAE,GAAG,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,EAAE,GAAG,KAAK,GAAG,KAAK,CAAC,EAAE,GAAG,MAAM;AAC7G,SAAO;AAAA,IACH,MAAM,CAAC,GAAyD,WAC5D,KAAmB,GAAG,IAAI,aAAa,GAAG,EAAE,GAAG,IAAI,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA,IACnH,MAAM,CAAC,IAAY,WACf,KAAmB,GAAG,IAAI,aAAa,mBAAmB,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,QAAW,MAAM;AAAA,IAChG,SAAS,CAAC,WAAyB,KAAsB,GAAG,IAAI,qBAAqB,GAAG,EAAE,CAAC,IAAI,QAAW,MAAM;AAAA,IAChH,WAAW,CAAC,WAAyB,KAAoC,GAAG,IAAI,uBAAuB,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA,IACjJ,QAAQ,CAAC,MAAuD,KAAmB,aAAa,CAAC;AAAA,IACjG,MAAM,CAAC,OAAe,KAAwC,aAAa,mBAAmB,EAAE,CAAC,SAAS,CAAC,CAAC;AAAA,IAC5G,UAAU,CAAC,IAAY,WACnB,KAAsC,GAAG,IAAI,aAAa,mBAAmB,EAAE,CAAC,aAAa,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA,IAC3I,SAAS,CAAC,IAAY,SAAiB,KAAsB,aAAa,mBAAmB,EAAE,CAAC,aAAa,EAAE,KAAK,CAAC;AAAA,IACrH,QAAQ,CAAC,KAAa,WAClB,KAA0C,GAAG,IAAI,YAAY,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA,IACxG,MAAM,CAAC,OAAe,KAAc,YAAY,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,OAAU,CAAC;AAAA,IAClG,SAAS,CAAC,IAAY,MAClB,KAAc,YAAY,mBAAmB,EAAE,CAAC,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKjE,MAAM,CAAC,QAAsB,iBAA0B,KAAiB,GAAG,IAAI,aAAa,GAAG,EAAE,GAAG,IAAI,cAAc,SAAS,IAAI,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,IAK1J,UAAU,CAAC,MAA4H,KAAiB,aAAa,EAAE,GAAG,GAAG,SAAS,KAAK,CAAC;AAAA;AAAA,IAE5L,gBAAgB,CAAC,MAAkB,WAAyB;AACxD,YAAM,OAAO,IAAI,SAAS;AAC1B,WAAK,OAAO,OAAO,EAAE,MAAM;AAC3B,WAAK,OAAO,cAAc,EAAE,UAAU;AACtC,UAAI,EAAE,SAAU,MAAK,OAAO,YAAY,EAAE,QAAQ;AAClD,UAAI,SAAS,KAAM,MAAK,OAAO,QAAQ,IAAuB;AAAA,UACzD,MAAK,OAAO,QAAQ,MAAO,KAAkC,QAAQ,MAAM;AAChF,aAAO,KAAe,SAAS,GAAG,IAAI,uBAAuB,GAAG,EAAE,QAAQ,QAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,IAC1G;AAAA;AAAA,IAEA,eAAe,CAAC,OAAe,GAAG,IAAI,yBAAyB,mBAAmB,EAAE,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;AAAA,IACnG,UAAU,CAAC,GAAY,WAAyB,KAAqC,GAAG,IAAI,aAAa,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA,IACtJ,SAAS,CAAC,IAAY,WAClB,KAAc,GAAG,IAAI,aAAa,mBAAmB,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,QAAW,MAAM;AAAA,IAC3F,eAAe,CAAC,WAAyB,KAAoB,GAAG,IAAI,cAAc,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,QAAW,MAAM;AAAA,IAC5H,aAAa,CAAC,IAAY,YAAqB,KAA2B,aAAa,mBAAmB,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;AAAA,EACrI;AACJ;","names":["t"]}
@@ -1,4 +1,4 @@
1
- (function(){'use strict';var Fe=()=>{try{return typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches}catch(e){return false}},ae=["#f59e0b","#10b981","#ef4444","#8b5cf6","#06b6d4","#ec4899"],Pe=(e,t)=>{e.beginPath();for(let o=0;o<10;o++){let s=Math.PI/5*o-Math.PI/2,c=o%2?t*.45:t;e[o?"lineTo":"moveTo"](Math.cos(s)*c,Math.sin(s)*c);}e.closePath(),e.fill();},Ee=(e,t,o,s)=>{let c=(d,w)=>d+Math.random()*(w-d),m=()=>s[Math.floor(Math.random()*s.length)],h=[];if(e==="confetti")for(let d=0;d<110;d++){let w=d%2===0;h.push({x:w?t*.15:t*.85,y:o*.95,vx:(w?1:-1)*c(.12,.42)*(t/900+.4),vy:-c(.75,1.25)*(o/900+.35),r:c(4,7),spin:c(-0.02,.02),angle:c(0,Math.PI),color:m(),born:c(0,180),life:c(1500,2100),shape:"rect"});}else if(e==="fireworks")for(let d=0;d<4;d++){let w=c(t*.2,t*.8),l=c(o*.18,o*.5),x=m();for(let k=0;k<46;k++){let M=Math.PI*2*k/46+c(-0.05,.05),E=c(.12,.3)*(Math.min(t,o)/600+.5);h.push({x:w,y:l,vx:Math.cos(M)*E,vy:Math.sin(M)*E,r:c(1.6,2.6),spin:0,angle:0,color:x,born:d*320,life:c(900,1300),shape:"dot"});}}else for(let d=0;d<34;d++)h.push({x:c(t*.08,t*.92),y:c(o*.2,o*.85),vx:0,vy:-c(.02,.06),r:c(6,13),spin:c(-4e-3,.004),angle:c(0,Math.PI),color:m(),born:c(0,700),life:c(900,1300),shape:"star"});return h},ce=(e,t={})=>{if(!e||e==="none"||typeof document=="undefined"||!t.force&&Fe())return ()=>{};let o=document.createElement("canvas");o.setAttribute("aria-hidden","true");let s=t.host;o.style.cssText=s?"position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:5":"position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:2147483003",(s!=null?s:document.body).appendChild(o);let c=s?s.clientWidth:window.innerWidth,m=s?s.clientHeight:window.innerHeight,h=Math.min(2,window.devicePixelRatio||1);o.width=Math.max(1,Math.round(c*h)),o.height=Math.max(1,Math.round(m*h));let d=o.getContext("2d");if(!d)return o.remove(),()=>{};let w=t.accent?[t.accent,t.accent,...ae]:ae,l=Ee(e,c,m,w),x=Math.max(...l.map(z=>z.born+z.life)),k=e==="confetti"?.0016:e==="fireworks"?35e-5:0,M=0,E=0,H=false,T=()=>{H||(H=true,cancelAnimationFrame(M),o.remove());},N=z=>{if(H)return;E||(E=z);let V=z-E;d.setTransform(h,0,0,h,0,0),d.clearRect(0,0,c,m);for(let y of l){let P=V-y.born;if(P<0||P>y.life)continue;let q=y.x+y.vx*P,R=y.y+y.vy*P+.5*k*P*P,r=Math.min(1,(y.life-P)/350);if(d.save(),d.globalAlpha=Math.max(0,r),d.translate(q,R),d.rotate(y.angle+y.spin*P),d.fillStyle=y.color,y.shape==="rect")d.fillRect(-y.r,-y.r/2.2,y.r*2,y.r/1.1);else if(y.shape==="dot")d.beginPath(),d.arc(0,0,y.r,0,Math.PI*2),d.fill();else {let i=Math.min(1,P/220);Pe(d,y.r*(i<1?i:1-Math.max(0,(P-y.life*.6)/(y.life*.4))*.6));}d.restore();}V<x?M=requestAnimationFrame(N):T();};return M=requestAnimationFrame(N),T};var Y=globalThis,le,K=(le=Y.__mrrocketI18n)!=null?le:Y.__mrrocketI18n={version:0,onWords:new Set,onLocale:new Set};var f=e=>{var t;return ((t=K.words)==null?void 0:t[e])||e},I=(e,t)=>f(e).replace(/\{(\w+)\}/g,(o,s)=>s in t?String(t[s]):o);var de=()=>{var e,t;return (t=(e=K.locale)!=null?e:K.device)!=null?t:typeof navigator!="undefined"&&navigator.language||void 0};var fe=()=>K.lang;var J=e=>(K.onWords.add(e),()=>{K.onWords.delete(e);});var U="other:",Q=e=>{var s,c;let t=(s=e==null?void 0:e.min)!=null?s:0,o=(c=e==null?void 0:e.max)!=null?c:10;return Array.from({length:Math.max(0,Math.min(o-t,20)+1)},(m,h)=>t+h)},pe=(e,t)=>{var o;return !e||t==null?false:e.type==="choice"?e.other&&t.startsWith(U)?t.slice(U.length).trim().length>0:((o=e.options)!=null?o:[]).some(s=>s.id===t):e.type==="scale"?Q(e).some(s=>String(s)===t):t.trim().length>0&&t.length<=500};var X=e=>{let t=(e!=null?e:"").trim();if(!/^https?:\/\//i.test(t))return null;let o=t.match(/^https?:\/\/(?:www\.|m\.)?(?:youtube\.com\/(?:watch\?(?:.*&)?v=|embed\/|shorts\/|live\/)|youtu\.be\/|youtube-nocookie\.com\/embed\/)([\w-]{6,20})/i);return o?{kind:"iframe",src:`https://www.youtube-nocookie.com/embed/${o[1]}?rel=0`}:(o=t.match(/^https?:\/\/(?:www\.|player\.)?vimeo\.com\/(?:video\/)?(\d{4,12})/i),o?{kind:"iframe",src:`https://player.vimeo.com/video/${o[1]}?dnt=1`}:(o=t.match(/^https?:\/\/(?:www\.)?loom\.com\/(?:share|embed)\/([\w-]{8,64})/i),o?{kind:"iframe",src:`https://www.loom.com/embed/${o[1]}`}:/\.(mp4|webm|mov|m4v)(\?|#|$)/i.test(t)||/\/media\/uploads\//.test(t)?{kind:"file",src:t}:null))},ue=e=>{var o;let t=e.media;if(!(!t||t.kind!=="image"&&t.kind!=="video"||!/^https?:\/\//i.test((o=t.url)!=null?o:"")))return t.kind==="video"&&!X(t.url)?void 0:t};var ge=(e,t)=>Math.round(e*(1-t/100)*100)/100,G=(e,t)=>{try{return new Intl.NumberFormat(de(),{style:"currency",currency:t}).format(e)}catch(o){return `${e.toFixed(2)} ${t}`}},me=e=>e.kind==="contact"?f("Send to the team"):e.kind==="pause"?f("Pause instead"):e.kind==="downgrade"?f("Switch plan"):f("Accept offer"),Z=e=>e===1?f("1 month"):I("{n} months",{n:e}),ee=e=>I("for {months}",{months:Z(e)});var B={check:{label:"Check",paths:["M5 12.5l4.5 4.5L19 7.5"],emoji:"\u2705"},star:{label:"Star",paths:["M12 3.5l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z"],emoji:"\u2B50"},rocket:{label:"Rocket",paths:["M12 3c3 2 4.5 5.5 4 10l-2 3h-4l-2-3c-.5-4.5 1-8 4-10z","M8 13.5l-3 3 3.5.5","M16 13.5l3 3-3.5.5","M13.5 9.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z","M11 19.5v1.5M13 19.5v1.5"],emoji:"\u{1F680}"},user:{label:"Person",paths:["M15.5 8a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z","M5 20c.8-3.5 3.6-5.5 7-5.5s6.2 2 7 5.5"],emoji:"\u{1F464}"},users:{label:"Team",paths:["M13 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z","M3.5 19c.6-3 3-4.8 6.5-4.8s5.9 1.8 6.5 4.8","M16 5.2a3 3 0 0 1 0 5.6","M18 14.6c1.5.6 2.4 2 2.7 4.4"],emoji:"\u{1F465}"},settings:{label:"Settings",paths:["M12 2.8v2.4M12 18.8v2.4M2.8 12h2.4M18.8 12h2.4M5.5 5.5l1.7 1.7M16.8 16.8l1.7 1.7M5.5 18.5l1.7-1.7M16.8 7.2l1.7-1.7","M17 12a5 5 0 1 1-10 0 5 5 0 0 1 10 0z","M14 12a2 2 0 1 1-4 0 2 2 0 0 1 4 0z"],emoji:"\u2699\uFE0F"},bell:{label:"Bell",paths:["M6 16v-5a6 6 0 0 1 12 0v5l1.5 2h-15z","M10 20.5a2 2 0 0 0 4 0"],emoji:"\u{1F514}"},mail:{label:"Mail",paths:["M4 6h16v12H4z","M4 7l8 6 8-6"],emoji:"\u2709\uFE0F"},chat:{label:"Chat",paths:["M4 5h16v11H9l-5 4z"],emoji:"\u{1F4AC}"},heart:{label:"Heart",paths:["M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z"],emoji:"\u2764\uFE0F"},flag:{label:"Flag",paths:["M5 21V4","M5 4h11l-2 4 2 4H5"],emoji:"\u{1F6A9}"},bolt:{label:"Bolt",paths:["M13 3L5 13.5h6L10 21l8-10.5h-6z"],emoji:"\u26A1"},book:{label:"Book",paths:["M4 5.5C6.5 4 9.5 4 12 6c2.5-2 5.5-2 8-.5V19c-2.5-1.5-5.5-1.5-8 .5-2.5-2-5.5-2-8-.5z","M12 6v13.5"],emoji:"\u{1F4D6}"},calendar:{label:"Calendar",paths:["M4 6h16v14H4z","M4 10h16","M8 3.5v4M16 3.5v4"],emoji:"\u{1F4C5}"},camera:{label:"Camera",paths:["M4 8h3.5L9 5.5h6L16.5 8H20v11H4z","M15.5 13a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z"],emoji:"\u{1F4F7}"},cart:{label:"Cart",paths:["M3.5 4.5H6l2 10h10l2-7H7","M9.5 19.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z","M18.5 19.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"],emoji:"\u{1F6D2}"},chart:{label:"Chart",paths:["M4 20h16","M7 16v-4M12 16V8M17 16V9"],emoji:"\u{1F4CA}"},gift:{label:"Gift",paths:["M4 10h16v10H4z","M3 7h18v3H3z","M12 7v13","M12 7c-1.5-3-5-3-5-1s3.5 1 5 1z","M12 7c1.5-3 5-3 5-1s-3.5 1-5 1z"],emoji:"\u{1F381}"},home:{label:"Home",paths:["M4 11l8-7 8 7","M6 9.5V20h12V9.5","M10 20v-6h4v6"],emoji:"\u{1F3E0}"},link:{label:"Link",paths:["M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1","M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"],emoji:"\u{1F517}"},lock:{label:"Lock",paths:["M6 11h12v9H6z","M8.5 11V8a3.5 3.5 0 0 1 7 0v3"],emoji:"\u{1F512}"},pencil:{label:"Pencil",paths:["M4 20l1-4L16 5l3 3L8 19z","M14 7l3 3"],emoji:"\u270F\uFE0F"},plus:{label:"Plus",paths:["M12 5v14M5 12h14"],emoji:"\u2795"},search:{label:"Search",paths:["M16 10.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z","M14.5 14.5L20 20"],emoji:"\u{1F50D}"},upload:{label:"Upload",paths:["M12 15V4","M7.5 8.5L12 4l4.5 4.5","M4 15v5h16v-5"],emoji:"\u2B06\uFE0F"},play:{label:"Play",paths:["M8 5l11 7-11 7z"],emoji:"\u25B6\uFE0F"},sparkle:{label:"Sparkle",paths:["M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z","M19 16l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7z"],emoji:"\u2728"},globe:{label:"Globe",paths:["M20 12a8 8 0 1 1-16 0 8 8 0 0 1 16 0z","M4 12h16","M12 4c2.2 2.2 3.3 4.9 3.3 8s-1.1 5.8-3.3 8c-2.2-2.2-3.3-4.9-3.3-8S9.8 6.2 12 4z"],emoji:"\u{1F310}"}},ke=e=>{if(e){if(e.kind==="builtin")return e.name&&B[e.name]?e:void 0;if(e.kind==="emoji")return e.value&&e.value.trim()&&[...e.value.trim()].length<=8?e:void 0;if(e.kind==="image")return e.url&&/^https?:\/\//i.test(e.url)?e:void 0}};var he="ckf-styles",Se=`
1
+ (function(){'use strict';var Fe=()=>{try{return typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches}catch(e){return false}},ae=["#f59e0b","#10b981","#ef4444","#8b5cf6","#06b6d4","#ec4899"],Pe=(e,t)=>{e.beginPath();for(let o=0;o<10;o++){let s=Math.PI/5*o-Math.PI/2,c=o%2?t*.45:t;e[o?"lineTo":"moveTo"](Math.cos(s)*c,Math.sin(s)*c);}e.closePath(),e.fill();},Ee=(e,t,o,s)=>{let c=(d,w)=>d+Math.random()*(w-d),m=()=>s[Math.floor(Math.random()*s.length)],h=[];if(e==="confetti")for(let d=0;d<110;d++){let w=d%2===0;h.push({x:w?t*.15:t*.85,y:o*.95,vx:(w?1:-1)*c(.12,.42)*(t/900+.4),vy:-c(.75,1.25)*(o/900+.35),r:c(4,7),spin:c(-0.02,.02),angle:c(0,Math.PI),color:m(),born:c(0,180),life:c(1500,2100),shape:"rect"});}else if(e==="fireworks")for(let d=0;d<4;d++){let w=c(t*.2,t*.8),l=c(o*.18,o*.5),x=m();for(let k=0;k<46;k++){let M=Math.PI*2*k/46+c(-0.05,.05),E=c(.12,.3)*(Math.min(t,o)/600+.5);h.push({x:w,y:l,vx:Math.cos(M)*E,vy:Math.sin(M)*E,r:c(1.6,2.6),spin:0,angle:0,color:x,born:d*320,life:c(900,1300),shape:"dot"});}}else for(let d=0;d<34;d++)h.push({x:c(t*.08,t*.92),y:c(o*.2,o*.85),vx:0,vy:-c(.02,.06),r:c(6,13),spin:c(-4e-3,.004),angle:c(0,Math.PI),color:m(),born:c(0,700),life:c(900,1300),shape:"star"});return h},ce=(e,t={})=>{if(!e||e==="none"||typeof document=="undefined"||!t.force&&Fe())return ()=>{};let o=document.createElement("canvas");o.setAttribute("aria-hidden","true");let s=t.host;o.style.cssText=s?"position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:5":"position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:2147483003",(s!=null?s:document.body).appendChild(o);let c=s?s.clientWidth:window.innerWidth,m=s?s.clientHeight:window.innerHeight,h=Math.min(2,window.devicePixelRatio||1);o.width=Math.max(1,Math.round(c*h)),o.height=Math.max(1,Math.round(m*h));let d=o.getContext("2d");if(!d)return o.remove(),()=>{};let w=t.accent?[t.accent,t.accent,...ae]:ae,l=Ee(e,c,m,w),x=Math.max(...l.map(z=>z.born+z.life)),k=e==="confetti"?.0016:e==="fireworks"?35e-5:0,M=0,E=0,H=false,I=()=>{H||(H=true,cancelAnimationFrame(M),o.remove());},N=z=>{if(H)return;E||(E=z);let V=z-E;d.setTransform(h,0,0,h,0,0),d.clearRect(0,0,c,m);for(let y of l){let P=V-y.born;if(P<0||P>y.life)continue;let q=y.x+y.vx*P,R=y.y+y.vy*P+.5*k*P*P,r=Math.min(1,(y.life-P)/350);if(d.save(),d.globalAlpha=Math.max(0,r),d.translate(q,R),d.rotate(y.angle+y.spin*P),d.fillStyle=y.color,y.shape==="rect")d.fillRect(-y.r,-y.r/2.2,y.r*2,y.r/1.1);else if(y.shape==="dot")d.beginPath(),d.arc(0,0,y.r,0,Math.PI*2),d.fill();else {let i=Math.min(1,P/220);Pe(d,y.r*(i<1?i:1-Math.max(0,(P-y.life*.6)/(y.life*.4))*.6));}d.restore();}V<x?M=requestAnimationFrame(N):I();};return M=requestAnimationFrame(N),I};var Y=globalThis,le,K=(le=Y.__mrrocketI18n)!=null?le:Y.__mrrocketI18n={version:0,onWords:new Set,onLocale:new Set};var f=e=>{var t;return ((t=K.words)==null?void 0:t[e])||e},T=(e,t)=>f(e).replace(/\{(\w+)\}/g,(o,s)=>s in t?String(t[s]):o);var de=()=>{var e,t;return (t=(e=K.locale)!=null?e:K.device)!=null?t:typeof navigator!="undefined"&&navigator.language||void 0};var fe=()=>K.lang;var J=e=>(K.onWords.add(e),()=>{K.onWords.delete(e);});var U="other:",Q=e=>{var s,c;let t=(s=e==null?void 0:e.min)!=null?s:0,o=(c=e==null?void 0:e.max)!=null?c:10;return Array.from({length:Math.max(0,Math.min(o-t,20)+1)},(m,h)=>t+h)},pe=(e,t)=>{var o;return !e||t==null?false:e.type==="choice"?e.other&&t.startsWith(U)?t.slice(U.length).trim().length>0:((o=e.options)!=null?o:[]).some(s=>s.id===t):e.type==="scale"?Q(e).some(s=>String(s)===t):t.trim().length>0&&t.length<=500};var X=e=>{let t=(e!=null?e:"").trim();if(!/^https?:\/\//i.test(t))return null;let o=t.match(/^https?:\/\/(?:www\.|m\.)?(?:youtube\.com\/(?:watch\?(?:.*&)?v=|embed\/|shorts\/|live\/)|youtu\.be\/|youtube-nocookie\.com\/embed\/)([\w-]{6,20})/i);return o?{kind:"iframe",src:`https://www.youtube-nocookie.com/embed/${o[1]}?rel=0`}:(o=t.match(/^https?:\/\/(?:www\.|player\.)?vimeo\.com\/(?:video\/)?(\d{4,12})/i),o?{kind:"iframe",src:`https://player.vimeo.com/video/${o[1]}?dnt=1`}:(o=t.match(/^https?:\/\/(?:www\.)?loom\.com\/(?:share|embed)\/([\w-]{8,64})/i),o?{kind:"iframe",src:`https://www.loom.com/embed/${o[1]}`}:/\.(mp4|webm|mov|m4v)(\?|#|$)/i.test(t)||/\/media\/uploads\//.test(t)?{kind:"file",src:t}:null))},ue=e=>{var o;let t=e.media;if(!(!t||t.kind!=="image"&&t.kind!=="video"||!/^https?:\/\//i.test((o=t.url)!=null?o:"")))return t.kind==="video"&&!X(t.url)?void 0:t};var ge=(e,t)=>Math.round(e*(1-t/100)*100)/100,G=(e,t)=>{try{return new Intl.NumberFormat(de(),{style:"currency",currency:t}).format(e)}catch(o){return `${e.toFixed(2)} ${t}`}},me=e=>e.kind==="contact"?f("Send to the team"):e.kind==="pause"?f("Pause instead"):e.kind==="downgrade"?f("Switch plan"):f("Accept offer"),Z=e=>e===1?f("1 month"):T("{n} months",{n:e}),ee=e=>T("for {months}",{months:Z(e)});var B={check:{label:"Check",paths:["M5 12.5l4.5 4.5L19 7.5"],emoji:"\u2705"},star:{label:"Star",paths:["M12 3.5l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z"],emoji:"\u2B50"},rocket:{label:"Rocket",paths:["M12 3c3 2 4.5 5.5 4 10l-2 3h-4l-2-3c-.5-4.5 1-8 4-10z","M8 13.5l-3 3 3.5.5","M16 13.5l3 3-3.5.5","M13.5 9.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z","M11 19.5v1.5M13 19.5v1.5"],emoji:"\u{1F680}"},user:{label:"Person",paths:["M15.5 8a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z","M5 20c.8-3.5 3.6-5.5 7-5.5s6.2 2 7 5.5"],emoji:"\u{1F464}"},users:{label:"Team",paths:["M13 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z","M3.5 19c.6-3 3-4.8 6.5-4.8s5.9 1.8 6.5 4.8","M16 5.2a3 3 0 0 1 0 5.6","M18 14.6c1.5.6 2.4 2 2.7 4.4"],emoji:"\u{1F465}"},settings:{label:"Settings",paths:["M12 2.8v2.4M12 18.8v2.4M2.8 12h2.4M18.8 12h2.4M5.5 5.5l1.7 1.7M16.8 16.8l1.7 1.7M5.5 18.5l1.7-1.7M16.8 7.2l1.7-1.7","M17 12a5 5 0 1 1-10 0 5 5 0 0 1 10 0z","M14 12a2 2 0 1 1-4 0 2 2 0 0 1 4 0z"],emoji:"\u2699\uFE0F"},bell:{label:"Bell",paths:["M6 16v-5a6 6 0 0 1 12 0v5l1.5 2h-15z","M10 20.5a2 2 0 0 0 4 0"],emoji:"\u{1F514}"},mail:{label:"Mail",paths:["M4 6h16v12H4z","M4 7l8 6 8-6"],emoji:"\u2709\uFE0F"},chat:{label:"Chat",paths:["M4 5h16v11H9l-5 4z"],emoji:"\u{1F4AC}"},heart:{label:"Heart",paths:["M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z"],emoji:"\u2764\uFE0F"},flag:{label:"Flag",paths:["M5 21V4","M5 4h11l-2 4 2 4H5"],emoji:"\u{1F6A9}"},bolt:{label:"Bolt",paths:["M13 3L5 13.5h6L10 21l8-10.5h-6z"],emoji:"\u26A1"},book:{label:"Book",paths:["M4 5.5C6.5 4 9.5 4 12 6c2.5-2 5.5-2 8-.5V19c-2.5-1.5-5.5-1.5-8 .5-2.5-2-5.5-2-8-.5z","M12 6v13.5"],emoji:"\u{1F4D6}"},calendar:{label:"Calendar",paths:["M4 6h16v14H4z","M4 10h16","M8 3.5v4M16 3.5v4"],emoji:"\u{1F4C5}"},camera:{label:"Camera",paths:["M4 8h3.5L9 5.5h6L16.5 8H20v11H4z","M15.5 13a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z"],emoji:"\u{1F4F7}"},cart:{label:"Cart",paths:["M3.5 4.5H6l2 10h10l2-7H7","M9.5 19.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z","M18.5 19.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"],emoji:"\u{1F6D2}"},chart:{label:"Chart",paths:["M4 20h16","M7 16v-4M12 16V8M17 16V9"],emoji:"\u{1F4CA}"},gift:{label:"Gift",paths:["M4 10h16v10H4z","M3 7h18v3H3z","M12 7v13","M12 7c-1.5-3-5-3-5-1s3.5 1 5 1z","M12 7c1.5-3 5-3 5-1s-3.5 1-5 1z"],emoji:"\u{1F381}"},home:{label:"Home",paths:["M4 11l8-7 8 7","M6 9.5V20h12V9.5","M10 20v-6h4v6"],emoji:"\u{1F3E0}"},link:{label:"Link",paths:["M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1","M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"],emoji:"\u{1F517}"},lock:{label:"Lock",paths:["M6 11h12v9H6z","M8.5 11V8a3.5 3.5 0 0 1 7 0v3"],emoji:"\u{1F512}"},pencil:{label:"Pencil",paths:["M4 20l1-4L16 5l3 3L8 19z","M14 7l3 3"],emoji:"\u270F\uFE0F"},plus:{label:"Plus",paths:["M12 5v14M5 12h14"],emoji:"\u2795"},search:{label:"Search",paths:["M16 10.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z","M14.5 14.5L20 20"],emoji:"\u{1F50D}"},upload:{label:"Upload",paths:["M12 15V4","M7.5 8.5L12 4l4.5 4.5","M4 15v5h16v-5"],emoji:"\u2B06\uFE0F"},play:{label:"Play",paths:["M8 5l11 7-11 7z"],emoji:"\u25B6\uFE0F"},sparkle:{label:"Sparkle",paths:["M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z","M19 16l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7z"],emoji:"\u2728"},globe:{label:"Globe",paths:["M20 12a8 8 0 1 1-16 0 8 8 0 0 1 16 0z","M4 12h16","M12 4c2.2 2.2 3.3 4.9 3.3 8s-1.1 5.8-3.3 8c-2.2-2.2-3.3-4.9-3.3-8S9.8 6.2 12 4z"],emoji:"\u{1F310}"}},ke=e=>{if(e){if(e.kind==="builtin")return e.name&&B[e.name]?e:void 0;if(e.kind==="emoji")return e.value&&e.value.trim()&&[...e.value.trim()].length<=8?e:void 0;if(e.kind==="image")return e.url&&/^https?:\/\//i.test(e.url)?e:void 0}};var he="ckf-styles",Se=`
2
2
  .ckf-root{--ckf-accent:#3f76ff;--ckf-accent-ink:#fff;--ckf-bg:#fff;--ckf-fg:#1c1d20;--ckf-muted:#5d6068;--ckf-soft:#f4f5f7;--ckf-line:#e4e5e8;--ckf-danger:#d92d20;--ckf-radius:14px;--ckf-font:inherit;--ckf-shadow:0 16px 40px -12px rgba(16,18,24,.28),0 0 0 1px rgba(16,18,24,.07)}
3
3
  .ckf-root[data-theme=dark]{--ckf-bg:#17181b;--ckf-fg:#f1f2f4;--ckf-muted:#a9acb3;--ckf-soft:#232428;--ckf-line:#2e2f35;--ckf-shadow:0 16px 40px -12px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.08)}
4
4
  @media (prefers-color-scheme:dark){.ckf-root[data-theme=auto]{--ckf-bg:#17181b;--ckf-fg:#f1f2f4;--ckf-muted:#a9acb3;--ckf-soft:#232428;--ckf-line:#2e2f35;--ckf-shadow:0 16px 40px -12px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.08)}}
@@ -88,5 +88,5 @@
88
88
  .ckf-banner{animation-name:ckf-fade}
89
89
  @media (max-width:520px){.ckf-scrim{align-items:flex-end;padding:0}.ckf-scrim .ckf-card{max-width:none;border-radius:var(--ckf-radius) var(--ckf-radius) 0 0;max-height:92dvh}.ckf-float{right:12px;bottom:12px}}
90
90
  @media (prefers-reduced-motion:reduce){.ckf-root *{animation:none!important;transition:none!important}}
91
- `,n=(e,t={},...o)=>{let s=document.createElement(e);for(let[c,m]of Object.entries(t))m===void 0||m===false||(typeof m=="function"?s.addEventListener(c.slice(2).toLowerCase(),m):c==="className"?s.className=String(m):s.setAttribute(c,m===true?"":m));for(let c of o)(c||c==="")&&s.append(typeof c=="string"?document.createTextNode(c):c);return s},L=(e,t,o,s={})=>n("button",{type:"button",className:`ckf-btn${t==="secondary"?"":` ckf-${t}`}`,disabled:!!s.disabled,"data-ckf-id":s.id,onClick:()=>o()},e),W=(e,t)=>n("button",{type:"button",className:"ckf-x","aria-label":e,"data-ckf-id":"x",onClick:()=>t()},"\xD7"),ne=(e,t)=>t>1?n("span",{className:"ckf-dots",role:"img","aria-label":I("Step {n} of {total}",{n:e,total:t})},...Array.from({length:t},(o,s)=>n("span",{className:"ckf-dot","data-on":s<e}))):n("span"),be=e=>{var t;return e.type==="cancel"?`c:${e.screen}:${(t=e.round)!=null?t:1}`:e.type==="step"?`s:${e.step.id}`:e.type==="checklist"?`l:${e.flow.id}`:`m:${e.message.id}`},Re=e=>e.type==="cancel"?"c":e.type==="step"&&(e.step.kind==="question"||e.step.kind==="modal")?`d:${e.flow.id}`:be(e),we=e=>{var o;if(!document.getElementById(he)){let s=document.createElement("style");s.id=he,s.textContent=Se,document.head.appendChild(s);}let t=n("div",{className:`ckf-root${e.className?` ${e.className}`:""}`,"data-theme":(o=e.theme)!=null?o:"auto"});return e.accent&&t.style.setProperty("--ckf-accent",e.accent),document.body.appendChild(t),t},xe=e=>{let t=fe();t?e.setAttribute("lang",t):e.removeAttribute("lang");},te=(e,t)=>{let o=ke(e);if(!o)return false;let s=n("span",{className:t,"aria-hidden":"true"});if(o.kind==="emoji")s.textContent=o.value;else if(o.kind==="image")s.append(n("img",{src:o.url,alt:""}));else {let c="http://www.w3.org/2000/svg",m=document.createElementNS(c,"svg");for(let[h,d]of Object.entries({viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}))m.setAttribute(h,d);for(let h of B[o.name].paths){let d=document.createElementNS(c,"path");d.setAttribute("d",h),m.append(d);}s.append(m);}return s},ye=(e,t={})=>{if(typeof document=="undefined")return ()=>{};let o=we(t),s="",c="",m="",h=null,d="",w=null,l=r=>{var g,O,$;let i="ckf-title",a=r.busy,u=[];if(r.screen==="survey")u.push(n("h2",{className:"ckf-h",id:i},r.flow.question||f("Why are you leaving?")),n("div",{className:"ckf-opts",role:"radiogroup","aria-labelledby":i},...r.flow.reasons.map(p=>n("button",{type:"button",role:"radio",className:"ckf-opt","aria-checked":String(r.reason===p.id),"data-ckf-id":`r:${p.id}`,onClick:()=>e.cancel.pick(p.id)},n("span",{className:"ckf-radio"}),p.label))),n("div",{className:"ckf-btns"},L(f("Continue"),"primary",e.cancel.next,{disabled:!r.reason,id:"go"}),L(f("Never mind, keep my plan"),"quiet",e.cancel.close)));else if(r.screen==="followup"&&r.followUp){let p=r.followUp,C;if(p.answers.length)C=n("div",{className:"ckf-opts",role:"radiogroup","aria-labelledby":i},...p.answers.map((F,b)=>{var S;return n("button",{type:"button",role:"radio",className:"ckf-opt","aria-checked":String(r.answer===F),"data-ckf-id":`a:${b}`,onClick:()=>e.cancel.answer(F)},n("span",{className:"ckf-radio"}),((S=p.answerLabels)==null?void 0:S[b])||F)}));else {let F=n("textarea",{className:"ckf-text",placeholder:f("Your answer (optional)"),"aria-labelledby":i,maxlength:"500","data-ckf-id":"answer",onInput:b=>e.cancel.answer(b.target.value)});F.value=(g=r.answer)!=null?g:"",C=F;}let v=(O=r.flow.reasons.find(F=>F.id===r.reason))==null?void 0:O.label;u.push(v?n("p",{className:"ckf-small"},I("You said: {label}",{label:v})):false,n("h2",{className:"ckf-h",id:i},p.question),C,n("div",{className:"ckf-btns"},L(f("Continue"),"primary",e.cancel.next,{id:"go"}),L(f("Never mind, keep my plan"),"quiet",e.cancel.close)));}else if(r.screen==="offer"&&r.offer){let p=r.offer,C=($=r.flow.reasons.find(b=>b.id===r.reason))==null?void 0:$.label,v=false;p.kind==="discount"&&p.percent&&(v=r.price?n("div",{className:"ckf-box"},n("span",{className:"ckf-big"},G(ge(r.price.amount,p.percent),r.price.currency)),n("span",{className:"ckf-strike"},G(r.price.amount,r.price.currency)),n("span",{className:"ckf-small"},`/${r.price.interval==="year"?f("year"):f("month")}${p.months?` ${ee(p.months)}`:""}`)):n("div",{className:"ckf-box"},n("span",{className:"ckf-big"},I("{percent}% off",{percent:p.percent})),p.months?n("span",{className:"ckf-small"},ee(p.months)):false)),p.kind==="pause"&&p.months&&(v=n("div",{className:"ckf-box"},n("span",{},I("Pause for up to {months}. Your data stays.",{months:Z(p.months)})))),p.kind==="downgrade"&&p.planName&&(v=n("div",{className:"ckf-box"},n("b",{},p.planName)));let F=p.kind==="contact"?n("textarea",{className:"ckf-text",placeholder:f("What would make you stay?"),"aria-label":f("Your message"),maxlength:"500","data-ckf-id":"comment",onInput:b=>d=b.target.value}):null;F&&(F.value=d),u.push(C?n("p",{className:"ckf-small"},I("You said: {label}",{label:C})):false,n("h2",{className:"ckf-h",id:i},p.headline),v,F!=null?F:false,n("div",{className:"ckf-btns"},L(a?f("One moment\u2026"):me(p),"primary",()=>e.cancel.accept(d),{disabled:a,id:"go"}),L(f("No thanks, continue cancelling"),"quiet",e.cancel.decline,{disabled:a})));}else {let C=r.steps===1?null:n("textarea",{className:"ckf-text",placeholder:f("Anything else we should know? (optional)"),"aria-label":f("Anything else we should know? (optional)"),maxlength:"500","data-ckf-id":"comment",onInput:v=>d=v.target.value});C&&(C.value=d),u.push(n("h2",{className:"ckf-h",id:i},r.flow.confirm.title),r.flow.confirm.body?n("p",{className:"ckf-p"},r.flow.confirm.body):false,C!=null?C:false,n("div",{className:"ckf-btns"},L(a?f("One moment\u2026"):r.flow.confirm.button,"danger",()=>e.cancel.confirm(d),{disabled:a,id:"go"}),L(f("Keep my plan"),"secondary",e.cancel.close,{disabled:a})));}return n("div",{className:"ckf-scrim",onClick:p=>p.target===p.currentTarget&&!a&&e.cancel.close()},n("div",{className:"ckf-card",role:"dialog","aria-modal":"true","aria-labelledby":i},n("div",{className:"ckf-top"},ne(r.step,r.steps),W(f("Close"),e.cancel.close)),...u,r.error?n("p",{className:"ckf-err",role:"alert"},r.error):false))},x=r=>{var u;let i=ue(r);if(!i)return false;if(i.kind==="image")return n("img",{className:"ckf-media",src:i.url,alt:(u=i.alt)!=null?u:"",onLoad:()=>P()});let a=X(i.url);return a.kind==="iframe"?n("div",{className:"ckf-video"},n("iframe",{src:a.src,title:i.alt||f("Video"),allow:"fullscreen; picture-in-picture",allowfullscreen:true,loading:"lazy",referrerpolicy:"strict-origin-when-cross-origin"})):n("video",{className:"ckf-media",src:a.src,controls:true,playsinline:true,preload:"metadata","aria-label":i.alt||void 0,onLoadedmetadata:()=>P()})},k=r=>{var C,v,F;let i=r.step,a=i.question,u="ckf-title",g=pe(a,r.answer),O=false,$=(b,S,_)=>{let A=n("input",{type:"text",className:"ckf-input",placeholder:b,"aria-labelledby":u,maxlength:"500","data-ckf-id":"answer",onInput:j=>_(j.target.value),onKeydown:j=>j.key==="Enter"&&e.onboarding.next()});return A.value=S,A},p=(b,S,_,A)=>n("button",{type:"button",role:"radio",className:"ckf-opt","aria-checked":String(b),"data-ckf-id":`q:${S}`,onClick:A},n("span",{className:"ckf-radio"}),_);if((a==null?void 0:a.type)==="choice"){let b=!!a.other&&!!((C=r.answer)!=null&&C.startsWith(U));O=n("div",{className:"ckf-opts",role:"radiogroup","aria-labelledby":u},...((v=a.options)!=null?v:[]).map(S=>p(r.answer===S.id,S.id,S.label,()=>e.onboarding.answer(S.id))),a.other?p(b,"other",a.otherLabel||f("Other"),()=>b||e.onboarding.answer(U)):false,b?$(f("Your answer"),r.answer.slice(U.length),S=>e.onboarding.answer(U+S)):false);}else (a==null?void 0:a.type)==="scale"?O=n("div",{},n("div",{className:"ckf-scale",role:"radiogroup","aria-labelledby":u},...Q(a).map(b=>n("button",{type:"button",role:"radio",className:"ckf-num","aria-checked":String(r.answer===String(b)),"data-ckf-id":`q:${b}`,onClick:()=>e.onboarding.answer(String(b))},String(b)))),a.lowLabel||a.highLabel?n("div",{className:"ckf-ends ckf-small"},n("span",{},a.lowLabel||""),n("span",{},a.highLabel||"")):false):a&&(O=$(a.placeholder||f("Your answer"),(F=r.answer)!=null?F:"",b=>e.onboarding.answer(b)));return n("div",{className:"ckf-scrim"},n("div",{className:"ckf-card",role:"dialog","aria-modal":"true","aria-labelledby":u},n("div",{className:"ckf-top"},ne(r.index+1,r.total),W(f("Close"),e.onboarding.dismiss)),r.index===0?te(r.flow.icon,"ckf-hic"):false,n("h2",{className:"ckf-h",id:u},i.title),i.body?n("p",{className:"ckf-p"},i.body):false,O,n("div",{className:"ckf-row"},r.back?L(f("Back"),"quiet",e.onboarding.back):false,a!=null&&a.optional?L(a.skipLabel||f("Skip"),"quiet",e.onboarding.skip):false,L(i.button||(r.last?f("Done"):f("Continue")),"primary",e.onboarding.next,{disabled:!g,id:"go"}))))},M=r=>{let i=r.step;if(i.kind==="question")return k(r);let a=n("div",{className:"ckf-card",role:"dialog","aria-modal":i.kind==="modal"?"true":void 0,"aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},r.total>1?n("p",{className:"ckf-small"},I("Step {n} of {total}",{n:r.index+1,total:r.total})):n("span"),W(f("Close the tour"),e.onboarding.dismiss)),i.kind==="modal"?te(r.flow.icon,"ckf-hic"):false,x(i),n("h2",{className:"ckf-h",id:"ckf-title"},i.title),i.body?n("p",{className:"ckf-p"},i.body):false,n("div",{className:"ckf-row"},L(i.button||(r.last?f("Done"):f("Next")),"primary",e.onboarding.next,{id:"go"})));if(i.kind==="modal")return n("div",{className:"ckf-scrim"},a);let u=i.target?E(i.target):null,g=n("div",{className:"ckf-float"},a);if(u){let O=n("div",{className:"ckf-ring","aria-hidden":"true"});return g.append(n("span",{className:"ckf-arrow","aria-hidden":"true"})),w={float:g,ring:O,target:u,side:i.placement},T(g,O,u,i.placement),n("div",{},O,g)}return g},E=r=>{var a;let i=()=>document.querySelector(`[data-ck-target="${CSS.escape(r)}"]`);return /^[#.[]|[\s>:=]/.test(r)&&(a=H(r))!=null?a:i()},H=r=>{try{return document.querySelector(r)}catch(i){return null}},T=(r,i,a,u="auto")=>{var se;let g=a.getBoundingClientRect();Object.assign(i.style,{left:`${g.left-4}px`,top:`${g.top-4}px`,width:`${g.width+8}px`,height:`${g.height+8}px`});let O=window.innerWidth,$=window.innerHeight,p=Math.min(340,O-24),C=r.offsetHeight||200,v=14,F={bottom:$-g.bottom-v-12>=C,top:g.top-v-12>=C,right:O-g.right-v-12>=p,left:g.left-v-12>=p},b={top:"bottom",bottom:"top",left:"right",right:"left"},_=(se=(u==="auto"||!b[u]?["bottom","top"]:[u,b[u],"bottom","top","right","left"]).find(D=>F[D]))!=null?se:u!=="auto"&&b[u]?u:g.top>$-g.bottom?"top":"bottom",A=(D,Oe)=>Math.max(12,Math.min(D,Oe-12)),j=_==="top"||_==="bottom",oe=j?A(u==="auto"?g.left:g.left+g.width/2-p/2,O-p):_==="right"?g.right+v:g.left-v-p,ie=j?_==="bottom"?g.bottom+v:g.top-v-C:A(g.top+g.height/2-C/2,$-C);Object.assign(r.style,{left:`${oe}px`,top:`${ie}px`,right:"auto",bottom:"auto",width:`${p}px`}),r.setAttribute("data-side",_);let Ne=j?g.left+g.width/2-oe:g.top+g.height/2-ie;r.style.setProperty("--ckf-ap",`${Math.max(18,Math.min(Ne,(j?p:C)-18))}px`);},N=r=>{let i=r.items.filter(a=>a.done).length;return n("div",{className:"ckf-float"},n("div",{className:"ckf-card",role:"region","aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},n("h2",{className:"ckf-h",id:"ckf-title"},r.flow.name),W(f("Hide the checklist"),e.onboarding.dismiss)),n("p",{className:"ckf-small"},I("{done} of {total} done",{done:i,total:r.items.length})),n("div",{className:"ckf-bar",role:"progressbar","aria-valuemin":"0","aria-valuemax":String(r.items.length),"aria-valuenow":String(i)},n("i",{style:`width:${i/r.items.length*100}%`})),n("div",{className:"ckf-opts"},...r.items.map(({step:a,done:u,opens:g})=>{let O=[n("span",{className:"ckf-tick","aria-hidden":"true"},u?"\u2713":""),te(a.icon,"ckf-ic"),n("span",{},n("b",{},a.title),a.body?n("span",{className:"ckf-small"},a.body):false)];return !u&&g?n("button",{type:"button",className:"ckf-check","aria-label":I("Start \u201C{title}\u201D",{title:a.title}),"data-ckf-id":`t:${a.id}`,onClick:()=>e.onboarding.open(a.id)},...O,n("span",{className:"ckf-go","aria-hidden":"true"},"\u203A")):u||a.event?n("div",{className:"ckf-check","data-done":u,role:"listitem"},...O):n("button",{type:"button",className:"ckf-check","aria-label":I("Mark \u201C{title}\u201D done",{title:a.title}),"data-ckf-id":`i:${a.id}`,onClick:()=>e.onboarding.check(a.id)},...O)}))))},z=r=>{let i=r.message,a=i.button?L(i.button,"primary",e.message.click,{id:"go"}):false;return i.style==="banner"?n("div",{className:"ckf-banner",role:"status"},n("span",{},n("b",{},i.title),i.body?n("span",{className:"ckf-small"},i.body):false),a,W(f("Dismiss"),e.message.dismiss)):n("div",{className:"ckf-scrim",onClick:u=>u.target===u.currentTarget&&e.message.dismiss()},n("div",{className:"ckf-card",role:"dialog","aria-modal":"true","aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},n("span"),W(f("Dismiss"),e.message.dismiss)),n("h2",{className:"ckf-h",id:"ckf-title"},i.title),i.body?n("p",{className:"ckf-p"},i.body):false,a?n("div",{className:"ckf-row"},a):false))},V=()=>{var $,p,C,v,F,b,S,_;let r=e.view();xe(o);let i=(p=t.accent)!=null?p:($=e.accent)==null?void 0:$.call(e);i&&o.style.setProperty("--ckf-accent",i);let a=(C=e.finale)==null?void 0:C.call(e);a&&a.key!==s&&(s=a.key,ce(a.kind,{accent:i}));let u=r?be(r):"",g=(F=(v=document.activeElement)==null?void 0:v.closest)!=null&&F.call(v,".ckf-root")?(b=document.activeElement)==null?void 0:b.getAttribute("data-ckf-id"):null;u&&!c&&document.activeElement instanceof HTMLElement&&!document.activeElement.closest(".ckf-root")&&(h=document.activeElement),u!==c&&!u.startsWith("c:")&&(d=""),u||(d=""),w=null;let O=r?Re(r):"";if(o.toggleAttribute("data-still",!!O&&O===m),m=O,o.replaceChildren(...r?[r.type==="cancel"?l(r):r.type==="step"?M(r):r.type==="checklist"?N(r):z(r)]:[]),P(),u!==c){let A=o.querySelector("[aria-modal=true]"),j=(S=A==null?void 0:A.querySelector("[role=radio], input, [data-ckf-id=go], textarea"))!=null?S:null;j==null||j.focus(),!u&&h&&(h.focus(),h=null);}else g&&((_=o.querySelector(`[data-ckf-id="${CSS.escape(g)}"]`))==null||_.focus());c=u;},y=r=>{if(r.key!=="Escape")return;let i=e.view();(i==null?void 0:i.type)==="cancel"?e.cancel.close():(i==null?void 0:i.type)==="message"?e.message.dismiss():(i==null?void 0:i.type)==="step"&&(i.step.kind==="modal"||i.step.kind==="question")&&e.onboarding.dismiss();};function P(){w&&T(w.float,w.ring,w.target,w.side);}document.addEventListener("keydown",y),window.addEventListener("resize",P),window.addEventListener("scroll",P,{passive:true,capture:true});let q=e.subscribe(V),R=J(V);return V(),()=>{q(),R(),document.removeEventListener("keydown",y),window.removeEventListener("resize",P),window.removeEventListener("scroll",P,{capture:true}),o.remove();}},ve=(e,t={})=>{if(typeof document=="undefined")return ()=>{};let o=we(t),s="",c=null,m=()=>{var E,H,T;let l=e.view();xe(o);let x=l?`${l.paywall.id}:${l.index}`:"";if(x&&!s&&document.activeElement instanceof HTMLElement&&(c=document.activeElement),!l){o.replaceChildren(),o.removeAttribute("data-still"),s&&(c==null||c.focus()),s="";return}s&&o.setAttribute("data-still","");let k=l.page,M=k.kind==="plans"?n("div",{className:"ckf-opts",role:"radiogroup","aria-label":f("Plans")},...l.plans.map(N=>n("button",{type:"button",role:"radio",className:"ckf-opt ckf-plan","aria-checked":String(l.plan===N.id),"data-ckf-id":`p:${N.id}`,onClick:()=>e.pick(N.id)},n("span",{className:"ckf-radio"}),n("span",{},N.name,N.note?n("span",{className:"ckf-small"},N.note):false),n("b",{},N.price)))):false;o.replaceChildren(n("div",{className:"ckf-scrim",onClick:N=>N.target===N.currentTarget&&e.close()},n("div",{className:"ckf-card ckf-pw",role:"dialog","aria-modal":"true","aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},ne(l.index+1,l.total),W(f("Close"),e.close)),n("h2",{className:"ckf-h",id:"ckf-title"},k.title),k.body?n("p",{className:"ckf-p"},k.body):false,k.kind==="benefits"&&((E=k.items)!=null&&E.length)?n("div",{className:"ckf-opts"},...k.items.map(N=>n("p",{className:"ckf-li"},N))):false,k.kind==="proof"&&((H=k.quotes)!=null&&H.length)?n("div",{className:"ckf-opts"},...k.quotes.map(N=>n("blockquote",{className:"ckf-quote"},N.text,N.by?n("cite",{},N.by):false))):false,M,l.error?n("p",{className:"ckf-err",role:"alert"},l.error):false,n("div",{className:"ckf-btns"},L(l.busy?f("One moment\u2026"):k.button||f("Continue"),"primary",e.next,{disabled:l.busy||k.kind==="plans"&&!l.plan,id:"go"}),l.index?L(f("Back"),"quiet",e.back,{disabled:l.busy}):false)))),x!==s&&((T=o.querySelector("[data-ckf-id=go]"))==null||T.focus()),s=x;},h=l=>{e.view()&&l.key==="Escape"&&e.close();};document.addEventListener("keydown",h);let d=e.subscribe(m),w=J(m);return m(),()=>{d(),w(),document.removeEventListener("keydown",h),o.remove();}};var Le=e=>{let t=2166136261;for(let o=0;o<e.length;o++)t^=e.charCodeAt(o),t=Math.imul(t,16777619);return (t>>>0)/4294967296};var Ce=(e,t)=>{var m,h,d,w;let o=(h=(m=e.variants[0])==null?void 0:m.id)!=null?h:"control";if(e.winner)return e.winner;if(e.status!=="running")return o;let s=Le(`${e.key}:${t}`),c=0;for(let l of e.variants)if(c+=l.weight,s<c)return l.id;return (w=(d=e.variants[e.variants.length-1])==null?void 0:d.id)!=null?w:o};var re="$paywall",Ie=(e,t,o)=>{var h,d;let s=t.experiment?e==null?void 0:e.experiments.find(w=>w.key===t.experiment):void 0,c=s?Ce(s,o):(h=t.variants[0])==null?void 0:h.id,m=(d=t.variants.find(w=>w.id===c))!=null?d:t.variants[0];return m?{variant:m.id,pages:m.pages,test:(s==null?void 0:s.status)==="running"&&!s.winner?s.key:void 0}:null},Me=e=>{let t=null,o=new Set,s=()=>{for(let l of [...o])try{l();}catch(x){}},c=()=>t?{paywall:t.w.id,placement:t.w.placement,variant:t.variant}:{},m=()=>{t&&!t.seen.has(t.index)&&(t.seen.add(t.index),e.track(re,{...c(),page:t.pages[t.index].id,index:t.index,action:"page"})),s();},h=l=>{var k,M;let x=t;x&&(t=null,l.outcome==="closed"&&((M=(k=x.options).onClose)==null||M.call(k,l)),x.resolve(l),s());},d=l=>{var x;return {outcome:l,index:(x=t==null?void 0:t.index)!=null?x:0,...t?{paywall:t.w.id,variant:t.variant}:{},...l!=="closed"&&t?{plan:t.plans.find(k=>k.id===t.plan)}:{}}},w=()=>{let l=t,x=l==null?void 0:l.plans.find(k=>k.id===l.plan);if(!(!l||!x||l.busy)){if(!l.options.onPurchase)return h(d("chosen"));l.busy=true,l.error=void 0,s(),Promise.resolve().then(()=>{var k,M;return (M=(k=l.options).onPurchase)==null?void 0:M.call(k,x)}).then(k=>{if(l.busy=false,t===l){if(k===false)return s();e.track(re,{...c(),page:l.pages[l.index].id,index:l.index,plan:x.id,action:"purchased"}),h(d("purchased"));}},()=>{l.busy=false,l.error=f("The purchase did not go through. Please try again."),s();});}};return {open:(l,x={})=>{var y,P,q;if(t)return t.promise;let k=e.config(),M=(y=k==null?void 0:k.paywalls)==null?void 0:y.find(R=>R.placement===l),E=M?Ie(k,M,e.distinctId()):null;if(!M||!(E!=null&&E.pages.length))return Promise.resolve({outcome:"closed",index:0});let H=new Map(((P=x.plans)!=null?P:[]).map(R=>[R.id,R])),T=M.plans.map(R=>{var r;return (r=H.get(R.id))!=null?r:R}),N=()=>{},z=new Promise(R=>N=R),V=T.some(R=>R.id===M.highlight)?M.highlight:(q=T[0])==null?void 0:q.id;return t={w:M,variant:E.variant,pages:E.pages,plans:T,index:0,plan:V,busy:false,seen:new Set,options:x,resolve:N,promise:z},E.test&&e.track("$exposure",{experiment:E.test,variant:E.variant}),m(),z},view:()=>t?{paywall:t.w,variant:t.variant,page:t.pages[t.index],index:t.index,total:t.pages.length,last:t.index===t.pages.length-1,plans:t.plans,plan:t.plan,busy:t.busy,error:t.error}:null,subscribe:l=>(o.add(l),()=>o.delete(l)),next:()=>{if(!(!t||t.busy)){if(t.pages[t.index].kind==="plans"||t.index===t.pages.length-1)return w();t.index++,t.error=void 0,m();}},back:()=>{!t||t.busy||!t.index||(t.index--,t.error=void 0,s());},pick:l=>{!t||t.busy||!t.plans.some(x=>x.id===l)||(t.plan=l,t.error=void 0,s());},close:()=>{!t||t.busy||(e.track(re,{...c(),index:t.index,action:"closed"}),h(d("closed")));}}};var Te=(e,t)=>{let o=Me(e);return ve(o,t),o};window.__mrrocketFlows={mountFlows:ye,paywallHost:Te};
91
+ `,n=(e,t={},...o)=>{let s=document.createElement(e);for(let[c,m]of Object.entries(t))m===void 0||m===false||(typeof m=="function"?s.addEventListener(c.slice(2).toLowerCase(),m):c==="className"?s.className=String(m):s.setAttribute(c,m===true?"":m));for(let c of o)(c||c==="")&&s.append(typeof c=="string"?document.createTextNode(c):c);return s},L=(e,t,o,s={})=>n("button",{type:"button",className:`ckf-btn${t==="secondary"?"":` ckf-${t}`}`,disabled:!!s.disabled,"data-ckf-id":s.id,onClick:()=>o()},e),W=(e,t)=>n("button",{type:"button",className:"ckf-x","aria-label":e,"data-ckf-id":"x",onClick:()=>t()},"\xD7"),ne=(e,t)=>t>1?n("span",{className:"ckf-dots",role:"img","aria-label":T("Step {n} of {total}",{n:e,total:t})},...Array.from({length:t},(o,s)=>n("span",{className:"ckf-dot","data-on":s<e}))):n("span"),be=e=>{var t;return e.type==="cancel"?`c:${e.screen}:${(t=e.round)!=null?t:1}`:e.type==="step"?`s:${e.step.id}`:e.type==="checklist"?`l:${e.flow.id}`:`m:${e.message.id}`},Re=e=>e.type==="cancel"?"c":e.type==="step"&&(e.step.kind==="question"||e.step.kind==="modal")?`d:${e.flow.id}`:be(e),we=e=>{var o;if(!document.getElementById(he)){let s=document.createElement("style");s.id=he,s.textContent=Se,document.head.appendChild(s);}let t=n("div",{className:`ckf-root${e.className?` ${e.className}`:""}`,"data-theme":(o=e.theme)!=null?o:"auto"});return e.accent&&t.style.setProperty("--ckf-accent",e.accent),document.body.appendChild(t),t},xe=e=>{let t=fe();t?e.setAttribute("lang",t):e.removeAttribute("lang");},te=(e,t)=>{let o=ke(e);if(!o)return false;let s=n("span",{className:t,"aria-hidden":"true"});if(o.kind==="emoji")s.textContent=o.value;else if(o.kind==="image")s.append(n("img",{src:o.url,alt:""}));else {let c="http://www.w3.org/2000/svg",m=document.createElementNS(c,"svg");for(let[h,d]of Object.entries({viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}))m.setAttribute(h,d);for(let h of B[o.name].paths){let d=document.createElementNS(c,"path");d.setAttribute("d",h),m.append(d);}s.append(m);}return s},ye=(e,t={})=>{if(typeof document=="undefined")return ()=>{};let o=we(t),s="",c="",m="",h=null,d="",w=null,l=r=>{var g,O,$;let i="ckf-title",a=r.busy,u=[];if(r.screen==="survey")u.push(n("h2",{className:"ckf-h",id:i},r.flow.question||f("Why are you leaving?")),n("div",{className:"ckf-opts",role:"radiogroup","aria-labelledby":i},...r.flow.reasons.map(p=>n("button",{type:"button",role:"radio",className:"ckf-opt","aria-checked":String(r.reason===p.id),"data-ckf-id":`r:${p.id}`,onClick:()=>e.cancel.pick(p.id)},n("span",{className:"ckf-radio"}),p.label))),n("div",{className:"ckf-btns"},L(f("Continue"),"primary",e.cancel.next,{disabled:!r.reason,id:"go"}),L(f("Never mind, keep my plan"),"quiet",e.cancel.close)));else if(r.screen==="followup"&&r.followUp){let p=r.followUp,C;if(p.answers.length)C=n("div",{className:"ckf-opts",role:"radiogroup","aria-labelledby":i},...p.answers.map((F,b)=>{var S;return n("button",{type:"button",role:"radio",className:"ckf-opt","aria-checked":String(r.answer===F),"data-ckf-id":`a:${b}`,onClick:()=>e.cancel.answer(F)},n("span",{className:"ckf-radio"}),((S=p.answerLabels)==null?void 0:S[b])||F)}));else {let F=n("textarea",{className:"ckf-text",placeholder:f("Your answer (optional)"),"aria-labelledby":i,maxlength:"500","data-ckf-id":"answer",onInput:b=>e.cancel.answer(b.target.value)});F.value=(g=r.answer)!=null?g:"",C=F;}let v=(O=r.flow.reasons.find(F=>F.id===r.reason))==null?void 0:O.label;u.push(v?n("p",{className:"ckf-small"},T("You said: {label}",{label:v})):false,n("h2",{className:"ckf-h",id:i},p.question),C,n("div",{className:"ckf-btns"},L(f("Continue"),"primary",e.cancel.next,{id:"go"}),L(f("Never mind, keep my plan"),"quiet",e.cancel.close)));}else if(r.screen==="offer"&&r.offer){let p=r.offer,C=($=r.flow.reasons.find(b=>b.id===r.reason))==null?void 0:$.label,v=false;p.kind==="discount"&&p.percent&&(v=r.price?n("div",{className:"ckf-box"},n("span",{className:"ckf-big"},G(ge(r.price.amount,p.percent),r.price.currency)),n("span",{className:"ckf-strike"},G(r.price.amount,r.price.currency)),n("span",{className:"ckf-small"},`/${r.price.interval==="year"?f("year"):f("month")}${p.months?` ${ee(p.months)}`:""}`)):n("div",{className:"ckf-box"},n("span",{className:"ckf-big"},T("{percent}% off",{percent:p.percent})),p.months?n("span",{className:"ckf-small"},ee(p.months)):false)),p.kind==="pause"&&p.months&&(v=n("div",{className:"ckf-box"},n("span",{},T("Pause for up to {months}. Your data stays.",{months:Z(p.months)})))),p.kind==="downgrade"&&p.planName&&(v=n("div",{className:"ckf-box"},n("b",{},p.planName)));let F=p.kind==="contact"?n("textarea",{className:"ckf-text",placeholder:f("What would make you stay?"),"aria-label":f("Your message"),maxlength:"500","data-ckf-id":"comment",onInput:b=>d=b.target.value}):null;F&&(F.value=d),u.push(C?n("p",{className:"ckf-small"},T("You said: {label}",{label:C})):false,n("h2",{className:"ckf-h",id:i},p.headline),v,F!=null?F:false,n("div",{className:"ckf-btns"},L(a?f("One moment\u2026"):me(p),"primary",()=>e.cancel.accept(d),{disabled:a,id:"go"}),L(f("No thanks, continue cancelling"),"quiet",e.cancel.decline,{disabled:a})));}else {let C=r.steps===1?null:n("textarea",{className:"ckf-text",placeholder:f("Anything else we should know? (optional)"),"aria-label":f("Anything else we should know? (optional)"),maxlength:"500","data-ckf-id":"comment",onInput:v=>d=v.target.value});C&&(C.value=d),u.push(n("h2",{className:"ckf-h",id:i},r.flow.confirm.title),r.flow.confirm.body?n("p",{className:"ckf-p"},r.flow.confirm.body):false,C!=null?C:false,n("div",{className:"ckf-btns"},L(a?f("One moment\u2026"):r.flow.confirm.button,"danger",()=>e.cancel.confirm(d),{disabled:a,id:"go"}),L(f("Keep my plan"),"secondary",e.cancel.close,{disabled:a})));}return n("div",{className:"ckf-scrim",onClick:p=>p.target===p.currentTarget&&!a&&e.cancel.close()},n("div",{className:"ckf-card",role:"dialog","aria-modal":"true","aria-labelledby":i},n("div",{className:"ckf-top"},ne(r.step,r.steps),W(f("Close"),e.cancel.close)),...u,r.error?n("p",{className:"ckf-err",role:"alert"},r.error):false))},x=r=>{var u;let i=ue(r);if(!i)return false;if(i.kind==="image")return n("img",{className:"ckf-media",src:i.url,alt:(u=i.alt)!=null?u:"",onLoad:()=>P()});let a=X(i.url);return a.kind==="iframe"?n("div",{className:"ckf-video"},n("iframe",{src:a.src,title:i.alt||f("Video"),allow:"fullscreen; picture-in-picture",allowfullscreen:true,loading:"lazy",referrerpolicy:"strict-origin-when-cross-origin"})):n("video",{className:"ckf-media",src:a.src,controls:true,playsinline:true,preload:"metadata","aria-label":i.alt||void 0,onLoadedmetadata:()=>P()})},k=r=>{var C,v,F;let i=r.step,a=i.question,u="ckf-title",g=pe(a,r.answer),O=false,$=(b,S,_)=>{let A=n("input",{type:"text",className:"ckf-input",placeholder:b,"aria-labelledby":u,maxlength:"500","data-ckf-id":"answer",onInput:j=>_(j.target.value),onKeydown:j=>j.key==="Enter"&&e.onboarding.next()});return A.value=S,A},p=(b,S,_,A)=>n("button",{type:"button",role:"radio",className:"ckf-opt","aria-checked":String(b),"data-ckf-id":`q:${S}`,onClick:A},n("span",{className:"ckf-radio"}),_);if((a==null?void 0:a.type)==="choice"){let b=!!a.other&&!!((C=r.answer)!=null&&C.startsWith(U));O=n("div",{className:"ckf-opts",role:"radiogroup","aria-labelledby":u},...((v=a.options)!=null?v:[]).map(S=>p(r.answer===S.id,S.id,S.label,()=>e.onboarding.answer(S.id))),a.other?p(b,"other",a.otherLabel||f("Other"),()=>b||e.onboarding.answer(U)):false,b?$(f("Your answer"),r.answer.slice(U.length),S=>e.onboarding.answer(U+S)):false);}else (a==null?void 0:a.type)==="scale"?O=n("div",{},n("div",{className:"ckf-scale",role:"radiogroup","aria-labelledby":u},...Q(a).map(b=>n("button",{type:"button",role:"radio",className:"ckf-num","aria-checked":String(r.answer===String(b)),"data-ckf-id":`q:${b}`,onClick:()=>e.onboarding.answer(String(b))},String(b)))),a.lowLabel||a.highLabel?n("div",{className:"ckf-ends ckf-small"},n("span",{},a.lowLabel||""),n("span",{},a.highLabel||"")):false):a&&(O=$(a.placeholder||f("Your answer"),(F=r.answer)!=null?F:"",b=>e.onboarding.answer(b)));return n("div",{className:"ckf-scrim"},n("div",{className:"ckf-card",role:"dialog","aria-modal":"true","aria-labelledby":u},n("div",{className:"ckf-top"},ne(r.index+1,r.total),W(f("Close"),e.onboarding.dismiss)),r.index===0?te(r.flow.icon,"ckf-hic"):false,n("h2",{className:"ckf-h",id:u},i.title),i.body?n("p",{className:"ckf-p"},i.body):false,O,n("div",{className:"ckf-row"},r.back?L(f("Back"),"quiet",e.onboarding.back):false,a!=null&&a.optional?L(a.skipLabel||f("Skip"),"quiet",e.onboarding.skip):false,L(i.button||(r.last?f("Done"):f("Continue")),"primary",e.onboarding.next,{disabled:!g,id:"go"}))))},M=r=>{let i=r.step;if(i.kind==="question")return k(r);let a=n("div",{className:"ckf-card",role:"dialog","aria-modal":i.kind==="modal"?"true":void 0,"aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},r.total>1?n("p",{className:"ckf-small"},T("Step {n} of {total}",{n:r.index+1,total:r.total})):n("span"),W(f("Close the tour"),e.onboarding.dismiss)),i.kind==="modal"?te(r.flow.icon,"ckf-hic"):false,x(i),n("h2",{className:"ckf-h",id:"ckf-title"},i.title),i.body?n("p",{className:"ckf-p"},i.body):false,n("div",{className:"ckf-row"},L(i.button||(r.last?f("Done"):f("Next")),"primary",e.onboarding.next,{id:"go"})));if(i.kind==="modal")return n("div",{className:"ckf-scrim"},a);let u=i.target?E(i.target):null,g=n("div",{className:"ckf-float"},a);if(u){let O=n("div",{className:"ckf-ring","aria-hidden":"true"});return g.append(n("span",{className:"ckf-arrow","aria-hidden":"true"})),w={float:g,ring:O,target:u,side:i.placement},I(g,O,u,i.placement),n("div",{},O,g)}return g},E=r=>{var a;let i=()=>document.querySelector(`[data-ck-target="${CSS.escape(r)}"]`);return /^[#.[]|[\s>:=]/.test(r)&&(a=H(r))!=null?a:i()},H=r=>{try{return document.querySelector(r)}catch(i){return null}},I=(r,i,a,u="auto")=>{var se;let g=a.getBoundingClientRect();Object.assign(i.style,{left:`${g.left-4}px`,top:`${g.top-4}px`,width:`${g.width+8}px`,height:`${g.height+8}px`});let O=window.innerWidth,$=window.innerHeight,p=Math.min(340,O-24),C=r.offsetHeight||200,v=14,F={bottom:$-g.bottom-v-12>=C,top:g.top-v-12>=C,right:O-g.right-v-12>=p,left:g.left-v-12>=p},b={top:"bottom",bottom:"top",left:"right",right:"left"},_=(se=(u==="auto"||!b[u]?["bottom","top"]:[u,b[u],"bottom","top","right","left"]).find(D=>F[D]))!=null?se:u!=="auto"&&b[u]?u:g.top>$-g.bottom?"top":"bottom",A=(D,Oe)=>Math.max(12,Math.min(D,Oe-12)),j=_==="top"||_==="bottom",oe=j?A(u==="auto"?g.left:g.left+g.width/2-p/2,O-p):_==="right"?g.right+v:g.left-v-p,ie=j?_==="bottom"?g.bottom+v:g.top-v-C:A(g.top+g.height/2-C/2,$-C);Object.assign(r.style,{left:`${oe}px`,top:`${ie}px`,right:"auto",bottom:"auto",width:`${p}px`}),r.setAttribute("data-side",_);let Ne=j?g.left+g.width/2-oe:g.top+g.height/2-ie;r.style.setProperty("--ckf-ap",`${Math.max(18,Math.min(Ne,(j?p:C)-18))}px`);},N=r=>{let i=r.items.filter(a=>a.done).length;return n("div",{className:"ckf-float"},n("div",{className:"ckf-card",role:"region","aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},n("h2",{className:"ckf-h",id:"ckf-title"},r.flow.name),W(f("Hide the checklist"),e.onboarding.dismiss)),n("p",{className:"ckf-small"},T("{done} of {total} done",{done:i,total:r.items.length})),n("div",{className:"ckf-bar",role:"progressbar","aria-valuemin":"0","aria-valuemax":String(r.items.length),"aria-valuenow":String(i)},n("i",{style:`width:${i/r.items.length*100}%`})),n("div",{className:"ckf-opts"},...r.items.map(({step:a,done:u,opens:g})=>{let O=[n("span",{className:"ckf-tick","aria-hidden":"true"},u?"\u2713":""),te(a.icon,"ckf-ic"),n("span",{},n("b",{},a.title),a.body?n("span",{className:"ckf-small"},a.body):false)];return !u&&g?n("button",{type:"button",className:"ckf-check","aria-label":T("Start \u201C{title}\u201D",{title:a.title}),"data-ckf-id":`t:${a.id}`,onClick:()=>e.onboarding.open(a.id)},...O,n("span",{className:"ckf-go","aria-hidden":"true"},"\u203A")):u||a.event?n("div",{className:"ckf-check","data-done":u,role:"listitem"},...O):n("button",{type:"button",className:"ckf-check","aria-label":T("Mark \u201C{title}\u201D done",{title:a.title}),"data-ckf-id":`i:${a.id}`,onClick:()=>e.onboarding.check(a.id)},...O)}))))},z=r=>{let i=r.message,a=i.button?L(i.button,"primary",e.message.click,{id:"go"}):false;return i.style==="banner"?n("div",{className:"ckf-banner",role:"status"},n("span",{},n("b",{},i.title),i.body?n("span",{className:"ckf-small"},i.body):false),a,W(f("Dismiss"),e.message.dismiss)):n("div",{className:"ckf-scrim",onClick:u=>u.target===u.currentTarget&&e.message.dismiss()},n("div",{className:"ckf-card",role:"dialog","aria-modal":"true","aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},n("span"),W(f("Dismiss"),e.message.dismiss)),n("h2",{className:"ckf-h",id:"ckf-title"},i.title),i.body?n("p",{className:"ckf-p"},i.body):false,a?n("div",{className:"ckf-row"},a):false))},V=()=>{var $,p,C,v,F,b,S,_;let r=e.view();xe(o);let i=(p=t.accent)!=null?p:($=e.accent)==null?void 0:$.call(e);i&&o.style.setProperty("--ckf-accent",i);let a=(C=e.finale)==null?void 0:C.call(e);a&&a.key!==s&&(s=a.key,ce(a.kind,{accent:i}));let u=r?be(r):"",g=(F=(v=document.activeElement)==null?void 0:v.closest)!=null&&F.call(v,".ckf-root")?(b=document.activeElement)==null?void 0:b.getAttribute("data-ckf-id"):null;u&&!c&&document.activeElement instanceof HTMLElement&&!document.activeElement.closest(".ckf-root")&&(h=document.activeElement),u!==c&&!u.startsWith("c:")&&(d=""),u||(d=""),w=null;let O=r?Re(r):"";if(o.toggleAttribute("data-still",!!O&&O===m),m=O,o.replaceChildren(...r?[r.type==="cancel"?l(r):r.type==="step"?M(r):r.type==="checklist"?N(r):z(r)]:[]),P(),u!==c){let A=o.querySelector("[aria-modal=true]"),j=(S=A==null?void 0:A.querySelector("[role=radio], input, [data-ckf-id=go], textarea"))!=null?S:null;j==null||j.focus(),!u&&h&&(h.focus(),h=null);}else g&&((_=o.querySelector(`[data-ckf-id="${CSS.escape(g)}"]`))==null||_.focus());c=u;},y=r=>{if(r.key!=="Escape")return;let i=e.view();(i==null?void 0:i.type)==="cancel"?e.cancel.close():(i==null?void 0:i.type)==="message"?e.message.dismiss():(i==null?void 0:i.type)==="step"&&(i.step.kind==="modal"||i.step.kind==="question")&&e.onboarding.dismiss();};function P(){w&&I(w.float,w.ring,w.target,w.side);}document.addEventListener("keydown",y),window.addEventListener("resize",P),window.addEventListener("scroll",P,{passive:true,capture:true});let q=e.subscribe(V),R=J(V);return V(),()=>{q(),R(),document.removeEventListener("keydown",y),window.removeEventListener("resize",P),window.removeEventListener("scroll",P,{capture:true}),o.remove();}},ve=(e,t={})=>{if(typeof document=="undefined")return ()=>{};let o=we(t),s="",c=null,m=()=>{var E,H,I;let l=e.view();xe(o);let x=l?`${l.paywall.id}:${l.index}`:"";if(x&&!s&&document.activeElement instanceof HTMLElement&&(c=document.activeElement),!l){o.replaceChildren(),o.removeAttribute("data-still"),s&&(c==null||c.focus()),s="";return}s&&o.setAttribute("data-still","");let k=l.page,M=k.kind==="plans"?n("div",{className:"ckf-opts",role:"radiogroup","aria-label":f("Plans")},...l.plans.map(N=>n("button",{type:"button",role:"radio",className:"ckf-opt ckf-plan","aria-checked":String(l.plan===N.id),"data-ckf-id":`p:${N.id}`,onClick:()=>e.pick(N.id)},n("span",{className:"ckf-radio"}),n("span",{},N.name,N.note?n("span",{className:"ckf-small"},N.note):false),n("b",{},N.price)))):false;o.replaceChildren(n("div",{className:"ckf-scrim",onClick:N=>N.target===N.currentTarget&&e.close()},n("div",{className:"ckf-card ckf-pw",role:"dialog","aria-modal":"true","aria-labelledby":"ckf-title"},n("div",{className:"ckf-top"},ne(l.index+1,l.total),W(f("Close"),e.close)),n("h2",{className:"ckf-h",id:"ckf-title"},k.title),k.body?n("p",{className:"ckf-p"},k.body):false,k.kind==="benefits"&&((E=k.items)!=null&&E.length)?n("div",{className:"ckf-opts"},...k.items.map(N=>n("p",{className:"ckf-li"},N))):false,k.kind==="proof"&&((H=k.quotes)!=null&&H.length)?n("div",{className:"ckf-opts"},...k.quotes.map(N=>n("blockquote",{className:"ckf-quote"},N.text,N.by?n("cite",{},N.by):false))):false,M,l.error?n("p",{className:"ckf-err",role:"alert"},l.error):false,n("div",{className:"ckf-btns"},L(l.busy?f("One moment\u2026"):k.button||f("Continue"),"primary",e.next,{disabled:l.busy||k.kind==="plans"&&!l.plan,id:"go"}),l.index?L(f("Back"),"quiet",e.back,{disabled:l.busy}):false)))),x!==s&&((I=o.querySelector("[data-ckf-id=go]"))==null||I.focus()),s=x;},h=l=>{e.view()&&l.key==="Escape"&&e.close();};document.addEventListener("keydown",h);let d=e.subscribe(m),w=J(m);return m(),()=>{d(),w(),document.removeEventListener("keydown",h),o.remove();}};var Le=e=>{let t=2166136261;for(let o=0;o<e.length;o++)t^=e.charCodeAt(o),t=Math.imul(t,16777619);return (t>>>0)/4294967296};var Ce=(e,t)=>{var m,h,d,w;let o=(h=(m=e.variants[0])==null?void 0:m.id)!=null?h:"control";if(e.winner)return e.winner;if(e.status!=="running")return o;let s=Le(`${e.key}:${t}`),c=0;for(let l of e.variants)if(c+=l.weight,s<c)return l.id;return (w=(d=e.variants[e.variants.length-1])==null?void 0:d.id)!=null?w:o};var re="$paywall",Te=(e,t,o)=>{var h,d;let s=t.experiment?e==null?void 0:e.experiments.find(w=>w.key===t.experiment):void 0,c=s?Ce(s,o):(h=t.variants[0])==null?void 0:h.id,m=(d=t.variants.find(w=>w.id===c))!=null?d:t.variants[0];return m?{variant:m.id,pages:m.pages,test:(s==null?void 0:s.status)==="running"&&!s.winner?s.key:void 0}:null},Me=e=>{let t=null,o=new Set,s=()=>{for(let l of [...o])try{l();}catch(x){}},c=()=>t?{paywall:t.w.id,placement:t.w.placement,variant:t.variant}:{},m=()=>{t&&!t.seen.has(t.index)&&(t.seen.add(t.index),e.track(re,{...c(),page:t.pages[t.index].id,index:t.index,action:"page"})),s();},h=l=>{var k,M;let x=t;x&&(t=null,l.outcome==="closed"&&((M=(k=x.options).onClose)==null||M.call(k,l)),x.resolve(l),s());},d=l=>{var x;return {outcome:l,index:(x=t==null?void 0:t.index)!=null?x:0,...t?{paywall:t.w.id,variant:t.variant}:{},...l!=="closed"&&t?{plan:t.plans.find(k=>k.id===t.plan)}:{}}},w=()=>{let l=t,x=l==null?void 0:l.plans.find(k=>k.id===l.plan);if(!(!l||!x||l.busy)){if(!l.options.onPurchase)return h(d("chosen"));l.busy=true,l.error=void 0,s(),Promise.resolve().then(()=>{var k,M;return (M=(k=l.options).onPurchase)==null?void 0:M.call(k,x)}).then(k=>{if(l.busy=false,t===l){if(k===false)return s();e.track(re,{...c(),page:l.pages[l.index].id,index:l.index,plan:x.id,action:"purchased"}),h(d("purchased"));}},()=>{l.busy=false,l.error=f("The purchase did not go through. Please try again."),s();});}};return {open:(l,x={})=>{var y,P,q;if(t)return t.promise;let k=e.config(),M=(y=k==null?void 0:k.paywalls)==null?void 0:y.find(R=>R.placement===l),E=M?Te(k,M,e.distinctId()):null;if(!M||!(E!=null&&E.pages.length))return Promise.resolve({outcome:"closed",index:0});let H=new Map(((P=x.plans)!=null?P:[]).map(R=>[R.id,R])),I=M.plans.map(R=>{var r;return (r=H.get(R.id))!=null?r:R}),N=()=>{},z=new Promise(R=>N=R),V=I.some(R=>R.id===M.highlight)?M.highlight:(q=I[0])==null?void 0:q.id;return t={w:M,variant:E.variant,pages:E.pages,plans:I,index:0,plan:V,busy:false,seen:new Set,options:x,resolve:N,promise:z},E.test&&e.track("$exposure",{experiment:E.test,variant:E.variant}),m(),z},view:()=>t?{paywall:t.w,variant:t.variant,page:t.pages[t.index],index:t.index,total:t.pages.length,last:t.index===t.pages.length-1,plans:t.plans,plan:t.plan,busy:t.busy,error:t.error}:null,subscribe:l=>(o.add(l),()=>o.delete(l)),next:()=>{if(!(!t||t.busy)){if(t.pages[t.index].kind==="plans"||t.index===t.pages.length-1)return w();t.index++,t.error=void 0,m();}},back:()=>{!t||t.busy||!t.index||(t.index--,t.error=void 0,s());},pick:l=>{!t||t.busy||!t.plans.some(x=>x.id===l)||(t.plan=l,t.error=void 0,s());},close:()=>{!t||t.busy||(e.track(re,{...c(),index:t.index,action:"closed"}),h(d("closed")));}}};var Ie=(e,t)=>{let o=Me(e);return ve(o,t),o};window.__mrrocketFlows={mountFlows:ye,paywallHost:Ie};
92
92
  })();