@mrrocket/sdk 0.18.0 → 0.21.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +24 -1
  3. package/dist/api-client.d.ts +28 -4
  4. package/dist/api-client.js +30 -13
  5. package/dist/api-client.js.map +1 -1
  6. package/dist/browser/mrrocket-flows.js +8 -3
  7. package/dist/browser/mrrocket-messenger.js +38 -5
  8. package/dist/browser/mrrocket.js +1 -1
  9. package/dist/browser.d.ts +1 -1
  10. package/dist/browser.js.map +1 -1
  11. package/dist/client.d.ts +6 -1
  12. package/dist/client.js +22 -4
  13. package/dist/client.js.map +1 -1
  14. package/dist/core.d.ts +5 -1
  15. package/dist/core.js +1 -1
  16. package/dist/core.js.map +1 -1
  17. package/dist/feedback.js +161 -119
  18. package/dist/feedback.js.map +1 -1
  19. package/dist/flows-ui.d.ts +1 -1
  20. package/dist/flows-ui.js +100 -72
  21. package/dist/flows-ui.js.map +1 -1
  22. package/dist/flows-web.js +2 -1
  23. package/dist/flows-web.js.map +1 -1
  24. package/dist/flows.d.ts +38 -6
  25. package/dist/flows.js +51 -17
  26. package/dist/flows.js.map +1 -1
  27. package/dist/i18n.d.ts +22 -0
  28. package/dist/i18n.js +74 -0
  29. package/dist/i18n.js.map +1 -0
  30. package/dist/index.d.ts +3 -1
  31. package/dist/index.js +3 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/messenger-ui.d.ts +9 -3
  34. package/dist/messenger-ui.js +324 -152
  35. package/dist/messenger-ui.js.map +1 -1
  36. package/dist/messenger.d.ts +3 -1
  37. package/dist/messenger.js +3 -2
  38. package/dist/messenger.js.map +1 -1
  39. package/dist/paywall.js +2 -1
  40. package/dist/paywall.js.map +1 -1
  41. package/dist/react-native/index.d.cts +66 -8
  42. package/dist/react-native/index.d.ts +66 -8
  43. package/dist/react-native/index.js +615 -334
  44. package/dist/react-native/index.js.map +1 -1
  45. package/dist/server.d.ts +4 -2
  46. package/dist/server.js +2 -2
  47. package/dist/server.js.map +1 -1
  48. package/dist/styles-css.d.ts +1 -1
  49. package/dist/styles-css.js +35 -2
  50. package/dist/styles-css.js.map +1 -1
  51. package/dist/survey.js +18 -14
  52. package/dist/survey.js.map +1 -1
  53. package/dist/ui.d.ts +2 -0
  54. package/dist/ui.js +15 -12
  55. package/dist/ui.js.map +1 -1
  56. package/package.json +6 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/flows-ui.ts"],"sourcesContent":["/**\n * The web renderer of the cancel flow, onboarding and in-app messages (flows.ts): plain DOM, no React, so the Next.js\n * provider and the script tag share it. Both load it only when something is about to show (a dynamic import, and\n * `sdk-flows.js` for the script tag), so pages that show nothing never download it.\n *\n * Themeable three ways: `theme` (\"light\", \"dark\", \"auto\") and `accent` from the SDK's options, and CSS variables on\n * `.ckf-root` in the site's own stylesheet (`--ckf-accent`, `--ckf-bg`, `--ckf-fg`, `--ckf-muted`, `--ckf-line`,\n * `--ckf-radius`, `--ckf-font`). Every text is set with textContent; nothing from the server is parsed as HTML.\n */\nimport { playFinish } from \"./finish-web\";\nimport { type FlowIcon, type FlowView, type FlowsController, type OnboardingStep, type TourPlacement, answerOk, discounted, mediaOf, money, offerButton, videoEmbed } from \"./flows\";\nimport { FLOW_ICONS, iconOf } from \"./icons\";\nimport type { PaywallHost } from \"./paywall\";\n\nexport interface FlowsTheme {\n theme?: \"light\" | \"dark\" | \"auto\";\n /** The main color of buttons and highlights, like \"#3f76ff\". */\n accent?: string;\n /** An extra class on the root, for the site's own CSS. */\n className?: string;\n}\n\nconst STYLE_ID = \"ckf-styles\";\n\nexport const FLOWS_CSS = `\n.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)}\n.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)}\n@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)}}\n.ckf-root,.ckf-root *{box-sizing:border-box}\n.ckf-root{font-family:var(--ckf-font);font-size:14px;line-height:1.45;color:var(--ckf-fg);-webkit-font-smoothing:antialiased}\n.ckf-root :where(button,textarea){font:inherit;color:inherit;margin:0}\n.ckf-root :focus-visible{outline:2px solid var(--ckf-accent);outline-offset:2px}\n.ckf-scrim{position:fixed;inset:0;z-index:2147483002;background:rgba(0,0,0,.4);display:flex;align-items:center;justify-content:center;padding:16px;animation:ckf-fade .15s ease-out}\n.ckf-card{position:relative;width:100%;max-width:400px;max-height:calc(100dvh - 32px);overflow-y:auto;background:var(--ckf-bg);color:var(--ckf-fg);border-radius:var(--ckf-radius);box-shadow:var(--ckf-shadow);padding:18px 20px 20px;display:flex;flex-direction:column;gap:12px;animation:ckf-in .18s ease-out}\n.ckf-float{position:fixed;z-index:2147483001;right:20px;bottom:20px;width:340px;max-width:calc(100vw - 24px)}\n.ckf-top{display:flex;align-items:center;gap:8px;min-height:20px}\n.ckf-dots{display:flex;gap:4px}\n.ckf-dot{width:16px;height:4px;border-radius:4px;background:var(--ckf-line)}\n.ckf-dot[data-on]{background:var(--ckf-accent)}\n.ckf-x{margin-left:auto;width:28px;height:28px;border:0;border-radius:8px;background:none;color:var(--ckf-muted);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:18px;line-height:1}\n.ckf-x:hover{background:var(--ckf-soft);color:var(--ckf-fg)}\n.ckf-h{margin:0;font-size:17px;font-weight:650;letter-spacing:-.01em;text-wrap:balance}\n.ckf-p{margin:0;color:var(--ckf-muted);text-wrap:pretty;white-space:pre-wrap}\n.ckf-small{margin:0;font-size:12px;color:var(--ckf-muted)}\n.ckf-opts{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}\n.ckf-opt{display:flex;align-items:center;gap:10px;width:100%;min-height:40px;padding:8px 12px;border:1px solid var(--ckf-line);border-radius:10px;background:var(--ckf-bg);text-align:left;cursor:pointer;font-weight:500}\n.ckf-opt:hover{background:var(--ckf-soft)}\n.ckf-opt[aria-checked=true]{border-color:var(--ckf-accent);background:color-mix(in srgb,var(--ckf-accent) 8%,var(--ckf-bg))}\n.ckf-radio{width:16px;height:16px;flex:none;border-radius:50%;border:1.5px solid var(--ckf-line);display:inline-flex;align-items:center;justify-content:center}\n.ckf-opt[aria-checked=true] .ckf-radio{border-color:var(--ckf-accent)}\n.ckf-opt[aria-checked=true] .ckf-radio::after{content:\"\";width:8px;height:8px;border-radius:50%;background:var(--ckf-accent)}\n.ckf-box{border-radius:10px;background:var(--ckf-soft);padding:12px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}\n.ckf-big{font-size:22px;font-weight:650;font-variant-numeric:tabular-nums}\n.ckf-strike{color:var(--ckf-muted);text-decoration:line-through;font-variant-numeric:tabular-nums}\n.ckf-text{width:100%;min-height:64px;resize:vertical;border:1px solid var(--ckf-line);border-radius:10px;background:var(--ckf-bg);padding:8px 10px}\n.ckf-text::placeholder{color:var(--ckf-muted)}\n.ckf-btns{display:flex;flex-direction:column;gap:6px}\n.ckf-btn{height:38px;padding:0 14px;border-radius:10px;border:1px solid var(--ckf-line);background:var(--ckf-bg);font-weight:600;cursor:pointer;transition:filter .1s linear,background-color .1s linear}\n.ckf-btn:hover{background:var(--ckf-soft)}\n.ckf-btn[disabled]{opacity:.55;cursor:not-allowed}\n.ckf-primary{background:var(--ckf-accent);border-color:var(--ckf-accent);color:var(--ckf-accent-ink)}\n.ckf-primary:hover{background:var(--ckf-accent);filter:brightness(1.07)}\n.ckf-danger{background:var(--ckf-danger);border-color:var(--ckf-danger);color:#fff}\n.ckf-danger:hover{background:var(--ckf-danger);filter:brightness(1.07)}\n.ckf-quiet{border-color:transparent;background:none;color:var(--ckf-muted);height:30px;font-weight:500}\n.ckf-quiet:hover{background:none;color:var(--ckf-fg)}\n.ckf-err{margin:0;color:var(--ckf-danger);font-size:13px;font-weight:500}\n.ckf-row{display:flex;justify-content:flex-end;gap:8px;align-items:center}\n.ckf-row .ckf-small{margin-right:auto}\n.ckf-media{display:block;width:100%;max-height:240px;object-fit:cover;border-radius:10px;background:var(--ckf-soft)}\n.ckf-video{position:relative;width:100%;aspect-ratio:16/9;border-radius:10px;overflow:hidden;background:#000}\n.ckf-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}\n.ckf-arrow{position:absolute;width:12px;height:12px;margin:-6px;background:var(--ckf-bg);transform:rotate(45deg)}\n[data-side=bottom]>.ckf-arrow{top:0;left:var(--ckf-ap)}[data-side=top]>.ckf-arrow{top:100%;left:var(--ckf-ap)}\n[data-side=right]>.ckf-arrow{left:0;top:var(--ckf-ap)}[data-side=left]>.ckf-arrow{left:100%;top:var(--ckf-ap)}\n.ckf-check .ckf-go{margin-left:auto;align-self:center;color:var(--ckf-accent);font-weight:700}\n.ckf-ic{width:20px;height:20px;flex:none;display:inline-flex;align-items:center;justify-content:center;color:var(--ckf-accent);font-size:16px;line-height:1}\n.ckf-ic svg{width:20px;height:20px}.ckf-ic img{width:20px;height:20px;border-radius:5px;object-fit:cover}\n.ckf-hic{width:40px;height:40px;border-radius:12px;background:color-mix(in srgb,var(--ckf-accent) 12%,var(--ckf-bg));display:inline-flex;align-items:center;justify-content:center;color:var(--ckf-accent);font-size:22px;line-height:1}\n.ckf-hic svg{width:22px;height:22px}.ckf-hic img{width:40px;height:40px;border-radius:12px;object-fit:cover}\n.ckf-input{width:100%;height:40px;border:1px solid var(--ckf-line);border-radius:10px;background:var(--ckf-bg);padding:0 12px}\n.ckf-input::placeholder{color:var(--ckf-muted)}\n.ckf-ring{position:fixed;z-index:2147483000;pointer-events:none;border-radius:10px;box-shadow:0 0 0 2px var(--ckf-accent),0 0 0 6px color-mix(in srgb,var(--ckf-accent) 25%,transparent);transition:all .15s ease-out}\n.ckf-check{display:flex;align-items:flex-start;gap:10px;width:100%;padding:8px 6px;border:0;border-radius:8px;background:none;text-align:left}\n.ckf-check:where(button){cursor:pointer}\n.ckf-check:where(button):hover{background:var(--ckf-soft)}\n.ckf-tick{width:18px;height:18px;flex:none;margin-top:1px;border-radius:50%;border:1.5px solid var(--ckf-line);display:inline-flex;align-items:center;justify-content:center;color:var(--ckf-accent-ink);font-size:11px;font-weight:700}\n.ckf-check[data-done] .ckf-tick{background:var(--ckf-accent);border-color:var(--ckf-accent)}\n.ckf-check[data-done] b{color:var(--ckf-muted);text-decoration:line-through}\n.ckf-check span{display:flex;flex-direction:column;gap:2px;min-width:0}\n.ckf-bar{height:4px;border-radius:4px;background:var(--ckf-soft);overflow:hidden}\n.ckf-bar i{display:block;height:100%;background:var(--ckf-accent)}\n.ckf-banner{position:fixed;z-index:2147483001;left:50%;top:12px;transform:translateX(-50%);width:min(640px,calc(100vw - 24px));background:var(--ckf-bg);border-radius:12px;box-shadow:var(--ckf-shadow);padding:10px 10px 10px 16px;display:flex;align-items:center;gap:12px;animation:ckf-in .18s ease-out}\n.ckf-banner>span{flex:1;min-width:0;display:flex;flex-direction:column}\n.ckf-banner .ckf-btn{height:32px}\n.ckf-pw{max-width:420px;gap:14px}\n.ckf-root[data-still] :is(.ckf-scrim,.ckf-card){animation:none}\n.ckf-li{display:flex;gap:10px;align-items:flex-start;margin:0}\n.ckf-li::before{content:\"✓\";flex:none;width:20px;height:20px;border-radius:50%;background:color-mix(in srgb,var(--ckf-accent) 14%,var(--ckf-bg));color:var(--ckf-accent);font-size:12px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}\n.ckf-quote{margin:0;padding:12px 14px;border-radius:12px;background:var(--ckf-soft)}\n.ckf-quote cite{display:block;margin-top:6px;font-style:normal;font-size:12px;color:var(--ckf-muted)}\n.ckf-plan{justify-content:space-between;min-height:52px}\n.ckf-plan span:nth-child(2){display:flex;flex-direction:column;margin-right:auto}\n.ckf-plan b{font-variant-numeric:tabular-nums}\n@keyframes ckf-fade{from{opacity:0}}\n@keyframes ckf-in{from{opacity:0;transform:translateY(6px)}}\n.ckf-banner{animation-name:ckf-fade}\n@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}}\n@media (prefers-reduced-motion:reduce){.ckf-root *{animation:none!important;transition:none!important}}\n`;\n\ntype Attrs = Record<string, string | boolean | undefined | ((e: Event) => void)>;\n\n/** A small element builder: attributes, `on*` handlers and children (strings become text, never HTML). */\nconst h = (tag: string, attrs: Attrs = {}, ...children: (Node | string | false | null | undefined)[]) => {\n const el = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (v === undefined || v === false) continue;\n if (typeof v === \"function\") el.addEventListener(k.slice(2).toLowerCase(), v);\n else if (k === \"className\") el.className = String(v);\n else el.setAttribute(k, v === true ? \"\" : v);\n }\n for (const c of children) if (c || c === \"\") el.append(typeof c === \"string\" ? document.createTextNode(c) : c);\n return el;\n};\n\nconst button = (label: string, kind: \"primary\" | \"danger\" | \"secondary\" | \"quiet\", onClick: () => void, opts: { disabled?: boolean; id?: string } = {}) =>\n h(\n \"button\",\n {\n type: \"button\",\n className: `ckf-btn${kind === \"secondary\" ? \"\" : ` ckf-${kind}`}`,\n disabled: !!opts.disabled,\n \"data-ckf-id\": opts.id,\n onClick: () => onClick(),\n },\n label,\n );\n\nconst closeButton = (label: string, onClick: () => void) =>\n h(\"button\", { type: \"button\", className: \"ckf-x\", \"aria-label\": label, \"data-ckf-id\": \"x\", onClick: () => onClick() }, \"×\");\n\nconst dots = (step: number, steps: number) =>\n steps > 1\n ? h(\n \"span\",\n { className: \"ckf-dots\", role: \"img\", \"aria-label\": `Step ${step} of ${steps}` },\n ...Array.from({ length: steps }, (_, i) => h(\"span\", { className: \"ckf-dot\", \"data-on\": i < step })),\n )\n : h(\"span\");\n\n/** A key that changes when the screen (not just its state) changes: then focus moves to the new screen. */\nconst screenKey = (v: FlowView) =>\n v.type === \"cancel\" ? `c:${v.screen}:${v.round ?? 1}` : v.type === \"step\" ? `s:${v.step.id}` : v.type === \"checklist\" ? `l:${v.flow.id}` : `m:${v.message.id}`;\n\n/**\n * Draws the controller's view into the page until the returned function is called. One root element under <body>;\n * nothing is drawn while there is nothing to show.\n */\n/** The stylesheet once, and a themed root element under <body>. */\nconst rootFor = (theme: FlowsTheme) => {\n if (!document.getElementById(STYLE_ID)) {\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = FLOWS_CSS;\n document.head.appendChild(style);\n }\n const root = h(\"div\", { className: `ckf-root${theme.className ? ` ${theme.className}` : \"\"}`, \"data-theme\": theme.theme ?? \"auto\" });\n if (theme.accent) root.style.setProperty(\"--ckf-accent\", theme.accent);\n document.body.appendChild(root);\n return root;\n};\n\n/** 0.18.0: an icon (a built-in line icon, an emoji or a picture) in a box of `className`; false when there is none. */\nconst iconEl = (icon: FlowIcon | undefined, className: string): HTMLElement | false => {\n const i = iconOf(icon);\n if (!i) return false;\n const box = h(\"span\", { className, \"aria-hidden\": \"true\" });\n if (i.kind === \"emoji\") box.textContent = i.value;\n else if (i.kind === \"image\") box.append(h(\"img\", { src: i.url, alt: \"\" }));\n else {\n const ns = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(ns, \"svg\");\n for (const [k, v] of Object.entries({ viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"2\", \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\" }))\n svg.setAttribute(k, v);\n for (const d of FLOW_ICONS[i.name].paths) {\n const p = document.createElementNS(ns, \"path\");\n p.setAttribute(\"d\", d);\n svg.append(p);\n }\n box.append(svg);\n }\n return box;\n};\n\nexport const mountFlows = (ctl: FlowsController, theme: FlowsTheme = {}): (() => void) => {\n if (typeof document === \"undefined\") return () => {};\n const root = rootFor(theme);\n /** 0.18.0: the finish animation last played, so each plays once. */\n let played = \"\";\n\n let lastKey = \"\";\n let returnFocus: HTMLElement | null = null;\n let comment = \"\";\n let placed: { float: HTMLElement; ring: HTMLElement; target: HTMLElement; side?: TourPlacement } | null = null;\n\n // ---------- Cancel flow ----------\n\n const cancelCard = (v: Extract<FlowView, { type: \"cancel\" }>) => {\n const titleId = \"ckf-title\";\n const busy = v.busy;\n const body: (Node | false)[] = [];\n if (v.screen === \"survey\") {\n body.push(\n h(\"h2\", { className: \"ckf-h\", id: titleId }, v.flow.question || \"Why are you leaving?\"),\n h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...v.flow.reasons.map((r) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt\",\n \"aria-checked\": String(v.reason === r.id),\n \"data-ckf-id\": `r:${r.id}`,\n onClick: () => ctl.cancel.pick(r.id),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n r.label,\n ),\n ),\n ),\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(\"Continue\", \"primary\", ctl.cancel.next, { disabled: !v.reason, id: \"go\" }),\n button(\"Never mind, keep my plan\", \"quiet\", ctl.cancel.close),\n ),\n );\n } else if (v.screen === \"followup\" && v.followUp) {\n const f = v.followUp;\n let field: Node;\n if (f.answers.length)\n field = h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...f.answers.map((a, i) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt\",\n \"aria-checked\": String(v.answer === a),\n \"data-ckf-id\": `a:${i}`,\n onClick: () => ctl.cancel.answer(a),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n a,\n ),\n ),\n );\n else {\n const text = h(\"textarea\", {\n className: \"ckf-text\",\n placeholder: \"Your answer (optional)\",\n \"aria-labelledby\": titleId,\n maxlength: \"500\",\n \"data-ckf-id\": \"answer\",\n onInput: (e) => ctl.cancel.answer((e.target as HTMLTextAreaElement).value),\n }) as HTMLTextAreaElement;\n text.value = v.answer ?? \"\";\n field = text;\n }\n const label = v.flow.reasons.find((r) => r.id === v.reason)?.label;\n body.push(\n label ? h(\"p\", { className: \"ckf-small\" }, `You said: ${label}`) : false,\n h(\"h2\", { className: \"ckf-h\", id: titleId }, f.question),\n field,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(\"Continue\", \"primary\", ctl.cancel.next, { id: \"go\" }),\n button(\"Never mind, keep my plan\", \"quiet\", ctl.cancel.close),\n ),\n );\n } else if (v.screen === \"offer\" && v.offer) {\n const o = v.offer;\n const label = v.flow.reasons.find((r) => r.id === v.reason)?.label;\n let detail: Node | false = false;\n if (o.kind === \"discount\" && o.percent)\n detail = v.price\n ? h(\n \"div\",\n { className: \"ckf-box\" },\n h(\"span\", { className: \"ckf-big\" }, money(discounted(v.price.amount, o.percent), v.price.currency)),\n h(\"span\", { className: \"ckf-strike\" }, money(v.price.amount, v.price.currency)),\n h(\n \"span\",\n { className: \"ckf-small\" },\n `/${v.price.interval ?? \"month\"}${o.months ? ` for ${o.months} ${o.months === 1 ? \"month\" : \"months\"}` : \"\"}`,\n ),\n )\n : h(\n \"div\",\n { className: \"ckf-box\" },\n h(\"span\", { className: \"ckf-big\" }, `${o.percent}% off`),\n o.months ? h(\"span\", { className: \"ckf-small\" }, `for ${o.months} ${o.months === 1 ? \"month\" : \"months\"}`) : false,\n );\n if (o.kind === \"pause\" && o.months)\n detail = h(\n \"div\",\n { className: \"ckf-box\" },\n h(\"span\", {}, `Pause for up to ${o.months} ${o.months === 1 ? \"month\" : \"months\"}. Your data stays.`),\n );\n if (o.kind === \"downgrade\" && o.planName) detail = h(\"div\", { className: \"ckf-box\" }, h(\"b\", {}, o.planName));\n const text =\n o.kind === \"contact\"\n ? (h(\"textarea\", {\n className: \"ckf-text\",\n placeholder: \"What would make you stay?\",\n \"aria-label\": \"Your message\",\n maxlength: \"500\",\n \"data-ckf-id\": \"comment\",\n onInput: (e) => (comment = (e.target as HTMLTextAreaElement).value),\n }) as HTMLTextAreaElement)\n : null;\n if (text) text.value = comment;\n body.push(\n label ? h(\"p\", { className: \"ckf-small\" }, `You said: ${label}`) : false,\n h(\"h2\", { className: \"ckf-h\", id: titleId }, o.headline),\n detail,\n text ?? false,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(busy ? \"One moment…\" : offerButton(o), \"primary\", () => ctl.cancel.accept(comment), { disabled: busy, id: \"go\" }),\n button(\"No thanks, continue cancelling\", \"quiet\", ctl.cancel.decline, { disabled: busy }),\n ),\n );\n } else {\n const plain = v.steps === 1;\n const text = plain\n ? null\n : (h(\"textarea\", {\n className: \"ckf-text\",\n placeholder: \"Anything else we should know? (optional)\",\n \"aria-label\": \"Anything else we should know? (optional)\",\n maxlength: \"500\",\n \"data-ckf-id\": \"comment\",\n onInput: (e) => (comment = (e.target as HTMLTextAreaElement).value),\n }) as HTMLTextAreaElement);\n if (text) text.value = comment;\n body.push(\n h(\"h2\", { className: \"ckf-h\", id: titleId }, v.flow.confirm.title),\n v.flow.confirm.body ? h(\"p\", { className: \"ckf-p\" }, v.flow.confirm.body) : false,\n text ?? false,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(busy ? \"One moment…\" : v.flow.confirm.button, \"danger\", () => ctl.cancel.confirm(comment), { disabled: busy, id: \"go\" }),\n button(\"Keep my plan\", \"secondary\", ctl.cancel.close, { disabled: busy }),\n ),\n );\n }\n return h(\n \"div\",\n { className: \"ckf-scrim\", onClick: (e) => e.target === e.currentTarget && !busy && ctl.cancel.close() },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": titleId },\n h(\"div\", { className: \"ckf-top\" }, dots(v.step, v.steps), closeButton(\"Close\", ctl.cancel.close)),\n ...body,\n v.error ? h(\"p\", { className: \"ckf-err\", role: \"alert\" }, v.error) : false,\n ),\n );\n };\n\n // ---------- Onboarding ----------\n\n /** 0.17.0: the step's picture or video above its text; a video link plays in its privacy-friendly player. */\n const media = (s: OnboardingStep) => {\n const m = mediaOf(s);\n if (!m) return false;\n if (m.kind === \"image\") return h(\"img\", { className: \"ckf-media\", src: m.url, alt: m.alt ?? \"\", onLoad: () => follow() });\n const v = videoEmbed(m.url)!;\n return v.kind === \"iframe\"\n ? h(\n \"div\",\n { className: \"ckf-video\" },\n h(\"iframe\", { src: v.src, title: m.alt || \"Video\", allow: \"fullscreen; picture-in-picture\", allowfullscreen: true, loading: \"lazy\", referrerpolicy: \"strict-origin-when-cross-origin\" }),\n )\n : h(\"video\", { className: \"ckf-media\", src: v.src, controls: true, playsinline: true, preload: \"metadata\", \"aria-label\": m.alt || undefined, onLoadedmetadata: () => follow() });\n };\n\n /** 0.18.0: one question of a Questions item: a slide with dots, the options or a text field, Back and Continue. */\n const questionCard = (v: Extract<FlowView, { type: \"step\" }>) => {\n const s = v.step;\n const q = s.question;\n const titleId = \"ckf-title\";\n const ok = answerOk(q, v.answer);\n let field: Node | false = false;\n if (q?.type === \"choice\")\n field = h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...(q.options ?? []).map((o) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt\",\n \"aria-checked\": String(v.answer === o.id),\n \"data-ckf-id\": `q:${o.id}`,\n onClick: () => ctl.onboarding.answer(o.id),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n o.label,\n ),\n ),\n );\n else if (q) {\n const input = h(\"input\", {\n type: \"text\",\n className: \"ckf-input\",\n placeholder: q.placeholder || \"Your answer\",\n \"aria-labelledby\": titleId,\n maxlength: \"500\",\n \"data-ckf-id\": \"answer\",\n onInput: (e) => ctl.onboarding.answer((e.target as HTMLInputElement).value),\n onKeydown: (e) => (e as KeyboardEvent).key === \"Enter\" && ctl.onboarding.next(),\n }) as HTMLInputElement;\n input.value = v.answer ?? \"\";\n field = input;\n }\n return h(\n \"div\",\n { className: \"ckf-scrim\" },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": titleId },\n h(\"div\", { className: \"ckf-top\" }, dots(v.index + 1, v.total), closeButton(\"Close\", ctl.onboarding.dismiss)),\n v.index === 0 ? iconEl(v.flow.icon, \"ckf-hic\") : false,\n h(\"h2\", { className: \"ckf-h\", id: titleId }, s.title),\n s.body ? h(\"p\", { className: \"ckf-p\" }, s.body) : false,\n field,\n h(\n \"div\",\n { className: \"ckf-row\" },\n v.back ? button(\"Back\", \"quiet\", ctl.onboarding.back) : false,\n button(s.button || (v.last ? \"Done\" : \"Continue\"), \"primary\", ctl.onboarding.next, { disabled: !ok, id: \"go\" }),\n ),\n ),\n );\n };\n\n const stepCard = (v: Extract<FlowView, { type: \"step\" }>) => {\n const s = v.step;\n if (s.kind === \"question\") return questionCard(v);\n const card = h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": s.kind === \"modal\" ? \"true\" : undefined, \"aria-labelledby\": \"ckf-title\" },\n h(\n \"div\",\n { className: \"ckf-top\" },\n v.total > 1 ? h(\"p\", { className: \"ckf-small\" }, `Step ${v.index + 1} of ${v.total}`) : h(\"span\"),\n closeButton(\"Close the tour\", ctl.onboarding.dismiss),\n ),\n s.kind === \"modal\" ? iconEl(v.flow.icon, \"ckf-hic\") : false,\n media(s),\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, s.title),\n s.body ? h(\"p\", { className: \"ckf-p\" }, s.body) : false,\n h(\"div\", { className: \"ckf-row\" }, button(s.button || (v.last ? \"Done\" : \"Next\"), \"primary\", ctl.onboarding.next, { id: \"go\" })),\n );\n if (s.kind === \"modal\") return h(\"div\", { className: \"ckf-scrim\" }, card);\n const target = s.target ? findTarget(s.target) : null;\n const float = h(\"div\", { className: \"ckf-float\" }, card);\n if (target) {\n const ring = h(\"div\", { className: \"ckf-ring\", \"aria-hidden\": \"true\" });\n float.append(h(\"span\", { className: \"ckf-arrow\", \"aria-hidden\": \"true\" }));\n placed = { float, ring, target, side: s.placement };\n place(float, ring, target, s.placement);\n return h(\"div\", {}, ring, float);\n }\n return float;\n };\n\n /**\n * The element a tour step points at: a CSS selector (`#new-project`, `.toolbar button`, picked on the site in\n * MRRocket), or a plain name for `data-ck-target=\"…\"`. A selector that does not parse falls back to the name.\n */\n const findTarget = (t: string): HTMLElement | null => {\n const named = () => document.querySelector<HTMLElement>(`[data-ck-target=\"${CSS.escape(t)}\"]`);\n if (!/^[#.[]|[\\s>:=]/.test(t)) return named();\n return safeQuery(t) ?? named();\n };\n const safeQuery = (sel: string) => {\n try {\n return document.querySelector<HTMLElement>(sel);\n } catch {\n return null;\n }\n };\n\n /**\n * Puts a tour card next to the element it points at, on the step's side (0.17.0) or, on \"auto\", below it and above\n * when there is no room. A side without room flips to the opposite one, then to any side with room.\n */\n const place = (float: HTMLElement, ring: HTMLElement, target: HTMLElement, side: TourPlacement = \"auto\") => {\n const r = target.getBoundingClientRect();\n Object.assign(ring.style, { left: `${r.left - 4}px`, top: `${r.top - 4}px`, width: `${r.width + 8}px`, height: `${r.height + 8}px` });\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = Math.min(340, vw - 24);\n const ht = float.offsetHeight || 200;\n const gap = 14;\n const room: Record<string, boolean> = {\n bottom: vh - r.bottom - gap - 12 >= ht,\n top: r.top - gap - 12 >= ht,\n right: vw - r.right - gap - 12 >= w,\n left: r.left - gap - 12 >= w,\n };\n const flip: Record<string, string> = { top: \"bottom\", bottom: \"top\", left: \"right\", right: \"left\" };\n const order = side === \"auto\" || !flip[side] ? [\"bottom\", \"top\"] : [side, flip[side], \"bottom\", \"top\", \"right\", \"left\"];\n const s = order.find((x) => room[x]) ?? (side !== \"auto\" && flip[side] ? side : r.top > vh - r.bottom ? \"top\" : \"bottom\");\n const clamp = (v: number, hi: number) => Math.max(12, Math.min(v, hi - 12));\n const across = s === \"top\" || s === \"bottom\";\n // \"auto\" keeps the card's left edge at the element's, as before 0.17.0; a chosen side centres it.\n const left = across ? clamp(side === \"auto\" ? r.left : r.left + r.width / 2 - w / 2, vw - w) : s === \"right\" ? r.right + gap : r.left - gap - w;\n const top = across ? (s === \"bottom\" ? r.bottom + gap : r.top - gap - ht) : clamp(r.top + r.height / 2 - ht / 2, vh - ht);\n Object.assign(float.style, { left: `${left}px`, top: `${top}px`, right: \"auto\", bottom: \"auto\", width: `${w}px` });\n float.setAttribute(\"data-side\", s);\n // The arrow points at the element's middle, kept off the card's rounded corners.\n const at = across ? r.left + r.width / 2 - left : r.top + r.height / 2 - top;\n float.style.setProperty(\"--ckf-ap\", `${Math.max(18, Math.min(at, (across ? w : ht) - 18))}px`);\n };\n\n const checklist = (v: Extract<FlowView, { type: \"checklist\" }>) => {\n const done = v.items.filter((i) => i.done).length;\n return h(\n \"div\",\n { className: \"ckf-float\" },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"region\", \"aria-labelledby\": \"ckf-title\" },\n h(\n \"div\",\n { className: \"ckf-top\" },\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, v.flow.name),\n closeButton(\"Hide the checklist\", ctl.onboarding.dismiss),\n ),\n h(\"p\", { className: \"ckf-small\" }, `${done} of ${v.items.length} done`),\n h(\n \"div\",\n { className: \"ckf-bar\", role: \"progressbar\", \"aria-valuemin\": \"0\", \"aria-valuemax\": String(v.items.length), \"aria-valuenow\": String(done) },\n h(\"i\", { style: `width:${(done / v.items.length) * 100}%` } as Attrs),\n ),\n h(\n \"div\",\n { className: \"ckf-opts\" },\n ...v.items.map(({ step, done: d, opens }) => {\n const inner: (Node | false)[] = [\n h(\"span\", { className: \"ckf-tick\", \"aria-hidden\": \"true\" }, d ? \"✓\" : \"\"),\n iconEl(step.icon, \"ckf-ic\"),\n h(\"span\", {}, h(\"b\", {}, step.title), step.body ? h(\"span\", { className: \"ckf-small\" }, step.body) : false),\n ];\n // 0.17.0/0.18.0: a task that opens something (a tour, a modal, a page, the app's code) does it;\n // a finished tour or modal ticks it, a page or the app's code once opened (unless an event does).\n if (!d && opens)\n return h(\n \"button\",\n {\n type: \"button\",\n className: \"ckf-check\",\n \"aria-label\": `Start “${step.title}”`,\n \"data-ckf-id\": `t:${step.id}`,\n onClick: () => ctl.onboarding.open(step.id),\n },\n ...inner,\n h(\"span\", { className: \"ckf-go\", \"aria-hidden\": \"true\" }, \"›\"),\n );\n // An item with an event ticks itself when the app records it; the others are ticked by hand.\n return d || step.event\n ? h(\"div\", { className: \"ckf-check\", \"data-done\": d, role: \"listitem\" }, ...inner)\n : h(\n \"button\",\n {\n type: \"button\",\n className: \"ckf-check\",\n \"aria-label\": `Mark “${step.title}” done`,\n \"data-ckf-id\": `i:${step.id}`,\n onClick: () => ctl.onboarding.check(step.id),\n },\n ...inner,\n );\n }),\n ),\n ),\n );\n };\n\n // ---------- Messages ----------\n\n const message = (v: Extract<FlowView, { type: \"message\" }>) => {\n const m = v.message;\n const action = m.button ? button(m.button, \"primary\", ctl.message.click, { id: \"go\" }) : false;\n if (m.style === \"banner\")\n return h(\n \"div\",\n { className: \"ckf-banner\", role: \"status\" },\n h(\"span\", {}, h(\"b\", {}, m.title), m.body ? h(\"span\", { className: \"ckf-small\" }, m.body) : false),\n action,\n closeButton(\"Dismiss\", ctl.message.dismiss),\n );\n return h(\n \"div\",\n { className: \"ckf-scrim\", onClick: (e) => e.target === e.currentTarget && ctl.message.dismiss() },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": \"ckf-title\" },\n h(\"div\", { className: \"ckf-top\" }, h(\"span\"), closeButton(\"Dismiss\", ctl.message.dismiss)),\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, m.title),\n m.body ? h(\"p\", { className: \"ckf-p\" }, m.body) : false,\n action ? h(\"div\", { className: \"ckf-row\" }, action) : false,\n ),\n );\n };\n\n // ---------- Drawing ----------\n\n const draw = () => {\n const v = ctl.view();\n // 0.18.0: the product's brand color from MRRocket, unless the site set an accent of its own.\n const accent = theme.accent ?? ctl.accent?.();\n if (accent) root.style.setProperty(\"--ckf-accent\", accent);\n // 0.18.0: someone just finished a checklist, a tour or the questions.\n const fin = ctl.finale?.();\n if (fin && fin.key !== played) {\n played = fin.key;\n playFinish(fin.kind, { accent });\n }\n const key = v ? screenKey(v) : \"\";\n const focused = (document.activeElement as HTMLElement | null)?.closest?.(\".ckf-root\") ? document.activeElement?.getAttribute(\"data-ckf-id\") : null;\n if (key && !lastKey && document.activeElement instanceof HTMLElement && !document.activeElement.closest(\".ckf-root\"))\n returnFocus = document.activeElement;\n if (key !== lastKey && !key.startsWith(\"c:\")) comment = \"\";\n if (!key) comment = \"\";\n placed = null;\n root.replaceChildren(\n ...(v ? [v.type === \"cancel\" ? cancelCard(v) : v.type === \"step\" ? stepCard(v) : v.type === \"checklist\" ? checklist(v) : message(v)] : []),\n );\n // Placed again now that the card is in the page and has its real height.\n follow();\n if (key !== lastKey) {\n // A new screen: focus its first control (a dialog's), so keyboard and screen reader users land in it.\n const modal = root.querySelector<HTMLElement>(\"[aria-modal=true]\");\n const first = modal?.querySelector<HTMLElement>(\"[role=radio], input, [data-ckf-id=go], textarea\") ?? null;\n first?.focus();\n if (!key && returnFocus) {\n returnFocus.focus();\n returnFocus = null;\n }\n } else if (focused) root.querySelector<HTMLElement>(`[data-ckf-id=\"${CSS.escape(focused)}\"]`)?.focus();\n lastKey = key;\n };\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n const v = ctl.view();\n if (v?.type === \"cancel\") ctl.cancel.close();\n else if (v?.type === \"message\") ctl.message.dismiss();\n else if (v?.type === \"step\" && (v.step.kind === \"modal\" || v.step.kind === \"question\")) ctl.onboarding.dismiss();\n };\n // A tour card follows its element when the page scrolls or resizes.\n function follow() {\n if (placed) place(placed.float, placed.ring, placed.target, placed.side);\n }\n document.addEventListener(\"keydown\", onKey);\n window.addEventListener(\"resize\", follow);\n window.addEventListener(\"scroll\", follow, { passive: true, capture: true });\n const off = ctl.subscribe(draw);\n draw();\n return () => {\n off();\n document.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"resize\", follow);\n window.removeEventListener(\"scroll\", follow, { capture: true });\n root.remove();\n };\n};\n\n/**\n * Draws an open paywall (paywall.ts) page by page until the returned function is called: the dots, the page's title and\n * text, its benefits, quotes or plans, Back and the button. Closes on Escape and on a click beside the card.\n */\nexport const mountPaywall = (host: PaywallHost, theme: FlowsTheme = {}): (() => void) => {\n if (typeof document === \"undefined\") return () => {};\n const root = rootFor(theme);\n let lastKey = \"\";\n let returnFocus: HTMLElement | null = null;\n const draw = () => {\n const v = host.view();\n const key = v ? `${v.paywall.id}:${v.index}` : \"\";\n if (key && !lastKey && document.activeElement instanceof HTMLElement) returnFocus = document.activeElement;\n if (!v) {\n root.replaceChildren();\n root.removeAttribute(\"data-still\");\n if (lastKey) returnFocus?.focus();\n lastKey = \"\";\n return;\n }\n // Fades in when it opens, not again on every page or plan.\n if (lastKey) root.setAttribute(\"data-still\", \"\");\n const p = v.page;\n const plans =\n p.kind === \"plans\"\n ? h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-label\": \"Plans\" },\n ...v.plans.map((plan) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt ckf-plan\",\n \"aria-checked\": String(v.plan === plan.id),\n \"data-ckf-id\": `p:${plan.id}`,\n onClick: () => host.pick(plan.id),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n h(\"span\", {}, plan.name, plan.note ? h(\"span\", { className: \"ckf-small\" }, plan.note) : false),\n h(\"b\", {}, plan.price),\n ),\n ),\n )\n : false;\n root.replaceChildren(\n h(\n \"div\",\n { className: \"ckf-scrim\", onClick: (e) => e.target === e.currentTarget && host.close() },\n h(\n \"div\",\n { className: \"ckf-card ckf-pw\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": \"ckf-title\" },\n h(\"div\", { className: \"ckf-top\" }, dots(v.index + 1, v.total), closeButton(\"Close\", host.close)),\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, p.title),\n p.body ? h(\"p\", { className: \"ckf-p\" }, p.body) : false,\n p.kind === \"benefits\" && p.items?.length ? h(\"div\", { className: \"ckf-opts\" }, ...p.items.map((i) => h(\"p\", { className: \"ckf-li\" }, i))) : false,\n p.kind === \"proof\" && p.quotes?.length\n ? h(\"div\", { className: \"ckf-opts\" }, ...p.quotes.map((q) => h(\"blockquote\", { className: \"ckf-quote\" }, q.text, q.by ? h(\"cite\", {}, q.by) : false)))\n : false,\n plans,\n v.error ? h(\"p\", { className: \"ckf-err\", role: \"alert\" }, v.error) : false,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(v.busy ? \"One moment…\" : p.button || \"Continue\", \"primary\", host.next, {\n disabled: v.busy || (p.kind === \"plans\" && !v.plan),\n id: \"go\",\n }),\n v.index ? button(\"Back\", \"quiet\", host.back, { disabled: v.busy }) : false,\n ),\n ),\n ),\n );\n if (key !== lastKey) root.querySelector<HTMLElement>(\"[data-ckf-id=go]\")?.focus();\n lastKey = key;\n };\n const onKey = (e: KeyboardEvent) => {\n if (!host.view()) return;\n if (e.key === \"Escape\") host.close();\n };\n document.addEventListener(\"keydown\", onKey);\n const off = host.subscribe(draw);\n draw();\n return () => {\n off();\n document.removeEventListener(\"keydown\", onKey);\n root.remove();\n };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/flows-ui.ts"],"sourcesContent":["/**\n * The web renderer of the cancel flow, onboarding and in-app messages (flows.ts): plain DOM, no React, so the Next.js\n * provider and the script tag share it. Both load it only when something is about to show (a dynamic import, and\n * `sdk-flows.js` for the script tag), so pages that show nothing never download it.\n *\n * Themeable three ways: `theme` (\"light\", \"dark\", \"auto\") and `accent` from the SDK's options, and CSS variables on\n * `.ckf-root` in the site's own stylesheet (`--ckf-accent`, `--ckf-bg`, `--ckf-fg`, `--ckf-muted`, `--ckf-line`,\n * `--ckf-radius`, `--ckf-font`). Every text is set with textContent; nothing from the server is parsed as HTML.\n */\nimport { playFinish } from \"./finish-web\";\nimport { type FlowIcon, type FlowView, type FlowsController, OTHER_PREFIX, type OnboardingStep, type TourPlacement, answerOk, forMonths, monthsWord, scaleOf, discounted, mediaOf, money, offerButton, videoEmbed } from \"./flows\";\nimport { onWords, t, tf, wordsLang } from \"./i18n\";\nimport { FLOW_ICONS, iconOf } from \"./icons\";\nimport type { PaywallHost } from \"./paywall\";\n\nexport interface FlowsTheme {\n theme?: \"light\" | \"dark\" | \"auto\";\n /** The main color of buttons and highlights, like \"#3f76ff\". */\n accent?: string;\n /** An extra class on the root, for the site's own CSS. */\n className?: string;\n}\n\nconst STYLE_ID = \"ckf-styles\";\n\nexport const FLOWS_CSS = `\n.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)}\n.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)}\n@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)}}\n.ckf-root,.ckf-root *{box-sizing:border-box}\n.ckf-root{font-family:var(--ckf-font);font-size:14px;line-height:1.45;color:var(--ckf-fg);-webkit-font-smoothing:antialiased}\n.ckf-root :where(button,textarea){font:inherit;color:inherit;margin:0}\n.ckf-root :focus-visible{outline:2px solid var(--ckf-accent);outline-offset:2px}\n.ckf-scrim{position:fixed;inset:0;z-index:2147483002;background:rgba(0,0,0,.4);display:flex;align-items:center;justify-content:center;padding:16px;animation:ckf-fade .15s ease-out}\n.ckf-card{position:relative;width:100%;max-width:400px;max-height:calc(100dvh - 32px);overflow-y:auto;background:var(--ckf-bg);color:var(--ckf-fg);border-radius:var(--ckf-radius);box-shadow:var(--ckf-shadow);padding:18px 20px 20px;display:flex;flex-direction:column;gap:12px;animation:ckf-in .18s ease-out}\n.ckf-float{position:fixed;z-index:2147483001;right:20px;bottom:20px;width:340px;max-width:calc(100vw - 24px)}\n.ckf-top{display:flex;align-items:center;gap:8px;min-height:20px}\n.ckf-dots{display:flex;gap:4px}\n.ckf-dot{width:16px;height:4px;border-radius:4px;background:var(--ckf-line)}\n.ckf-dot[data-on]{background:var(--ckf-accent)}\n.ckf-x{margin-left:auto;width:28px;height:28px;border:0;border-radius:8px;background:none;color:var(--ckf-muted);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:18px;line-height:1}\n.ckf-x:hover{background:var(--ckf-soft);color:var(--ckf-fg)}\n.ckf-h{margin:0;font-size:17px;font-weight:650;letter-spacing:-.01em;text-wrap:balance}\n.ckf-p{margin:0;color:var(--ckf-muted);text-wrap:pretty;white-space:pre-wrap}\n.ckf-small{margin:0;font-size:12px;color:var(--ckf-muted)}\n.ckf-opts{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}\n.ckf-opt{display:flex;align-items:center;gap:10px;width:100%;min-height:40px;padding:8px 12px;border:1px solid var(--ckf-line);border-radius:10px;background:var(--ckf-bg);text-align:left;cursor:pointer;font-weight:500}\n.ckf-opt:hover{background:var(--ckf-soft)}\n.ckf-opt[aria-checked=true]{border-color:var(--ckf-accent);background:color-mix(in srgb,var(--ckf-accent) 8%,var(--ckf-bg))}\n.ckf-radio{width:16px;height:16px;flex:none;border-radius:50%;border:1.5px solid var(--ckf-line);display:inline-flex;align-items:center;justify-content:center}\n.ckf-opt[aria-checked=true] .ckf-radio{border-color:var(--ckf-accent)}\n.ckf-opt[aria-checked=true] .ckf-radio::after{content:\"\";width:8px;height:8px;border-radius:50%;background:var(--ckf-accent)}\n.ckf-scale{display:flex;gap:4px}\n.ckf-num{flex:1;min-width:0;height:38px;padding:0;border:1px solid var(--ckf-line);border-radius:8px;background:var(--ckf-bg);cursor:pointer;font-weight:500}\n.ckf-num:hover{background:var(--ckf-soft)}\n.ckf-num[aria-checked=true]{border-color:var(--ckf-accent);background:var(--ckf-accent);color:var(--ckf-accent-ink)}\n.ckf-ends{display:flex;justify-content:space-between;gap:12px;margin-top:6px}\n.ckf-box{border-radius:10px;background:var(--ckf-soft);padding:12px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}\n.ckf-big{font-size:22px;font-weight:650;font-variant-numeric:tabular-nums}\n.ckf-strike{color:var(--ckf-muted);text-decoration:line-through;font-variant-numeric:tabular-nums}\n.ckf-text{width:100%;min-height:64px;resize:vertical;border:1px solid var(--ckf-line);border-radius:10px;background:var(--ckf-bg);padding:8px 10px}\n.ckf-text::placeholder{color:var(--ckf-muted)}\n.ckf-btns{display:flex;flex-direction:column;gap:6px}\n.ckf-btn{height:38px;padding:0 14px;border-radius:10px;border:1px solid var(--ckf-line);background:var(--ckf-bg);font-weight:600;cursor:pointer;transition:filter .1s linear,background-color .1s linear}\n.ckf-btn:hover{background:var(--ckf-soft)}\n.ckf-btn[disabled]{opacity:.55;cursor:not-allowed}\n.ckf-primary{background:var(--ckf-accent);border-color:var(--ckf-accent);color:var(--ckf-accent-ink)}\n.ckf-primary:hover{background:var(--ckf-accent);filter:brightness(1.07)}\n.ckf-danger{background:var(--ckf-danger);border-color:var(--ckf-danger);color:#fff}\n.ckf-danger:hover{background:var(--ckf-danger);filter:brightness(1.07)}\n.ckf-quiet{border-color:transparent;background:none;color:var(--ckf-muted);height:30px;font-weight:500}\n.ckf-quiet:hover{background:none;color:var(--ckf-fg)}\n.ckf-err{margin:0;color:var(--ckf-danger);font-size:13px;font-weight:500}\n.ckf-row{display:flex;justify-content:flex-end;gap:8px;align-items:center}\n.ckf-row .ckf-small{margin-right:auto}\n.ckf-media{display:block;width:100%;max-height:240px;object-fit:cover;border-radius:10px;background:var(--ckf-soft)}\n.ckf-video{position:relative;width:100%;aspect-ratio:16/9;border-radius:10px;overflow:hidden;background:#000}\n.ckf-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}\n.ckf-arrow{position:absolute;width:12px;height:12px;margin:-6px;background:var(--ckf-bg);transform:rotate(45deg)}\n[data-side=bottom]>.ckf-arrow{top:0;left:var(--ckf-ap)}[data-side=top]>.ckf-arrow{top:100%;left:var(--ckf-ap)}\n[data-side=right]>.ckf-arrow{left:0;top:var(--ckf-ap)}[data-side=left]>.ckf-arrow{left:100%;top:var(--ckf-ap)}\n.ckf-check .ckf-go{margin-left:auto;align-self:center;color:var(--ckf-accent);font-weight:700}\n.ckf-ic{width:20px;height:20px;flex:none;display:inline-flex;align-items:center;justify-content:center;color:var(--ckf-accent);font-size:16px;line-height:1}\n.ckf-ic svg{width:20px;height:20px}.ckf-ic img{width:20px;height:20px;border-radius:5px;object-fit:cover}\n.ckf-hic{width:40px;height:40px;border-radius:12px;background:color-mix(in srgb,var(--ckf-accent) 12%,var(--ckf-bg));display:inline-flex;align-items:center;justify-content:center;color:var(--ckf-accent);font-size:22px;line-height:1}\n.ckf-hic svg{width:22px;height:22px}.ckf-hic img{width:40px;height:40px;border-radius:12px;object-fit:cover}\n.ckf-input{width:100%;height:40px;border:1px solid var(--ckf-line);border-radius:10px;background:var(--ckf-bg);padding:0 12px}\n.ckf-input::placeholder{color:var(--ckf-muted)}\n.ckf-ring{position:fixed;z-index:2147483000;pointer-events:none;border-radius:10px;box-shadow:0 0 0 2px var(--ckf-accent),0 0 0 6px color-mix(in srgb,var(--ckf-accent) 25%,transparent);transition:all .15s ease-out}\n.ckf-check{display:flex;align-items:flex-start;gap:10px;width:100%;padding:8px 6px;border:0;border-radius:8px;background:none;text-align:left}\n.ckf-check:where(button){cursor:pointer}\n.ckf-check:where(button):hover{background:var(--ckf-soft)}\n.ckf-tick{width:18px;height:18px;flex:none;margin-top:1px;border-radius:50%;border:1.5px solid var(--ckf-line);display:inline-flex;align-items:center;justify-content:center;color:var(--ckf-accent-ink);font-size:11px;font-weight:700}\n.ckf-check[data-done] .ckf-tick{background:var(--ckf-accent);border-color:var(--ckf-accent)}\n.ckf-check[data-done] b{color:var(--ckf-muted);text-decoration:line-through}\n.ckf-check span{display:flex;flex-direction:column;gap:2px;min-width:0}\n.ckf-bar{height:4px;border-radius:4px;background:var(--ckf-soft);overflow:hidden}\n.ckf-bar i{display:block;height:100%;background:var(--ckf-accent)}\n.ckf-banner{position:fixed;z-index:2147483001;left:50%;top:12px;transform:translateX(-50%);width:min(640px,calc(100vw - 24px));background:var(--ckf-bg);border-radius:12px;box-shadow:var(--ckf-shadow);padding:10px 10px 10px 16px;display:flex;align-items:center;gap:12px;animation:ckf-in .18s ease-out}\n.ckf-banner>span{flex:1;min-width:0;display:flex;flex-direction:column}\n.ckf-banner .ckf-btn{height:32px}\n.ckf-pw{max-width:420px;gap:14px}\n.ckf-root[data-still] :is(.ckf-scrim,.ckf-card,.ckf-banner){animation:none}\n.ckf-li{display:flex;gap:10px;align-items:flex-start;margin:0}\n.ckf-li::before{content:\"✓\";flex:none;width:20px;height:20px;border-radius:50%;background:color-mix(in srgb,var(--ckf-accent) 14%,var(--ckf-bg));color:var(--ckf-accent);font-size:12px;font-weight:700;display:inline-flex;align-items:center;justify-content:center}\n.ckf-quote{margin:0;padding:12px 14px;border-radius:12px;background:var(--ckf-soft)}\n.ckf-quote cite{display:block;margin-top:6px;font-style:normal;font-size:12px;color:var(--ckf-muted)}\n.ckf-plan{justify-content:space-between;min-height:52px}\n.ckf-plan span:nth-child(2){display:flex;flex-direction:column;margin-right:auto}\n.ckf-plan b{font-variant-numeric:tabular-nums}\n@keyframes ckf-fade{from{opacity:0}}\n@keyframes ckf-in{from{opacity:0;transform:translateY(6px)}}\n.ckf-banner{animation-name:ckf-fade}\n@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}}\n@media (prefers-reduced-motion:reduce){.ckf-root *{animation:none!important;transition:none!important}}\n`;\n\ntype Attrs = Record<string, string | boolean | undefined | ((e: Event) => void)>;\n\n/** A small element builder: attributes, `on*` handlers and children (strings become text, never HTML). */\nconst h = (tag: string, attrs: Attrs = {}, ...children: (Node | string | false | null | undefined)[]) => {\n const el = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) {\n if (v === undefined || v === false) continue;\n if (typeof v === \"function\") el.addEventListener(k.slice(2).toLowerCase(), v);\n else if (k === \"className\") el.className = String(v);\n else el.setAttribute(k, v === true ? \"\" : v);\n }\n for (const c of children) if (c || c === \"\") el.append(typeof c === \"string\" ? document.createTextNode(c) : c);\n return el;\n};\n\nconst button = (label: string, kind: \"primary\" | \"danger\" | \"secondary\" | \"quiet\", onClick: () => void, opts: { disabled?: boolean; id?: string } = {}) =>\n h(\n \"button\",\n {\n type: \"button\",\n className: `ckf-btn${kind === \"secondary\" ? \"\" : ` ckf-${kind}`}`,\n disabled: !!opts.disabled,\n \"data-ckf-id\": opts.id,\n onClick: () => onClick(),\n },\n label,\n );\n\nconst closeButton = (label: string, onClick: () => void) =>\n h(\"button\", { type: \"button\", className: \"ckf-x\", \"aria-label\": label, \"data-ckf-id\": \"x\", onClick: () => onClick() }, \"×\");\n\nconst dots = (step: number, steps: number) =>\n steps > 1\n ? h(\n \"span\",\n { className: \"ckf-dots\", role: \"img\", \"aria-label\": tf(\"Step {n} of {total}\", { n: step, total: steps }) },\n ...Array.from({ length: steps }, (_, i) => h(\"span\", { className: \"ckf-dot\", \"data-on\": i < step })),\n )\n : h(\"span\");\n\n/** A key that changes when the screen (not just its state) changes: then focus moves to the new screen. */\nconst screenKey = (v: FlowView) =>\n v.type === \"cancel\" ? `c:${v.screen}:${v.round ?? 1}` : v.type === \"step\" ? `s:${v.step.id}` : v.type === \"checklist\" ? `l:${v.flow.id}` : `m:${v.message.id}`;\n\n/**\n * What is open, for the opening animation: it plays when this changes. Questions, a modal and the cancel flow stay one\n * dialog across their slides; a tour's card moves to another element, so each of its steps comes in.\n */\nconst surfaceKey = (v: FlowView) =>\n v.type === \"cancel\" ? \"c\" : v.type === \"step\" && (v.step.kind === \"question\" || v.step.kind === \"modal\") ? `d:${v.flow.id}` : screenKey(v);\n\n/**\n * Draws the controller's view into the page until the returned function is called. One root element under <body>;\n * nothing is drawn while there is nothing to show.\n */\n/** The stylesheet once, and a themed root element under <body>. */\nconst rootFor = (theme: FlowsTheme) => {\n if (!document.getElementById(STYLE_ID)) {\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = FLOWS_CSS;\n document.head.appendChild(style);\n }\n const root = h(\"div\", { className: `ckf-root${theme.className ? ` ${theme.className}` : \"\"}`, \"data-theme\": theme.theme ?? \"auto\" });\n if (theme.accent) root.style.setProperty(\"--ckf-accent\", theme.accent);\n document.body.appendChild(root);\n return root;\n};\n\n/** Screen readers read the dialogs in the language of their words. */\nconst setRootLang = (root: HTMLElement) => {\n const lang = wordsLang();\n if (lang) root.setAttribute(\"lang\", lang);\n else root.removeAttribute(\"lang\");\n};\n\n/** 0.18.0: an icon (a built-in line icon, an emoji or a picture) in a box of `className`; false when there is none. */\nconst iconEl = (icon: FlowIcon | undefined, className: string): HTMLElement | false => {\n const i = iconOf(icon);\n if (!i) return false;\n const box = h(\"span\", { className, \"aria-hidden\": \"true\" });\n if (i.kind === \"emoji\") box.textContent = i.value;\n else if (i.kind === \"image\") box.append(h(\"img\", { src: i.url, alt: \"\" }));\n else {\n const ns = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(ns, \"svg\");\n for (const [k, v] of Object.entries({ viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"2\", \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\" }))\n svg.setAttribute(k, v);\n for (const d of FLOW_ICONS[i.name].paths) {\n const p = document.createElementNS(ns, \"path\");\n p.setAttribute(\"d\", d);\n svg.append(p);\n }\n box.append(svg);\n }\n return box;\n};\n\nexport const mountFlows = (ctl: FlowsController, theme: FlowsTheme = {}): (() => void) => {\n if (typeof document === \"undefined\") return () => {};\n const root = rootFor(theme);\n /** 0.18.0: the finish animation last played, so each plays once. */\n let played = \"\";\n\n let lastKey = \"\";\n let lastSurface = \"\";\n let returnFocus: HTMLElement | null = null;\n let comment = \"\";\n let placed: { float: HTMLElement; ring: HTMLElement; target: HTMLElement; side?: TourPlacement } | null = null;\n\n // ---------- Cancel flow ----------\n\n const cancelCard = (v: Extract<FlowView, { type: \"cancel\" }>) => {\n const titleId = \"ckf-title\";\n const busy = v.busy;\n const body: (Node | false)[] = [];\n if (v.screen === \"survey\") {\n body.push(\n h(\"h2\", { className: \"ckf-h\", id: titleId }, v.flow.question || t(\"Why are you leaving?\")),\n h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...v.flow.reasons.map((r) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt\",\n \"aria-checked\": String(v.reason === r.id),\n \"data-ckf-id\": `r:${r.id}`,\n onClick: () => ctl.cancel.pick(r.id),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n r.label,\n ),\n ),\n ),\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(t(\"Continue\"), \"primary\", ctl.cancel.next, { disabled: !v.reason, id: \"go\" }),\n button(t(\"Never mind, keep my plan\"), \"quiet\", ctl.cancel.close),\n ),\n );\n } else if (v.screen === \"followup\" && v.followUp) {\n const f = v.followUp;\n let field: Node;\n if (f.answers.length)\n field = h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...f.answers.map((a, i) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt\",\n \"aria-checked\": String(v.answer === a),\n \"data-ckf-id\": `a:${i}`,\n onClick: () => ctl.cancel.answer(a),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n // The label in the visitor's language; what is recorded stays `a`.\n f.answerLabels?.[i] || a,\n ),\n ),\n );\n else {\n const text = h(\"textarea\", {\n className: \"ckf-text\",\n placeholder: t(\"Your answer (optional)\"),\n \"aria-labelledby\": titleId,\n maxlength: \"500\",\n \"data-ckf-id\": \"answer\",\n onInput: (e) => ctl.cancel.answer((e.target as HTMLTextAreaElement).value),\n }) as HTMLTextAreaElement;\n text.value = v.answer ?? \"\";\n field = text;\n }\n const label = v.flow.reasons.find((r) => r.id === v.reason)?.label;\n body.push(\n label ? h(\"p\", { className: \"ckf-small\" }, tf(\"You said: {label}\", { label })) : false,\n h(\"h2\", { className: \"ckf-h\", id: titleId }, f.question),\n field,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(t(\"Continue\"), \"primary\", ctl.cancel.next, { id: \"go\" }),\n button(t(\"Never mind, keep my plan\"), \"quiet\", ctl.cancel.close),\n ),\n );\n } else if (v.screen === \"offer\" && v.offer) {\n const o = v.offer;\n const label = v.flow.reasons.find((r) => r.id === v.reason)?.label;\n let detail: Node | false = false;\n if (o.kind === \"discount\" && o.percent)\n detail = v.price\n ? h(\n \"div\",\n { className: \"ckf-box\" },\n h(\"span\", { className: \"ckf-big\" }, money(discounted(v.price.amount, o.percent), v.price.currency)),\n h(\"span\", { className: \"ckf-strike\" }, money(v.price.amount, v.price.currency)),\n h(\n \"span\",\n { className: \"ckf-small\" },\n `/${v.price.interval === \"year\" ? t(\"year\") : t(\"month\")}${o.months ? ` ${forMonths(o.months)}` : \"\"}`,\n ),\n )\n : h(\n \"div\",\n { className: \"ckf-box\" },\n h(\"span\", { className: \"ckf-big\" }, tf(\"{percent}% off\", { percent: o.percent })),\n o.months ? h(\"span\", { className: \"ckf-small\" }, forMonths(o.months)) : false,\n );\n if (o.kind === \"pause\" && o.months)\n detail = h(\n \"div\",\n { className: \"ckf-box\" },\n h(\"span\", {}, tf(\"Pause for up to {months}. Your data stays.\", { months: monthsWord(o.months) })),\n );\n if (o.kind === \"downgrade\" && o.planName) detail = h(\"div\", { className: \"ckf-box\" }, h(\"b\", {}, o.planName));\n const text =\n o.kind === \"contact\"\n ? (h(\"textarea\", {\n className: \"ckf-text\",\n placeholder: t(\"What would make you stay?\"),\n \"aria-label\": t(\"Your message\"),\n maxlength: \"500\",\n \"data-ckf-id\": \"comment\",\n onInput: (e) => (comment = (e.target as HTMLTextAreaElement).value),\n }) as HTMLTextAreaElement)\n : null;\n if (text) text.value = comment;\n body.push(\n label ? h(\"p\", { className: \"ckf-small\" }, tf(\"You said: {label}\", { label })) : false,\n h(\"h2\", { className: \"ckf-h\", id: titleId }, o.headline),\n detail,\n text ?? false,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(busy ? t(\"One moment…\") : offerButton(o), \"primary\", () => ctl.cancel.accept(comment), { disabled: busy, id: \"go\" }),\n button(t(\"No thanks, continue cancelling\"), \"quiet\", ctl.cancel.decline, { disabled: busy }),\n ),\n );\n } else {\n const plain = v.steps === 1;\n const text = plain\n ? null\n : (h(\"textarea\", {\n className: \"ckf-text\",\n placeholder: t(\"Anything else we should know? (optional)\"),\n \"aria-label\": t(\"Anything else we should know? (optional)\"),\n maxlength: \"500\",\n \"data-ckf-id\": \"comment\",\n onInput: (e) => (comment = (e.target as HTMLTextAreaElement).value),\n }) as HTMLTextAreaElement);\n if (text) text.value = comment;\n body.push(\n h(\"h2\", { className: \"ckf-h\", id: titleId }, v.flow.confirm.title),\n v.flow.confirm.body ? h(\"p\", { className: \"ckf-p\" }, v.flow.confirm.body) : false,\n text ?? false,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(busy ? t(\"One moment…\") : v.flow.confirm.button, \"danger\", () => ctl.cancel.confirm(comment), { disabled: busy, id: \"go\" }),\n button(t(\"Keep my plan\"), \"secondary\", ctl.cancel.close, { disabled: busy }),\n ),\n );\n }\n return h(\n \"div\",\n { className: \"ckf-scrim\", onClick: (e) => e.target === e.currentTarget && !busy && ctl.cancel.close() },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": titleId },\n h(\"div\", { className: \"ckf-top\" }, dots(v.step, v.steps), closeButton(t(\"Close\"), ctl.cancel.close)),\n ...body,\n v.error ? h(\"p\", { className: \"ckf-err\", role: \"alert\" }, v.error) : false,\n ),\n );\n };\n\n // ---------- Onboarding ----------\n\n /** 0.17.0: the step's picture or video above its text; a video link plays in its privacy-friendly player. */\n const media = (s: OnboardingStep) => {\n const m = mediaOf(s);\n if (!m) return false;\n if (m.kind === \"image\") return h(\"img\", { className: \"ckf-media\", src: m.url, alt: m.alt ?? \"\", onLoad: () => follow() });\n const v = videoEmbed(m.url)!;\n return v.kind === \"iframe\"\n ? h(\n \"div\",\n { className: \"ckf-video\" },\n h(\"iframe\", { src: v.src, title: m.alt || t(\"Video\"), allow: \"fullscreen; picture-in-picture\", allowfullscreen: true, loading: \"lazy\", referrerpolicy: \"strict-origin-when-cross-origin\" }),\n )\n : h(\"video\", { className: \"ckf-media\", src: v.src, controls: true, playsinline: true, preload: \"metadata\", \"aria-label\": m.alt || undefined, onLoadedmetadata: () => follow() });\n };\n\n /** 0.18.0: one question of a Questions item: a slide with dots, the options or a text field, Back and Continue. */\n const questionCard = (v: Extract<FlowView, { type: \"step\" }>) => {\n const s = v.step;\n const q = s.question;\n const titleId = \"ckf-title\";\n const ok = answerOk(q, v.answer);\n let field: Node | false = false;\n const textField = (hint: string, value: string, write: (t: string) => void) => {\n const input = h(\"input\", {\n type: \"text\",\n className: \"ckf-input\",\n placeholder: hint,\n \"aria-labelledby\": titleId,\n maxlength: \"500\",\n \"data-ckf-id\": \"answer\",\n onInput: (e) => write((e.target as HTMLInputElement).value),\n onKeydown: (e) => (e as KeyboardEvent).key === \"Enter\" && ctl.onboarding.next(),\n }) as HTMLInputElement;\n input.value = value;\n return input;\n };\n const picked = (on: boolean, id: string, label: string, press: () => void) =>\n h(\"button\", { type: \"button\", role: \"radio\", className: \"ckf-opt\", \"aria-checked\": String(on), \"data-ckf-id\": `q:${id}`, onClick: press }, h(\"span\", { className: \"ckf-radio\" }), label);\n if (q?.type === \"choice\") {\n const other = !!q.other && !!v.answer?.startsWith(OTHER_PREFIX);\n field = h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...(q.options ?? []).map((o) => picked(v.answer === o.id, o.id, o.label, () => ctl.onboarding.answer(o.id))),\n q.other ? picked(other, \"other\", q.otherLabel || t(\"Other\"), () => other || ctl.onboarding.answer(OTHER_PREFIX)) : false,\n other ? textField(t(\"Your answer\"), v.answer!.slice(OTHER_PREFIX.length), (t) => ctl.onboarding.answer(OTHER_PREFIX + t)) : false,\n );\n } else if (q?.type === \"scale\")\n field = h(\n \"div\",\n {},\n h(\n \"div\",\n { className: \"ckf-scale\", role: \"radiogroup\", \"aria-labelledby\": titleId },\n ...scaleOf(q).map((n) =>\n h(\"button\", { type: \"button\", role: \"radio\", className: \"ckf-num\", \"aria-checked\": String(v.answer === String(n)), \"data-ckf-id\": `q:${n}`, onClick: () => ctl.onboarding.answer(String(n)) }, String(n)),\n ),\n ),\n q.lowLabel || q.highLabel ? h(\"div\", { className: \"ckf-ends ckf-small\" }, h(\"span\", {}, q.lowLabel || \"\"), h(\"span\", {}, q.highLabel || \"\")) : false,\n );\n else if (q) field = textField(q.placeholder || t(\"Your answer\"), v.answer ?? \"\", (t) => ctl.onboarding.answer(t));\n return h(\n \"div\",\n { className: \"ckf-scrim\" },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": titleId },\n h(\"div\", { className: \"ckf-top\" }, dots(v.index + 1, v.total), closeButton(t(\"Close\"), ctl.onboarding.dismiss)),\n v.index === 0 ? iconEl(v.flow.icon, \"ckf-hic\") : false,\n h(\"h2\", { className: \"ckf-h\", id: titleId }, s.title),\n s.body ? h(\"p\", { className: \"ckf-p\" }, s.body) : false,\n field,\n h(\n \"div\",\n { className: \"ckf-row\" },\n v.back ? button(t(\"Back\"), \"quiet\", ctl.onboarding.back) : false,\n q?.optional ? button(q.skipLabel || t(\"Skip\"), \"quiet\", ctl.onboarding.skip) : false,\n button(s.button || (v.last ? t(\"Done\") : t(\"Continue\")), \"primary\", ctl.onboarding.next, { disabled: !ok, id: \"go\" }),\n ),\n ),\n );\n };\n\n const stepCard = (v: Extract<FlowView, { type: \"step\" }>) => {\n const s = v.step;\n if (s.kind === \"question\") return questionCard(v);\n const card = h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": s.kind === \"modal\" ? \"true\" : undefined, \"aria-labelledby\": \"ckf-title\" },\n h(\n \"div\",\n { className: \"ckf-top\" },\n v.total > 1 ? h(\"p\", { className: \"ckf-small\" }, tf(\"Step {n} of {total}\", { n: v.index + 1, total: v.total })) : h(\"span\"),\n closeButton(t(\"Close the tour\"), ctl.onboarding.dismiss),\n ),\n s.kind === \"modal\" ? iconEl(v.flow.icon, \"ckf-hic\") : false,\n media(s),\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, s.title),\n s.body ? h(\"p\", { className: \"ckf-p\" }, s.body) : false,\n h(\"div\", { className: \"ckf-row\" }, button(s.button || (v.last ? t(\"Done\") : t(\"Next\")), \"primary\", ctl.onboarding.next, { id: \"go\" })),\n );\n if (s.kind === \"modal\") return h(\"div\", { className: \"ckf-scrim\" }, card);\n const target = s.target ? findTarget(s.target) : null;\n const float = h(\"div\", { className: \"ckf-float\" }, card);\n if (target) {\n const ring = h(\"div\", { className: \"ckf-ring\", \"aria-hidden\": \"true\" });\n float.append(h(\"span\", { className: \"ckf-arrow\", \"aria-hidden\": \"true\" }));\n placed = { float, ring, target, side: s.placement };\n place(float, ring, target, s.placement);\n return h(\"div\", {}, ring, float);\n }\n return float;\n };\n\n /**\n * The element a tour step points at: a CSS selector (`#new-project`, `.toolbar button`, picked on the site in\n * MRRocket), or a plain name for `data-ck-target=\"…\"`. A selector that does not parse falls back to the name.\n */\n const findTarget = (t: string): HTMLElement | null => {\n const named = () => document.querySelector<HTMLElement>(`[data-ck-target=\"${CSS.escape(t)}\"]`);\n if (!/^[#.[]|[\\s>:=]/.test(t)) return named();\n return safeQuery(t) ?? named();\n };\n const safeQuery = (sel: string) => {\n try {\n return document.querySelector<HTMLElement>(sel);\n } catch {\n return null;\n }\n };\n\n /**\n * Puts a tour card next to the element it points at, on the step's side (0.17.0) or, on \"auto\", below it and above\n * when there is no room. A side without room flips to the opposite one, then to any side with room.\n */\n const place = (float: HTMLElement, ring: HTMLElement, target: HTMLElement, side: TourPlacement = \"auto\") => {\n const r = target.getBoundingClientRect();\n Object.assign(ring.style, { left: `${r.left - 4}px`, top: `${r.top - 4}px`, width: `${r.width + 8}px`, height: `${r.height + 8}px` });\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = Math.min(340, vw - 24);\n const ht = float.offsetHeight || 200;\n const gap = 14;\n const room: Record<string, boolean> = {\n bottom: vh - r.bottom - gap - 12 >= ht,\n top: r.top - gap - 12 >= ht,\n right: vw - r.right - gap - 12 >= w,\n left: r.left - gap - 12 >= w,\n };\n const flip: Record<string, string> = { top: \"bottom\", bottom: \"top\", left: \"right\", right: \"left\" };\n const order = side === \"auto\" || !flip[side] ? [\"bottom\", \"top\"] : [side, flip[side], \"bottom\", \"top\", \"right\", \"left\"];\n const s = order.find((x) => room[x]) ?? (side !== \"auto\" && flip[side] ? side : r.top > vh - r.bottom ? \"top\" : \"bottom\");\n const clamp = (v: number, hi: number) => Math.max(12, Math.min(v, hi - 12));\n const across = s === \"top\" || s === \"bottom\";\n // \"auto\" keeps the card's left edge at the element's, as before 0.17.0; a chosen side centres it.\n const left = across ? clamp(side === \"auto\" ? r.left : r.left + r.width / 2 - w / 2, vw - w) : s === \"right\" ? r.right + gap : r.left - gap - w;\n const top = across ? (s === \"bottom\" ? r.bottom + gap : r.top - gap - ht) : clamp(r.top + r.height / 2 - ht / 2, vh - ht);\n Object.assign(float.style, { left: `${left}px`, top: `${top}px`, right: \"auto\", bottom: \"auto\", width: `${w}px` });\n float.setAttribute(\"data-side\", s);\n // The arrow points at the element's middle, kept off the card's rounded corners.\n const at = across ? r.left + r.width / 2 - left : r.top + r.height / 2 - top;\n float.style.setProperty(\"--ckf-ap\", `${Math.max(18, Math.min(at, (across ? w : ht) - 18))}px`);\n };\n\n const checklist = (v: Extract<FlowView, { type: \"checklist\" }>) => {\n const done = v.items.filter((i) => i.done).length;\n return h(\n \"div\",\n { className: \"ckf-float\" },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"region\", \"aria-labelledby\": \"ckf-title\" },\n h(\n \"div\",\n { className: \"ckf-top\" },\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, v.flow.name),\n closeButton(t(\"Hide the checklist\"), ctl.onboarding.dismiss),\n ),\n h(\"p\", { className: \"ckf-small\" }, tf(\"{done} of {total} done\", { done, total: v.items.length })),\n h(\n \"div\",\n { className: \"ckf-bar\", role: \"progressbar\", \"aria-valuemin\": \"0\", \"aria-valuemax\": String(v.items.length), \"aria-valuenow\": String(done) },\n h(\"i\", { style: `width:${(done / v.items.length) * 100}%` } as Attrs),\n ),\n h(\n \"div\",\n { className: \"ckf-opts\" },\n ...v.items.map(({ step, done: d, opens }) => {\n const inner: (Node | false)[] = [\n h(\"span\", { className: \"ckf-tick\", \"aria-hidden\": \"true\" }, d ? \"✓\" : \"\"),\n iconEl(step.icon, \"ckf-ic\"),\n h(\"span\", {}, h(\"b\", {}, step.title), step.body ? h(\"span\", { className: \"ckf-small\" }, step.body) : false),\n ];\n // 0.17.0/0.18.0: a task that opens something (a tour, a modal, a page, the app's code) does it;\n // a finished tour or modal ticks it, a page or the app's code once opened (unless an event does).\n if (!d && opens)\n return h(\n \"button\",\n {\n type: \"button\",\n className: \"ckf-check\",\n \"aria-label\": tf(\"Start “{title}”\", { title: step.title }),\n \"data-ckf-id\": `t:${step.id}`,\n onClick: () => ctl.onboarding.open(step.id),\n },\n ...inner,\n h(\"span\", { className: \"ckf-go\", \"aria-hidden\": \"true\" }, \"›\"),\n );\n // An item with an event ticks itself when the app records it; the others are ticked by hand.\n return d || step.event\n ? h(\"div\", { className: \"ckf-check\", \"data-done\": d, role: \"listitem\" }, ...inner)\n : h(\n \"button\",\n {\n type: \"button\",\n className: \"ckf-check\",\n \"aria-label\": tf(\"Mark “{title}” done\", { title: step.title }),\n \"data-ckf-id\": `i:${step.id}`,\n onClick: () => ctl.onboarding.check(step.id),\n },\n ...inner,\n );\n }),\n ),\n ),\n );\n };\n\n // ---------- Messages ----------\n\n const message = (v: Extract<FlowView, { type: \"message\" }>) => {\n const m = v.message;\n const action = m.button ? button(m.button, \"primary\", ctl.message.click, { id: \"go\" }) : false;\n if (m.style === \"banner\")\n return h(\n \"div\",\n { className: \"ckf-banner\", role: \"status\" },\n h(\"span\", {}, h(\"b\", {}, m.title), m.body ? h(\"span\", { className: \"ckf-small\" }, m.body) : false),\n action,\n closeButton(t(\"Dismiss\"), ctl.message.dismiss),\n );\n return h(\n \"div\",\n { className: \"ckf-scrim\", onClick: (e) => e.target === e.currentTarget && ctl.message.dismiss() },\n h(\n \"div\",\n { className: \"ckf-card\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": \"ckf-title\" },\n h(\"div\", { className: \"ckf-top\" }, h(\"span\"), closeButton(t(\"Dismiss\"), ctl.message.dismiss)),\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, m.title),\n m.body ? h(\"p\", { className: \"ckf-p\" }, m.body) : false,\n action ? h(\"div\", { className: \"ckf-row\" }, action) : false,\n ),\n );\n };\n\n // ---------- Drawing ----------\n\n const draw = () => {\n const v = ctl.view();\n setRootLang(root);\n // 0.18.0: the product's brand color from MRRocket, unless the site set an accent of its own.\n const accent = theme.accent ?? ctl.accent?.();\n if (accent) root.style.setProperty(\"--ckf-accent\", accent);\n // 0.18.0: someone just finished a checklist, a tour or the questions.\n const fin = ctl.finale?.();\n if (fin && fin.key !== played) {\n played = fin.key;\n playFinish(fin.kind, { accent });\n }\n const key = v ? screenKey(v) : \"\";\n const focused = (document.activeElement as HTMLElement | null)?.closest?.(\".ckf-root\") ? document.activeElement?.getAttribute(\"data-ckf-id\") : null;\n if (key && !lastKey && document.activeElement instanceof HTMLElement && !document.activeElement.closest(\".ckf-root\"))\n returnFocus = document.activeElement;\n if (key !== lastKey && !key.startsWith(\"c:\")) comment = \"\";\n if (!key) comment = \"\";\n placed = null;\n const surface = v ? surfaceKey(v) : \"\";\n root.toggleAttribute(\"data-still\", !!surface && surface === lastSurface);\n lastSurface = surface;\n root.replaceChildren(\n ...(v ? [v.type === \"cancel\" ? cancelCard(v) : v.type === \"step\" ? stepCard(v) : v.type === \"checklist\" ? checklist(v) : message(v)] : []),\n );\n // Placed again now that the card is in the page and has its real height.\n follow();\n if (key !== lastKey) {\n // A new screen: focus its first control (a dialog's), so keyboard and screen reader users land in it.\n const modal = root.querySelector<HTMLElement>(\"[aria-modal=true]\");\n const first = modal?.querySelector<HTMLElement>(\"[role=radio], input, [data-ckf-id=go], textarea\") ?? null;\n first?.focus();\n if (!key && returnFocus) {\n returnFocus.focus();\n returnFocus = null;\n }\n } else if (focused) root.querySelector<HTMLElement>(`[data-ckf-id=\"${CSS.escape(focused)}\"]`)?.focus();\n lastKey = key;\n };\n\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n const v = ctl.view();\n if (v?.type === \"cancel\") ctl.cancel.close();\n else if (v?.type === \"message\") ctl.message.dismiss();\n else if (v?.type === \"step\" && (v.step.kind === \"modal\" || v.step.kind === \"question\")) ctl.onboarding.dismiss();\n };\n // A tour card follows its element when the page scrolls or resizes.\n function follow() {\n if (placed) place(placed.float, placed.ring, placed.target, placed.side);\n }\n document.addEventListener(\"keydown\", onKey);\n window.addEventListener(\"resize\", follow);\n window.addEventListener(\"scroll\", follow, { passive: true, capture: true });\n const off = ctl.subscribe(draw);\n const offWords = onWords(draw);\n draw();\n return () => {\n off();\n offWords();\n document.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"resize\", follow);\n window.removeEventListener(\"scroll\", follow, { capture: true });\n root.remove();\n };\n};\n\n/**\n * Draws an open paywall (paywall.ts) page by page until the returned function is called: the dots, the page's title and\n * text, its benefits, quotes or plans, Back and the button. Closes on Escape and on a click beside the card.\n */\nexport const mountPaywall = (host: PaywallHost, theme: FlowsTheme = {}): (() => void) => {\n if (typeof document === \"undefined\") return () => {};\n const root = rootFor(theme);\n let lastKey = \"\";\n let returnFocus: HTMLElement | null = null;\n const draw = () => {\n const v = host.view();\n setRootLang(root);\n const key = v ? `${v.paywall.id}:${v.index}` : \"\";\n if (key && !lastKey && document.activeElement instanceof HTMLElement) returnFocus = document.activeElement;\n if (!v) {\n root.replaceChildren();\n root.removeAttribute(\"data-still\");\n if (lastKey) returnFocus?.focus();\n lastKey = \"\";\n return;\n }\n // Fades in when it opens, not again on every page or plan.\n if (lastKey) root.setAttribute(\"data-still\", \"\");\n const p = v.page;\n const plans =\n p.kind === \"plans\"\n ? h(\n \"div\",\n { className: \"ckf-opts\", role: \"radiogroup\", \"aria-label\": t(\"Plans\") },\n ...v.plans.map((plan) =>\n h(\n \"button\",\n {\n type: \"button\",\n role: \"radio\",\n className: \"ckf-opt ckf-plan\",\n \"aria-checked\": String(v.plan === plan.id),\n \"data-ckf-id\": `p:${plan.id}`,\n onClick: () => host.pick(plan.id),\n },\n h(\"span\", { className: \"ckf-radio\" }),\n h(\"span\", {}, plan.name, plan.note ? h(\"span\", { className: \"ckf-small\" }, plan.note) : false),\n h(\"b\", {}, plan.price),\n ),\n ),\n )\n : false;\n root.replaceChildren(\n h(\n \"div\",\n { className: \"ckf-scrim\", onClick: (e) => e.target === e.currentTarget && host.close() },\n h(\n \"div\",\n { className: \"ckf-card ckf-pw\", role: \"dialog\", \"aria-modal\": \"true\", \"aria-labelledby\": \"ckf-title\" },\n h(\"div\", { className: \"ckf-top\" }, dots(v.index + 1, v.total), closeButton(t(\"Close\"), host.close)),\n h(\"h2\", { className: \"ckf-h\", id: \"ckf-title\" }, p.title),\n p.body ? h(\"p\", { className: \"ckf-p\" }, p.body) : false,\n p.kind === \"benefits\" && p.items?.length ? h(\"div\", { className: \"ckf-opts\" }, ...p.items.map((i) => h(\"p\", { className: \"ckf-li\" }, i))) : false,\n p.kind === \"proof\" && p.quotes?.length\n ? h(\"div\", { className: \"ckf-opts\" }, ...p.quotes.map((q) => h(\"blockquote\", { className: \"ckf-quote\" }, q.text, q.by ? h(\"cite\", {}, q.by) : false)))\n : false,\n plans,\n v.error ? h(\"p\", { className: \"ckf-err\", role: \"alert\" }, v.error) : false,\n h(\n \"div\",\n { className: \"ckf-btns\" },\n button(v.busy ? t(\"One moment…\") : p.button || t(\"Continue\"), \"primary\", host.next, {\n disabled: v.busy || (p.kind === \"plans\" && !v.plan),\n id: \"go\",\n }),\n v.index ? button(t(\"Back\"), \"quiet\", host.back, { disabled: v.busy }) : false,\n ),\n ),\n ),\n );\n if (key !== lastKey) root.querySelector<HTMLElement>(\"[data-ckf-id=go]\")?.focus();\n lastKey = key;\n };\n const onKey = (e: KeyboardEvent) => {\n if (!host.view()) return;\n if (e.key === \"Escape\") host.close();\n };\n document.addEventListener(\"keydown\", onKey);\n const off = host.subscribe(draw);\n const offWords = onWords(draw);\n draw();\n return () => {\n off();\n offWords();\n document.removeEventListener(\"keydown\", onKey);\n root.remove();\n };\n};\n"],"mappings":"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","names":["t"]}
package/dist/flows-web.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/flows-web.ts
2
2
  import { safeUrl } from "./flows.js";
3
3
  import { warnUnsigned } from "./identity.js";
4
+ import { langParam } from "./i18n.js";
4
5
  var local = {
5
6
  get: (key) => {
6
7
  try {
@@ -42,7 +43,7 @@ var webFlowsEnv = (o) => ({
42
43
  fetchInApp: async (id) => {
43
44
  if (!o.apiKey) return null;
44
45
  const hash = o.userHash?.(id);
45
- const r = await fetch(`${o.host}/api/sdk/inapp?key=${encodeURIComponent(o.apiKey)}&distinctId=${encodeURIComponent(id)}${hash ? `&userHash=${hash}` : ""}`);
46
+ const r = await fetch(`${o.host}/api/sdk/inapp?key=${encodeURIComponent(o.apiKey)}&distinctId=${encodeURIComponent(id)}${hash ? `&userHash=${hash}` : ""}${langParam()}`);
46
47
  warnUnsigned(r.status);
47
48
  return r.ok ? await r.json() : null;
48
49
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/flows-web.ts"],"sourcesContent":["/**\n * What the flows controller (flows.ts) needs in a browser, shared by the Next.js provider and the script tag: the\n * person's messages and onboarding progress from `GET /api/sdk/inapp`, progress kept in localStorage only while the\n * consent is \"cookies\", and links opened in the same tab. Plain functions; only called in the browser.\n */\nimport { type FlowsEnv, type InAppState, type OnboardingFlow, safeUrl } from \"./flows\";\nimport { warnUnsigned } from \"./identity\";\n\nexport interface WebFlowsOptions {\n host: string;\n apiKey: string;\n track: FlowsEnv[\"track\"];\n /** The identify() id while tracking is allowed; undefined otherwise (no messages, no stored progress then). */\n personId: () => string | undefined;\n /** The identity hash of that person (0.16.0), when the site gave one to identify. */\n userHash?: (id: string) => string | undefined;\n /** True while the consent is \"cookies\": progress may be kept in localStorage. */\n canStore: () => boolean;\n auto?: boolean;\n /**\n * 0.18.0: the app's own way to open a checklist task's page or screen (a single-page app's router). Without it a\n * path or an http(s) address opens in the same tab; anything else is not opened.\n */\n onNavigate?: () => ((target: string) => void) | undefined;\n /** 0.18.0: a checklist task that runs the app's own code. */\n onTask?: () => ((taskId: string, item: OnboardingFlow) => void) | undefined;\n}\n\nconst local = {\n get: (key: string) => {\n try {\n return window.localStorage.getItem(key);\n } catch {\n return null;\n }\n },\n set: (key: string, value: string) => {\n try {\n window.localStorage.setItem(key, value);\n } catch {\n // Private mode or full: progress stays in memory.\n }\n },\n};\n\n/** Removes what the flows kept in localStorage (consent withdrawn). */\nexport const forgetFlowsStorage = () => {\n try {\n for (let i = window.localStorage.length - 1; i >= 0; i--) {\n const key = window.localStorage.key(i);\n if (key?.startsWith(\"mrrocket:onboarding\")) window.localStorage.removeItem(key);\n }\n } catch {\n // No storage: nothing to delete.\n }\n};\n\nexport const webFlowsEnv = (o: WebFlowsOptions): FlowsEnv => ({\n track: o.track,\n personId: o.personId,\n auto: o.auto,\n storage: () => (o.canStore() ? local : null),\n openUrl: (url) => window.location.assign(url),\n path: () => window.location.pathname,\n navigate: (target) => {\n const own = o.onNavigate?.();\n if (own) return own(target);\n const url = safeUrl(target);\n if (url) window.location.assign(url);\n },\n task: (taskId, item) => o.onTask?.()?.(taskId, item),\n fetchInApp: async (id) => {\n if (!o.apiKey) return null;\n const hash = o.userHash?.(id);\n const r = await fetch(`${o.host}/api/sdk/inapp?key=${encodeURIComponent(o.apiKey)}&distinctId=${encodeURIComponent(id)}${hash ? `&userHash=${hash}` : \"\"}`);\n warnUnsigned(r.status);\n return r.ok ? ((await r.json()) as InAppState) : null;\n },\n});\n"],"mappings":";AAKA,SAA8D,eAAe;AAC7E,SAAS,oBAAoB;AAsB7B,IAAM,QAAQ;AAAA,EACV,KAAK,CAAC,QAAgB;AAClB,QAAI;AACA,aAAO,OAAO,aAAa,QAAQ,GAAG;AAAA,IAC1C,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EACA,KAAK,CAAC,KAAa,UAAkB;AACjC,QAAI;AACA,aAAO,aAAa,QAAQ,KAAK,KAAK;AAAA,IAC1C,QAAQ;AAAA,IAER;AAAA,EACJ;AACJ;AAGO,IAAM,qBAAqB,MAAM;AACpC,MAAI;AACA,aAAS,IAAI,OAAO,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AACtD,YAAM,MAAM,OAAO,aAAa,IAAI,CAAC;AACrC,UAAI,KAAK,WAAW,qBAAqB,EAAG,QAAO,aAAa,WAAW,GAAG;AAAA,IAClF;AAAA,EACJ,QAAQ;AAAA,EAER;AACJ;AAEO,IAAM,cAAc,CAAC,OAAkC;AAAA,EAC1D,OAAO,EAAE;AAAA,EACT,UAAU,EAAE;AAAA,EACZ,MAAM,EAAE;AAAA,EACR,SAAS,MAAO,EAAE,SAAS,IAAI,QAAQ;AAAA,EACvC,SAAS,CAAC,QAAQ,OAAO,SAAS,OAAO,GAAG;AAAA,EAC5C,MAAM,MAAM,OAAO,SAAS;AAAA,EAC5B,UAAU,CAAC,WAAW;AAClB,UAAM,MAAM,EAAE,aAAa;AAC3B,QAAI,IAAK,QAAO,IAAI,MAAM;AAC1B,UAAM,MAAM,QAAQ,MAAM;AAC1B,QAAI,IAAK,QAAO,SAAS,OAAO,GAAG;AAAA,EACvC;AAAA,EACA,MAAM,CAAC,QAAQ,SAAS,EAAE,SAAS,IAAI,QAAQ,IAAI;AAAA,EACnD,YAAY,OAAO,OAAO;AACtB,QAAI,CAAC,EAAE,OAAQ,QAAO;AACtB,UAAM,OAAO,EAAE,WAAW,EAAE;AAC5B,UAAM,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,sBAAsB,mBAAmB,EAAE,MAAM,CAAC,eAAe,mBAAmB,EAAE,CAAC,GAAG,OAAO,aAAa,IAAI,KAAK,EAAE,EAAE;AAC1J,iBAAa,EAAE,MAAM;AACrB,WAAO,EAAE,KAAO,MAAM,EAAE,KAAK,IAAoB;AAAA,EACrD;AACJ;","names":[]}
1
+ {"version":3,"sources":["../src/flows-web.ts"],"sourcesContent":["/**\n * What the flows controller (flows.ts) needs in a browser, shared by the Next.js provider and the script tag: the\n * person's messages and onboarding progress from `GET /api/sdk/inapp`, progress kept in localStorage only while the\n * consent is \"cookies\", and links opened in the same tab. Plain functions; only called in the browser.\n */\nimport { type FlowsEnv, type InAppState, type OnboardingFlow, safeUrl } from \"./flows\";\nimport { warnUnsigned } from \"./identity\";\nimport { langParam } from \"./i18n\";\n\nexport interface WebFlowsOptions {\n host: string;\n apiKey: string;\n track: FlowsEnv[\"track\"];\n /** The identify() id while tracking is allowed; undefined otherwise (no messages, no stored progress then). */\n personId: () => string | undefined;\n /** The identity hash of that person (0.16.0), when the site gave one to identify. */\n userHash?: (id: string) => string | undefined;\n /** True while the consent is \"cookies\": progress may be kept in localStorage. */\n canStore: () => boolean;\n auto?: boolean;\n /**\n * 0.18.0: the app's own way to open a checklist task's page or screen (a single-page app's router). Without it a\n * path or an http(s) address opens in the same tab; anything else is not opened.\n */\n onNavigate?: () => ((target: string) => void) | undefined;\n /** 0.18.0: a checklist task that runs the app's own code. */\n onTask?: () => ((taskId: string, item: OnboardingFlow) => void) | undefined;\n}\n\nconst local = {\n get: (key: string) => {\n try {\n return window.localStorage.getItem(key);\n } catch {\n return null;\n }\n },\n set: (key: string, value: string) => {\n try {\n window.localStorage.setItem(key, value);\n } catch {\n // Private mode or full: progress stays in memory.\n }\n },\n};\n\n/** Removes what the flows kept in localStorage (consent withdrawn). */\nexport const forgetFlowsStorage = () => {\n try {\n for (let i = window.localStorage.length - 1; i >= 0; i--) {\n const key = window.localStorage.key(i);\n if (key?.startsWith(\"mrrocket:onboarding\")) window.localStorage.removeItem(key);\n }\n } catch {\n // No storage: nothing to delete.\n }\n};\n\nexport const webFlowsEnv = (o: WebFlowsOptions): FlowsEnv => ({\n track: o.track,\n personId: o.personId,\n auto: o.auto,\n storage: () => (o.canStore() ? local : null),\n openUrl: (url) => window.location.assign(url),\n path: () => window.location.pathname,\n navigate: (target) => {\n const own = o.onNavigate?.();\n if (own) return own(target);\n const url = safeUrl(target);\n if (url) window.location.assign(url);\n },\n task: (taskId, item) => o.onTask?.()?.(taskId, item),\n fetchInApp: async (id) => {\n if (!o.apiKey) return null;\n const hash = o.userHash?.(id);\n const r = await fetch(`${o.host}/api/sdk/inapp?key=${encodeURIComponent(o.apiKey)}&distinctId=${encodeURIComponent(id)}${hash ? `&userHash=${hash}` : \"\"}${langParam()}`);\n warnUnsigned(r.status);\n return r.ok ? ((await r.json()) as InAppState) : null;\n },\n});\n"],"mappings":";AAKA,SAA8D,eAAe;AAC7E,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAsB1B,IAAM,QAAQ;AAAA,EACV,KAAK,CAAC,QAAgB;AAClB,QAAI;AACA,aAAO,OAAO,aAAa,QAAQ,GAAG;AAAA,IAC1C,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EACA,KAAK,CAAC,KAAa,UAAkB;AACjC,QAAI;AACA,aAAO,aAAa,QAAQ,KAAK,KAAK;AAAA,IAC1C,QAAQ;AAAA,IAER;AAAA,EACJ;AACJ;AAGO,IAAM,qBAAqB,MAAM;AACpC,MAAI;AACA,aAAS,IAAI,OAAO,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AACtD,YAAM,MAAM,OAAO,aAAa,IAAI,CAAC;AACrC,UAAI,KAAK,WAAW,qBAAqB,EAAG,QAAO,aAAa,WAAW,GAAG;AAAA,IAClF;AAAA,EACJ,QAAQ;AAAA,EAER;AACJ;AAEO,IAAM,cAAc,CAAC,OAAkC;AAAA,EAC1D,OAAO,EAAE;AAAA,EACT,UAAU,EAAE;AAAA,EACZ,MAAM,EAAE;AAAA,EACR,SAAS,MAAO,EAAE,SAAS,IAAI,QAAQ;AAAA,EACvC,SAAS,CAAC,QAAQ,OAAO,SAAS,OAAO,GAAG;AAAA,EAC5C,MAAM,MAAM,OAAO,SAAS;AAAA,EAC5B,UAAU,CAAC,WAAW;AAClB,UAAM,MAAM,EAAE,aAAa;AAC3B,QAAI,IAAK,QAAO,IAAI,MAAM;AAC1B,UAAM,MAAM,QAAQ,MAAM;AAC1B,QAAI,IAAK,QAAO,SAAS,OAAO,GAAG;AAAA,EACvC;AAAA,EACA,MAAM,CAAC,QAAQ,SAAS,EAAE,SAAS,IAAI,QAAQ,IAAI;AAAA,EACnD,YAAY,OAAO,OAAO;AACtB,QAAI,CAAC,EAAE,OAAQ,QAAO;AACtB,UAAM,OAAO,EAAE,WAAW,EAAE;AAC5B,UAAM,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,sBAAsB,mBAAmB,EAAE,MAAM,CAAC,eAAe,mBAAmB,EAAE,CAAC,GAAG,OAAO,aAAa,IAAI,KAAK,EAAE,GAAG,UAAU,CAAC,EAAE;AACxK,iBAAa,EAAE,MAAM;AACrB,WAAO,EAAE,KAAO,MAAM,EAAE,KAAK,IAAoB;AAAA,EACrD;AACJ;","names":[]}
package/dist/flows.d.ts CHANGED
@@ -39,8 +39,10 @@ export interface CancelOffer {
39
39
  /** 0.15.0: a second question after an answer ("What would be a fair price?"); no answers means a free text. */
40
40
  export interface CancelFollowUp {
41
41
  question: string;
42
- /** The choices, in order; empty for a free text. */
42
+ /** The choices, in order; empty for a free text. What is recorded and what rules compare, whatever the language. */
43
43
  answers: string[];
44
+ /** 0.21.0: what each choice says in the visitor's language, parallel to `answers`; shown instead of them. */
45
+ answerLabels?: string[];
44
46
  }
45
47
  /**
46
48
  * 0.15.0: a different offer for some customers of one answer. Every condition that is set must hold; the first rule
@@ -123,11 +125,15 @@ export type FlowIcon = {
123
125
  };
124
126
  /** 0.18.0: what plays when someone finishes a checklist, a tour or the questions. */
125
127
  export type FinishAnimation = "none" | "confetti" | "fireworks" | "stars";
126
- /** 0.18.0: one question of a Questions item: one choice of 2 to 6 options, or a short text. */
128
+ /**
129
+ * 0.18.0: one question of a Questions item: one choice of 2 to 6 options, or a short text. 0.21.0: a number scale, an
130
+ * "Other" with the person's own words, and a Skip button. An older app shows a scale as a text field, leaves "Other"
131
+ * out, and offers no Skip (its close button still ends the window).
132
+ */
127
133
  export interface OnboardingQuestion {
128
134
  /** The answer's name on the contact (`onboarding.<key>`) and in "People who answered …". */
129
135
  key: string;
130
- type: "choice" | "text";
136
+ type: "choice" | "text" | "scale";
131
137
  /** Choice: the options, in order; `id` is what is stored, `label` what people read. */
132
138
  options?: {
133
139
  id: string;
@@ -135,6 +141,19 @@ export interface OnboardingQuestion {
135
141
  }[];
136
142
  /** Text: the field's hint. */
137
143
  placeholder?: string;
144
+ /** 0.21.0, choice: one more option where people type their own words, stored as `other:<words>`. */
145
+ other?: boolean;
146
+ /** 0.21.0: the words of that option; "Other" when unset. */
147
+ otherLabel?: string;
148
+ /** 0.21.0, scale: the lowest and highest number, and the words under both ends. */
149
+ min?: number;
150
+ max?: number;
151
+ lowLabel?: string;
152
+ highLabel?: string;
153
+ /** 0.21.0: people may go on without answering. */
154
+ optional?: boolean;
155
+ /** 0.21.0: the words of that button; "Skip" when unset. */
156
+ skipLabel?: string;
138
157
  }
139
158
  /** 0.17.0: where a tour bubble sits next to its element; "auto" (and no value) puts it below, else above, as before. */
140
159
  export type TourPlacement = "auto" | "top" | "bottom" | "left" | "right";
@@ -420,6 +439,8 @@ export interface FlowsController {
420
439
  startTour(stepId: string): boolean;
421
440
  open(stepId: string): boolean;
422
441
  answer(value: string): void;
442
+ /** 0.21.0: goes on from an optional question without an answer. */
443
+ skip(): void;
423
444
  back(): void;
424
445
  item(id: string): OnboardingItemState | null;
425
446
  seen(id: string): void;
@@ -483,9 +504,16 @@ export declare const AFTER_PREFIX = "after:";
483
504
  export declare const afterOf: (trigger: string | undefined) => string | null;
484
505
  /** 0.18.0: what a task opens; a 0.17.0 `startsTour` reads as opening that tour. */
485
506
  export declare const opensOf: (step: Pick<OnboardingStep, "opens" | "startsTour">) => TaskOpens | undefined;
486
- /** 0.18.0: a usable answer to a question: one of its options' ids, or a text of 1 to 500 characters. */
507
+ /** 0.21.0: how a choice answer in the person's own words starts. */
508
+ export declare const OTHER_PREFIX = "other:";
509
+ /** 0.21.0: the numbers of a scale question, low to high. */
510
+ export declare const scaleOf: (q: OnboardingQuestion | undefined) => number[];
511
+ /**
512
+ * 0.18.0: a usable answer to a question: one of its options' ids, or a text of 1 to 500 characters. 0.21.0: the words
513
+ * of "Other", or a number of the scale.
514
+ */
487
515
  export declare const answerOk: (q: OnboardingQuestion | undefined, value: string | undefined) => boolean;
488
- /** The option's words for an answer (a text answer is its own words). */
516
+ /** The option's words for an answer (a text answer is its own words, "Other" the words typed, a number itself). */
489
517
  export declare const answerLabel: (q: OnboardingQuestion | undefined, value: string) => string;
490
518
  /**
491
519
  * 0.17.0: how a video link plays. YouTube, Vimeo and Loom through their players without tracking cookies
@@ -505,7 +533,11 @@ export declare const discounted: (amount: number, percent: number) => number;
505
533
  /** "€20.30" in the customer's own currency, without a library. */
506
534
  export declare const money: (amount: number, currency: string) => string;
507
535
  /** The button of an offer. */
508
- export declare const offerButton: (o: CancelOffer) => "Send to the team" | "Pause instead" | "Switch plan" | "Accept offer";
536
+ export declare const offerButton: (o: CancelOffer) => string;
537
+ /** "3 months". */
538
+ export declare const monthsWord: (n: number) => string;
539
+ /** "for 3 months". */
540
+ export declare const forMonths: (n: number) => string;
509
541
  /** A link a message may open: http(s), or a path of the app. Nothing else (no `javascript:`). */
510
542
  export declare const safeUrl: (url: string | undefined) => string | undefined;
511
543
  /** The flow's nodes: the whole tree (0.11.0 config), or the plain steps of an older one. */