@burdenoff/website-sdk 2026.1104.2 → 2026.1104.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/explore-avatar-api.ts","../../src/components/explore-avatar-i18n.ts","../../src/components/explore-avatar-turnstile.ts","../../src/components/explore-avatar-live-view.tsx"],"names":["INERT","locale","live","base","headers","off","shown","body","exchange","token","now","conversation","current","outcome","top","media","actions"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * BOFF-9797. The website live avatar's three requests, as a visitor's browser makes them.\n *\n * They go to the global gateway's web branch, under the SDK's configured gateway (`/api/web-avatar/v1/*` on its\n * origin), and follow the website avatar web API, v1:\n *\n * GET /availability?site=…&locale=… when the Avatar tab opens, never on page load\n * POST /sessions after the visitor's consent (and the bot check, where the server runs one)\n * POST /sessions/{id}/end Stop, leaving the tab, closing the panel, hiding the page\n *\n * - **Never with credentials** (`credentials: 'omit'`): a website visitor has no account, no cookie and no workspace\n * here.\n * - **The bot check's token** goes in the `x-web-avatar-bot-token` header, on create only, and only when the server\n * checks for bots: availability says whether it does (`botCheck`, contract v1.2). The gateway verifies it and drops\n * it; the body is exactly the contract's six fields. The check itself is bound to that body (contract v1.1): see\n * {@link avatarBotBinding}. A server that runs no bot check gets no header at all.\n * - **The end is a simple request** (see {@link sendEnd}): no `Content-Type` of our own, so a page being hidden has no\n * CORS preflight to wait for.\n * - **Every answer is read into one of a few outcomes** the Avatar tab can show. A missing route, a forbidden one, a\n * refused origin and a network failure are all `inert`: the tab shows what it showed before there was a live\n * avatar. Nothing a server says is shown as it was said.\n * - Nothing here logs. The conversation token goes into the create body and nowhere else, and the session's secret\n * only into the end body.\n */\n\nimport { isAvatarSite, isAvatarVersion } from \"./explore-avatar-live-config\";\n\n// The few helpers the panel itself needs (where the requests go, and the shapes a config may take) live in\n// `explore-avatar-live-config.ts`, so that they do not drag this file into every site's bundle; they are re-exported\n// here, where the rest of the contract's grammar is.\nexport {\n AVATAR_WEB_API_PATH,\n avatarApiBase,\n isAvatarSite,\n isAvatarVersion,\n} from \"./explore-avatar-live-config\";\n\n/** How long the Avatar tab waits to hear whether the live avatar is offered. */\nconst AVAILABILITY_TIMEOUT_MS = 8_000;\n/** How long a create may take: past the gateway's own deadline for it, so the gateway's answer is what decides. */\nconst CREATE_TIMEOUT_MS = 30_000;\n\n/** The refusals the Avatar tab explains, each in a short sentence of its own. */\nexport type AvatarRefusal =\n | \"busy\"\n | \"limits\"\n | \"region\"\n | \"locale\"\n | \"paused\"\n | \"not_eligible\"\n | \"answer_claimed\";\n\n/** Why the browser ends a session. Analytics only: the secret is what ends it. */\nexport type AvatarEndReason = \"user\" | \"page_hide\" | \"client_error\";\n\n/**\n * Whether the server checks for bots when a session is created: `turnstile` (a Cloudflare Turnstile token is required on\n * create) or `off` (none is; the server's own caps decide). A server older than contract v1.2 names no mode and always\n * checks, so it is read as `turnstile`.\n */\nexport type AvatarBotCheck = \"off\" | \"turnstile\";\n\n/**\n * Which first questions the server reads the answer to (contract v1.3, BOFF-9797): `suggested` (only the exact\n * suggested questions of the site's manifest) or `any` (a question the visitor typed too). A server older than v1.3\n * names none and reads suggested questions only, so it is read as `suggested`. The Avatar tab offers its own question\n * box only under `any`, and only with consent copy written for it.\n */\nexport type AvatarQuestions = \"any\" | \"suggested\";\n\n/** What an `ok` availability offers. */\nexport interface AvatarOffer {\n /** The consent version the visitor must agree to: the panel shows only copy written for exactly this version. */\n consentVersion: string;\n /** The longest a session can last, in seconds. */\n maxSessionSeconds: number;\n /** Whether a bot check runs before the create request. */\n botCheck: AvatarBotCheck;\n /** Which first questions the server reads the answer to. */\n questions: AvatarQuestions;\n}\n\nexport type AvatarAvailability =\n | { kind: \"available\"; offer: AvatarOffer }\n /**\n * `questions` is the server's (contract v1.3 reports it with every answer): under `any` a `limits` refusal leaves the\n * Avatar tab's box asking in text. Read leniently here, since a refusal offers nothing: anything but `any` is\n * `suggested`.\n */\n | { kind: \"refused\"; reason: AvatarRefusal; questions: AvatarQuestions }\n /** Not offered here, or not reachable: the Avatar tab stays as it was before the live avatar. */\n | { kind: \"inert\" };\n\n/** A created session: what the browser needs to watch it and to end it. */\nexport interface AvatarSession {\n sessionId: string;\n /** Returned once; ends this session and nothing else. Kept out of the page's markup. */\n endSecret: string;\n /** When the server ends the session, in epoch milliseconds. */\n endsAt: number;\n join: {\n livekitUrl: string;\n /** Subscribe-only and short-lived. Kept out of the page's markup. */\n participantToken: string;\n workerIdentity: string;\n };\n captions: { locale: string; text: string };\n}\n\nexport type AvatarCreateResult =\n | { kind: \"created\"; session: AvatarSession }\n /** A session was created, but its answer cannot be used: the browser ends it at once. */\n | { kind: \"unusable\"; sessionId: string; endSecret: string }\n | { kind: \"refused\"; reason: AvatarRefusal }\n /** The consent version moved on since availability: ask again, and show the consent that is current. */\n | { kind: \"consent\" }\n | { kind: \"inert\" }\n | { kind: \"failed\" };\n\n/** The create body: exactly these six fields, in the contract's order. */\nexport interface AvatarCreateBody {\n site: string;\n locale: string;\n conversationToken: string;\n messageId: string;\n consentVersion: string;\n manifestVersion: string;\n}\n\nconst MESSAGE_ID = /^[A-Za-z0-9_-]{1,64}$/;\nconst CONVERSATION_TOKEN = /^[A-Za-z0-9._~+/=-]{16,512}$/;\nconst LOCALE = /^[A-Za-z0-9-]{1,16}$/;\nconst SESSION_ID = /^avs_[0-9a-f]{32}$/;\nconst END_SECRET = /^[A-Za-z0-9_-]{43}$/;\n\nconst INERT = { kind: \"inert\" } as const;\nconst FAILED = { kind: \"failed\" } as const;\n\n/** An answer id the contract accepts. */\nexport function isAvatarMessageId(value: string): boolean {\n return MESSAGE_ID.test(value);\n}\n\n/** A conversation token the contract accepts. */\nexport function isAvatarConversationToken(value: string): boolean {\n return CONVERSATION_TOKEN.test(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/** What each availability `reason` other than `ok` means for the Avatar tab. A reason not listed is inert. */\nconst AVAILABILITY_REASONS: ReadonlyMap<string, AvatarRefusal | \"inert\"> =\n new Map<string, AvatarRefusal | \"inert\">([\n [\"site\", \"inert\"],\n [\"unavailable\", \"inert\"],\n [\"region\", \"region\"],\n [\"locale\", \"locale\"],\n [\"paused\", \"paused\"],\n [\"busy\", \"busy\"],\n [\"limits\", \"limits\"],\n ]);\n\nconst BOT_CHECK_MODES: ReadonlySet<string> = new Set<AvatarBotCheck>([\n \"off\",\n \"turnstile\",\n]);\n\n/**\n * An `ok` answer's `botCheck` (contract v1.2): exactly `{\"mode\":\"off\"}` or `{\"mode\":\"turnstile\"}`. Absent, from a\n * server older than v1.2: `turnstile`, as that server always checks. Anything else (an unknown mode, another field, a\n * value of another type) is null: the browser cannot tell what the server will require, so it offers nothing.\n */\nfunction readBotCheck(value: unknown): AvatarBotCheck | null {\n if (value === undefined) return \"turnstile\";\n if (!isRecord(value)) return null;\n const keys = Object.keys(value);\n const { mode } = value;\n if (\n keys.length !== 1 ||\n keys[0] !== \"mode\" ||\n typeof mode !== \"string\" ||\n !BOT_CHECK_MODES.has(mode)\n ) {\n return null;\n }\n return mode === \"off\" ? \"off\" : \"turnstile\";\n}\n\nconst QUESTION_MODES: ReadonlySet<string> = new Set<AvatarQuestions>([\n \"any\",\n \"suggested\",\n]);\n\n/**\n * An `ok` answer's `questions` (contract v1.3): exactly `\"any\"` or `\"suggested\"`. Absent, from a server older than v1.3:\n * `suggested`, which is all that server reads. Anything else is null: the browser cannot tell which questions the\n * server will read, so it offers nothing.\n */\nfunction readQuestions(value: unknown): AvatarQuestions | null {\n if (value === undefined) return \"suggested\";\n if (typeof value !== \"string\" || !QUESTION_MODES.has(value)) return null;\n return value === \"any\" ? \"any\" : \"suggested\";\n}\n\n/**\n * Read an availability answer: its HTTP status and its parsed JSON body (or null). Only an `ok` answer's `botCheck` is\n * read, and only an `ok` answer's `questions` strictly: a refusal offers nothing for them to change.\n */\nexport function readAvailability(\n status: number,\n body: unknown,\n): AvatarAvailability {\n if (status !== 200 || !isRecord(body)) return INERT;\n const { available, reason } = body;\n if (typeof available !== \"boolean\" || typeof reason !== \"string\") {\n return INERT;\n }\n if (reason === \"ok\") {\n const { consentVersion, maxSessionSeconds } = body;\n const botCheck = readBotCheck(body.botCheck);\n const questions = readQuestions(body.questions);\n if (\n available !== true ||\n typeof consentVersion !== \"string\" ||\n !isAvatarVersion(consentVersion) ||\n typeof maxSessionSeconds !== \"number\" ||\n !Number.isInteger(maxSessionSeconds) ||\n maxSessionSeconds < 1 ||\n botCheck === null ||\n questions === null\n ) {\n return INERT;\n }\n return {\n kind: \"available\",\n offer: { consentVersion, maxSessionSeconds, botCheck, questions },\n };\n }\n const meaning = available ? undefined : AVAILABILITY_REASONS.get(reason);\n return meaning === undefined || meaning === \"inert\"\n ? INERT\n : {\n kind: \"refused\",\n reason: meaning,\n questions: body.questions === \"any\" ? \"any\" : \"suggested\",\n };\n}\n\n/** The create error codes the Avatar tab explains. */\nconst CREATE_REFUSALS: ReadonlyMap<string, AvatarRefusal> = new Map<\n string,\n AvatarRefusal\n>([\n [\"busy\", \"busy\"],\n [\"limits\", \"limits\"],\n [\"region\", \"region\"],\n [\"locale\", \"locale\"],\n [\"paused\", \"paused\"],\n [\"not_eligible\", \"not_eligible\"],\n [\"answer_claimed\", \"answer_claimed\"],\n]);\n\nfunction errorCode(body: unknown): string | null {\n if (!isRecord(body) || !isRecord(body.error)) return null;\n const { code } = body.error;\n return typeof code === \"string\" ? code : null;\n}\n\nfunction readCreated(body: unknown): AvatarCreateResult {\n if (!isRecord(body)) return FAILED;\n const { sessionId, endSecret } = body;\n if (\n typeof sessionId !== \"string\" ||\n !SESSION_ID.test(sessionId) ||\n typeof endSecret !== \"string\" ||\n !END_SECRET.test(endSecret)\n ) {\n return FAILED;\n }\n const unusable = { kind: \"unusable\", sessionId, endSecret } as const;\n const { state, join, captions } = body;\n const endsAt =\n typeof body.endsAt === \"string\" ? Date.parse(body.endsAt) : NaN;\n if (\n state !== \"pending\" ||\n !Number.isFinite(endsAt) ||\n !isRecord(join) ||\n !isRecord(captions)\n ) {\n return unusable;\n }\n const { livekitUrl, participantToken, workerIdentity } = join;\n const { locale, text } = captions;\n if (\n typeof livekitUrl !== \"string\" ||\n !livekitUrl.startsWith(\"wss://\") ||\n typeof participantToken !== \"string\" ||\n participantToken === \"\" ||\n typeof workerIdentity !== \"string\" ||\n workerIdentity === \"\" ||\n typeof locale !== \"string\" ||\n typeof text !== \"string\"\n ) {\n return unusable;\n }\n return {\n kind: \"created\",\n session: {\n sessionId,\n endSecret,\n endsAt,\n join: { livekitUrl, participantToken, workerIdentity },\n captions: { locale, text },\n },\n };\n}\n\n/**\n * Read a create answer: its HTTP status and its parsed JSON body (or null).\n *\n * - 201: the session, or `unusable` when its fields cannot be used (the browser then ends it).\n * - `busy`, `limits`, `region`, `locale`, `paused`, `not_eligible`, `answer_claimed`: a refusal the tab explains.\n * - `consent`: the consent version moved on.\n * - Any other 401, 403, 404 or 405 (`untrusted_caller`, `bot_check`, `site`, `invalid_route`, `method_not_allowed`):\n * inert, as if there were no live avatar here.\n * - Anything else (`invalid_request`, `conflict`, `idempotency_mismatch`, `unavailable`, a gateway error page):\n * failed.\n */\nexport function readCreate(status: number, body: unknown): AvatarCreateResult {\n if (status === 201) return readCreated(body);\n const code = errorCode(body);\n if (code !== null) {\n const refusal = CREATE_REFUSALS.get(code);\n if (refusal !== undefined) return { kind: \"refused\", reason: refusal };\n if (code === \"consent\") return { kind: \"consent\" };\n }\n if (status === 401 || status === 403 || status === 404 || status === 405) {\n return INERT;\n }\n return FAILED;\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n try {\n return (await response.json()) as unknown;\n } catch {\n return null;\n }\n}\n\n/** An abort signal for `timeoutMs`, also aborted with `outer`; `done` clears its timer. */\nfunction deadline(\n timeoutMs: number,\n outer?: AbortSignal,\n): { signal: AbortSignal; done: () => void } {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const onOuter = () => controller.abort();\n if (outer?.aborted) controller.abort();\n else outer?.addEventListener(\"abort\", onOuter, { once: true });\n return {\n signal: controller.signal,\n done: () => {\n clearTimeout(timer);\n outer?.removeEventListener(\"abort\", onOuter);\n },\n };\n}\n\nexport interface AvatarRequestTarget {\n /** {@link avatarApiBase} of the SDK's gateway. */\n base: string;\n /** Headers every request carries: the alpha gateway's access headers, and nothing on production. */\n headers: Readonly<Record<string, string>>;\n}\n\n/** Ask whether the live avatar is offered for `site` in `locale`. Never throws: a failure is `inert`. */\nexport async function requestAvailability(\n target: AvatarRequestTarget & {\n site: string;\n locale: string;\n signal?: AbortSignal;\n },\n): Promise<AvatarAvailability> {\n if (!isAvatarSite(target.site) || !LOCALE.test(target.locale)) return INERT;\n const query = new URLSearchParams({\n site: target.site,\n locale: target.locale,\n });\n const timer = deadline(AVAILABILITY_TIMEOUT_MS, target.signal);\n try {\n const response = await fetch(`${target.base}/availability?${query}`, {\n method: \"GET\",\n credentials: \"omit\",\n cache: \"no-store\",\n headers: { ...target.headers },\n signal: timer.signal,\n });\n return readAvailability(response.status, await readJson(response));\n } catch {\n return INERT;\n } finally {\n timer.done();\n }\n}\n\n/**\n * Create a session. `botToken` is the bot check's token, for the gateway alone, and is sent only when there is one: a\n * server that runs no bot check gets no `x-web-avatar-bot-token` header. Never throws: a network failure is `inert`, an\n * answer that cannot be read is `failed`.\n */\nexport async function requestCreate(\n target: AvatarRequestTarget & {\n body: AvatarCreateBody;\n idempotencyKey: string;\n botToken?: string;\n },\n): Promise<AvatarCreateResult> {\n const { body } = target;\n // Exactly the contract's six fields, in its order: nothing else of the page's goes along.\n const payload = JSON.stringify({\n site: body.site,\n locale: body.locale,\n conversationToken: body.conversationToken,\n messageId: body.messageId,\n consentVersion: body.consentVersion,\n manifestVersion: body.manifestVersion,\n });\n const timer = deadline(CREATE_TIMEOUT_MS);\n try {\n const response = await fetch(`${target.base}/sessions`, {\n method: \"POST\",\n credentials: \"omit\",\n cache: \"no-store\",\n headers: {\n ...target.headers,\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": target.idempotencyKey,\n ...(target.botToken === undefined\n ? {}\n : { \"x-web-avatar-bot-token\": target.botToken }),\n },\n body: payload,\n signal: timer.signal,\n });\n return readCreate(response.status, await readJson(response));\n } catch {\n return INERT;\n } finally {\n timer.done();\n }\n}\n\n/**\n * Ask the server to end a session, without waiting for it: a `keepalive` request, sent in this same tick, so it still\n * goes when the page is being hidden or unloaded. The server ends the session on its own deadlines whether or not this\n * arrives.\n *\n * **A simple CORS request.** The body is a plain string and this sets no `Content-Type`, so the browser sends it as\n * `text/plain;charset=UTF-8`: a type the gateway's end route reads as JSON for exactly this reason. The session id is\n * in the URL, so a preflight could never be answered from the browser's cache, and one that has to complete while the\n * page unloads may never finish. On production nothing else is added, so no preflight is made. (On the alpha gateway\n * hosts the Access headers in `target.headers` are custom headers, which do bring a preflight there: see the README.)\n */\nexport function sendEnd(\n target: AvatarRequestTarget & {\n sessionId: string;\n secret: string;\n reason: AvatarEndReason;\n },\n): void {\n try {\n void fetch(\n `${target.base}/sessions/${encodeURIComponent(target.sessionId)}/end`,\n {\n method: \"POST\",\n keepalive: true,\n credentials: \"omit\",\n cache: \"no-store\",\n headers: { ...target.headers },\n body: JSON.stringify({ secret: target.secret, reason: target.reason }),\n },\n ).catch(() => undefined);\n } catch {\n // No fetch at all: the server's own deadlines end the session.\n }\n}\n\n/** What scopes the bot check's binding to this contract, and its version. */\nconst BOT_BINDING_PREFIX = \"boff-web-avatar-cdata/v1\";\n\n/** The browser's WebCrypto `subtle`, or null where it has none to offer (a page that is not a secure context). */\nfunction webCryptoSubtle(): SubtleCrypto | null {\n const subtle = globalThis.crypto?.subtle;\n return typeof subtle?.digest === \"function\" ? subtle : null;\n}\n\n/**\n * Whether this browser can make the bot check's binding ({@link avatarBotBinding}): it needs WebCrypto's SHA-256.\n * Without it no live avatar can start here, so a start asks first, before it loads anything for one.\n */\nexport function canBindBotCheck(): boolean {\n return webCryptoSubtle() !== null;\n}\n\nfunction base64UrlNoPad(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\n/**\n * The value the bot check is bound to, for Turnstile's `cData` (web API contract v1.1, additive):\n *\n * base64url_nopad( SHA-256( UTF-8( \"boff-web-avatar-cdata/v1\\n\" + site + \"\\n\" + locale + \"\\n\"\n * + conversationToken + \"\\n\" + messageId ) ) )\n *\n * The gateway recomputes it from the create body and checks it against the one Cloudflare returns with the verified\n * token, so a token minted for one request cannot be used for another. It must be made from the very values the create\n * body will carry, and before the widget is rendered: the caller builds the body once and hands the same one to this\n * and to {@link requestCreate}.\n *\n * Rejects where the browser has no WebCrypto (a page that is not a secure context): the bot check cannot be bound\n * there, so the live avatar does not start. {@link canBindBotCheck} says so beforehand, so that nothing is loaded for\n * a start that cannot happen.\n */\nexport async function avatarBotBinding(\n values: Pick<\n AvatarCreateBody,\n \"site\" | \"locale\" | \"conversationToken\" | \"messageId\"\n >,\n): Promise<string> {\n const subtle = webCryptoSubtle();\n if (subtle === null) {\n throw new Error(\"The bot check cannot be bound here: no WebCrypto.\");\n }\n const text = [\n BOT_BINDING_PREFIX,\n values.site,\n values.locale,\n values.conversationToken,\n values.messageId,\n ].join(\"\\n\");\n const digest = await subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return base64UrlNoPad(new Uint8Array(digest));\n}\n\n/** A random UUID v4 for `Idempotency-Key`, or null where the browser has no cryptographic random source. */\nexport function newIdempotencyKey(): string | null {\n const crypto = globalThis.crypto;\n if (typeof crypto?.randomUUID === \"function\") return crypto.randomUUID();\n if (typeof crypto?.getRandomValues !== \"function\") return null;\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\",\n );\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n","/**\n * BOFF-9797. The words of the live avatar's Avatar tab, in the six product locales, bundled like the rest of\n * Explore's copy (see `explore-i18n.ts` for why a marketing site bundles its strings).\n *\n * ## Review\n *\n * English is the reviewed copy. The other five locales are drafts awaiting translation review: each is a complete\n * object (a missing key is a type error), but the live avatar runs only in a locale that\n * {@link isAvatarLiveLocaleReviewed} lists. In any other, the Avatar tab stays as it was before the live avatar and\n * asks the server nothing. A locale is added there (in `explore-avatar-live-config.ts`) once its strings, and its\n * consent copy, have been reviewed.\n *\n * ## Consent\n *\n * The consent card's copy is versioned: the server names the version it will accept (`consentVersion`), and the panel\n * shows a consent card only when it holds copy written for exactly that version in the visitor's locale\n * ({@link avatarConsentCopy}). A version the SDK does not know, or a locale without reviewed copy for it, offers no\n * consent card at all, so a visitor never agrees to words other than the ones the server records. Each version also says\n * which bot check its words describe ({@link AvatarConsentCopy.botCheck}), and the card is shown only where the server\n * runs that one.\n */\n\nimport { isAvatarLiveLocaleReviewed } from \"./explore-avatar-live-config\";\n\nimport type { AvatarBotCheck, AvatarQuestions } from \"./explore-avatar-api\";\nimport type { ExploreLocale } from \"./explore-i18n\";\n\n// The reviewed locales are decided in `explore-avatar-live-config.ts`, which the panel reads without loading this file.\nexport { isAvatarLiveLocaleReviewed };\n\nexport interface AvatarLiveStrings {\n /** Status while the tab asks whether the live avatar is offered. Announced politely. */\n checking: string;\n /** No answer to read yet. */\n needsAnswer: string;\n needsAnswerDetail: string;\n /**\n * The conversation can never be read: its first answer failed, it has gone past the first question and answer, or\n * the answer is too old. Only a new chat can. The headline (announced politely), then the explanation, then a New\n * chat button. The avatar service reads exactly one answer: the first, completed, to a suggested question, within\n * fifteen minutes.\n */\n startNewChat: string;\n startNewChatDetail: string;\n /** The consent card's buttons. */\n start: string;\n notNow: string;\n /** After the privacy link, for screen readers: it opens in a new tab. */\n opensInNewTab: string;\n /** Status while the bot check runs. Announced politely. */\n botCheck: string;\n /** Status while the session is created and the room joined. Announced politely. */\n connecting: string;\n /** Status once the avatar's video plays. Announced politely. */\n speaking: string;\n /** Shown over the live video, always: the visitor is watching an AI, not a person. */\n badge: string;\n /** The video's accessible name. */\n video: string;\n /** The captions' accessible name. */\n captions: string;\n /** Before the countdown, which is never announced. */\n timeLeft: string;\n stop: string;\n /** Where the browser holds sound back until a tap (Safari, iOS). */\n tapForSound: string;\n /**\n * How a session ended. Announced politely. `finished` is \"the server closed the room, or the session's time ran out\n * with the room still open\": the browser cannot tell the avatar reading to the end from a server-side stop or a\n * hand-over, so it says only that the live avatar has ended.\n */\n finished: string;\n stopped: string;\n failed: string;\n interrupted: string;\n /** Under the captions and after a session: the answer itself is still in the conversation. */\n answerInChat: string;\n backToChat: string;\n /**\n * The refusals, one short sentence each, with no numbers in them (a number is spelled out). `notEligible` is the one\n * with a second sentence: it comes with a New chat button, and says what to do with it.\n */\n busy: string;\n limits: string;\n region: string;\n locale: string;\n paused: string;\n notEligible: string;\n answerClaimed: string;\n /**\n * The Avatar tab's own question box (BOFF-9797, contract v1.3): shown only where the server reads the answer to a\n * question the visitor typed too (`questions: \"any\"`), with consent copy written for that. The headline over the\n * suggested questions, the box's accessible name, its placeholder and the line under it, always visible with the box.\n */\n askHeadline: string;\n askLabel: string;\n askPlaceholder: string;\n askFooter: string;\n /** A file pasted or dropped on the box: the box takes text only. */\n askNoFiles: string;\n /** Why Send cannot be pressed: an answer is on its way, or the chat cannot take a question. */\n askBusy: string;\n askUnavailable: string;\n /** While the answer is written, when the chat reports no progress line of its own. Announced politely. */\n gettingAnswer: string;\n /**\n * The consent card's button while the answer is still being written: pressed, the avatar starts once the answer is\n * ready (`armed`), unless the visitor presses `cancel` or the start is called off (`armedCancelled`: the tab left,\n * the page hidden, the chat or the page changed, and the like).\n */\n startWhenReady: string;\n armed: string;\n cancel: string;\n armedCancelled: string;\n /** A first answer the avatar does not read (it fails the speech checks this browser can make): it stays in Chat. */\n notSpoken: string;\n /** The first answer failed. */\n answerFailed: string;\n /** Not now, under `any`: the card is offered again, while the answer is fresh, when the tab opens again. */\n declined: string;\n /** An answer to a question that was not the first of a new chat asked in this tab. */\n askHere: string;\n /**\n * Where the conversation can no longer be read: the button that starts a new chat for the avatar (the chat's own New\n * chat, staying on the Avatar tab), the note beside it, and the line once it has.\n */\n newChatForAvatar: string;\n newChatNote: string;\n newChatStarted: string;\n /** The button to the Chat tab, where the answer and its sources are. */\n readInChat: string;\n /** Over the box on the day this browser has had a live session. No number: the limits are the server's. */\n usedToday: string;\n /**\n * Under `any`, in place of `needsAnswer` (the box's description), `startNewChatDetail` and `notEligible`, which\n * speak of suggested questions only.\n */\n needsAnswerAny: string;\n startNewChatDetailAny: string;\n notEligibleAny: string;\n}\n\nconst EN: AvatarLiveStrings = {\n checking: \"Checking whether the live avatar is available…\",\n needsAnswer: \"Choose a suggested question in Chat first.\",\n needsAnswerDetail: \"The avatar can read only the first answer aloud.\",\n startNewChat: \"Start a new chat to use the avatar.\",\n startNewChatDetail:\n \"The avatar reads aloud only the first answer in a chat, to a suggested question, within fifteen minutes. Start a new chat and choose a suggested question.\",\n start: \"Start live avatar\",\n notNow: \"Not now\",\n opensInNewTab: \"(opens in a new tab)\",\n botCheck: \"Checking your browser…\",\n connecting: \"Connecting to the live avatar…\",\n speaking: \"The avatar is speaking.\",\n badge: \"AI avatar · not a real person\",\n video: \"Live AI avatar video\",\n captions: \"Captions\",\n timeLeft: \"Time left\",\n stop: \"Stop\",\n tapForSound: \"Tap to turn on sound\",\n finished: \"The live avatar has ended.\",\n stopped: \"You stopped the avatar.\",\n failed: \"The live avatar couldn't start.\",\n interrupted: \"The live avatar stopped early.\",\n answerInChat: \"The full answer is in Chat.\",\n backToChat: \"Back to Chat\",\n busy: \"The live avatar is busy right now. Please try again in a few minutes.\",\n limits:\n \"The live avatar has reached its limit for now. Please try again later.\",\n region: \"The live avatar isn't offered in your region yet.\",\n locale: \"The live avatar isn't offered in this language yet.\",\n paused: \"The live avatar is paused right now.\",\n notEligible:\n \"The avatar reads the first answer to a suggested question, within fifteen minutes. Start a new chat and choose a suggested question.\",\n answerClaimed: \"The avatar has already read this answer.\",\n askHeadline: \"Ask a question, and the avatar reads the answer aloud.\",\n askLabel: \"Question for the avatar\",\n askPlaceholder: \"Ask the avatar…\",\n askFooter:\n \"Answers are AI-generated and can be wrong. Don't include personal details.\",\n askNoFiles: \"To attach files, use Chat.\",\n askBusy: \"You can ask when the current answer is ready.\",\n askUnavailable: \"Chat isn't available right now.\",\n gettingAnswer: \"Getting the answer…\",\n startWhenReady: \"Start when ready\",\n armed: \"The avatar will start when the answer is ready.\",\n cancel: \"Cancel\",\n armedCancelled:\n \"The avatar didn't start. Press Start when ready to try again.\",\n notSpoken:\n \"This answer stays in Chat as text. The avatar reads only answers that pass its speech checks.\",\n answerFailed: \"The assistant couldn't answer. Try asking again.\",\n declined: \"No problem. The answer is in Chat.\",\n askHere: \"To hear an answer, ask it here.\",\n newChatForAvatar: \"New chat for the avatar\",\n newChatNote: \"Your current chat stays in History.\",\n newChatStarted: \"Started a new chat for the avatar.\",\n readInChat: \"Read the answer and sources in Chat\",\n usedToday:\n \"You've had today's avatar session. Answers will show here as text.\",\n needsAnswerAny: \"Ask a question here, and the avatar reads the answer aloud.\",\n startNewChatDetailAny:\n \"The avatar reads aloud only the first answer in a new chat started in the Avatar tab, provided it passes the speech checks.\",\n notEligibleAny:\n \"The avatar can't read this answer aloud. The answer and sources are in Chat.\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"zh\" is in REVIEWED.\nconst ZH: AvatarLiveStrings = {\n checking: \"正在检查实时虚拟形象是否可用…\",\n needsAnswer: \"请先在聊天中选择一个推荐问题。\",\n needsAnswerDetail: \"虚拟形象只能朗读第一个回答。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"请开始新的聊天,再使用虚拟形象。\",\n startNewChatDetail:\n \"虚拟形象只朗读一次聊天中的第一个回答,且仅限推荐问题的回答、在十五分钟内。请开始新的聊天,并选择一个推荐问题。\",\n start: \"启动实时虚拟形象\",\n notNow: \"暂不\",\n opensInNewTab: \"(在新标签页中打开)\",\n botCheck: \"正在检查您的浏览器…\",\n connecting: \"正在连接实时虚拟形象…\",\n speaking: \"虚拟形象正在讲话。\",\n badge: \"AI 虚拟形象 · 不是真人\",\n video: \"实时 AI 虚拟形象视频\",\n captions: \"字幕\",\n timeLeft: \"剩余时间\",\n stop: \"停止\",\n tapForSound: \"点按以开启声音\",\n finished: \"实时虚拟形象已结束。\",\n stopped: \"您已停止虚拟形象。\",\n failed: \"实时虚拟形象无法启动。\",\n interrupted: \"实时虚拟形象提前停止了。\",\n answerInChat: \"完整回答在聊天中。\",\n backToChat: \"返回聊天\",\n busy: \"实时虚拟形象目前繁忙,请几分钟后再试。\",\n limits: \"实时虚拟形象暂时已达到使用上限,请稍后再试。\",\n region: \"您所在的地区暂不提供实时虚拟形象。\",\n locale: \"此语言暂不提供实时虚拟形象。\",\n paused: \"实时虚拟形象目前已暂停。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"虚拟形象只朗读推荐问题的第一个回答,且须在十五分钟内。请开始新的聊天,并选择一个推荐问题。\",\n answerClaimed: \"虚拟形象已经朗读过这个回答。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"提出问题,虚拟形象会朗读回答。\",\n askLabel: \"向虚拟形象提的问题\",\n askPlaceholder: \"向虚拟形象提问…\",\n askFooter: \"回答由 AI 生成,可能有误。请勿包含个人信息。\",\n askNoFiles: \"如需附加文件,请使用聊天。\",\n askBusy: \"当前回答准备好后即可提问。\",\n askUnavailable: \"聊天目前不可用。\",\n gettingAnswer: \"正在获取回答…\",\n startWhenReady: \"准备好后开始\",\n armed: \"回答准备好后,虚拟形象将开始。\",\n cancel: \"取消\",\n armedCancelled: \"虚拟形象未启动。可再次按“准备好后开始”。\",\n notSpoken:\n \"此回答以文字形式保留在聊天中。虚拟形象只朗读通过其语音检查的回答。\",\n answerFailed: \"助手无法回答。请重新提问。\",\n declined: \"没关系。回答在聊天中。\",\n askHere: \"如需听取回答,请在这里提问。\",\n newChatForAvatar: \"为虚拟形象开始新聊天\",\n newChatNote: \"当前聊天会保留在历史记录中。\",\n newChatStarted: \"已为虚拟形象开始新的聊天。\",\n readInChat: \"在聊天中查看回答和来源\",\n usedToday: \"您今天已使用过虚拟形象。回答将以文字显示在这里。\",\n needsAnswerAny: \"在这里提问,虚拟形象会朗读回答。\",\n startNewChatDetailAny:\n \"虚拟形象只朗读在“虚拟形象”标签页中开始的新聊天的第一个回答,且该回答须通过语音检查。\",\n notEligibleAny: \"虚拟形象无法朗读此回答。回答和来源在聊天中。\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"hi\" is in REVIEWED.\nconst HI: AvatarLiveStrings = {\n checking: \"जाँच हो रही है कि लाइव अवतार उपलब्ध है या नहीं…\",\n needsAnswer: \"पहले चैट में कोई सुझाया गया प्रश्न चुनें।\",\n needsAnswerDetail: \"अवतार केवल पहला उत्तर ज़ोर से पढ़ सकता है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"अवतार का उपयोग करने के लिए नई चैट शुरू करें।\",\n startNewChatDetail:\n \"अवतार किसी चैट का केवल पहला उत्तर ज़ोर से पढ़ता है, वह भी सुझाए गए प्रश्न का और पंद्रह मिनट के भीतर। नई चैट शुरू करें और कोई सुझाया गया प्रश्न चुनें।\",\n start: \"लाइव अवतार शुरू करें\",\n notNow: \"अभी नहीं\",\n opensInNewTab: \"(नए टैब में खुलता है)\",\n botCheck: \"आपके ब्राउज़र की जाँच हो रही है…\",\n connecting: \"लाइव अवतार से जुड़ रहे हैं…\",\n speaking: \"अवतार बोल रहा है।\",\n badge: \"AI अवतार · असली व्यक्ति नहीं\",\n video: \"लाइव AI अवतार वीडियो\",\n captions: \"कैप्शन\",\n timeLeft: \"बचा हुआ समय\",\n stop: \"रोकें\",\n tapForSound: \"आवाज़ चालू करने के लिए टैप करें\",\n finished: \"लाइव अवतार समाप्त हो गया है।\",\n stopped: \"आपने अवतार को रोक दिया।\",\n failed: \"लाइव अवतार शुरू नहीं हो सका।\",\n interrupted: \"लाइव अवतार बीच में ही रुक गया।\",\n answerInChat: \"पूरा उत्तर चैट में है।\",\n backToChat: \"चैट पर वापस जाएँ\",\n busy: \"लाइव अवतार अभी व्यस्त है। कृपया कुछ मिनट बाद फिर कोशिश करें।\",\n limits:\n \"लाइव अवतार अभी अपनी सीमा तक पहुँच गया है। कृपया बाद में फिर कोशिश करें।\",\n region: \"आपके क्षेत्र में लाइव अवतार अभी उपलब्ध नहीं है।\",\n locale: \"इस भाषा में लाइव अवतार अभी उपलब्ध नहीं है।\",\n paused: \"लाइव अवतार अभी रुका हुआ है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"अवतार सुझाए गए प्रश्न का पहला उत्तर ही पढ़ता है, पंद्रह मिनट के भीतर। नई चैट शुरू करें और कोई सुझाया गया प्रश्न चुनें।\",\n answerClaimed: \"अवतार यह उत्तर पहले ही पढ़ चुका है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"कोई प्रश्न पूछें, और अवतार उसका उत्तर ज़ोर से पढ़ेगा।\",\n askLabel: \"अवतार के लिए प्रश्न\",\n askPlaceholder: \"अवतार से पूछें…\",\n askFooter:\n \"उत्तर AI द्वारा बनाए जाते हैं और गलत हो सकते हैं। निजी जानकारी शामिल न करें।\",\n askNoFiles: \"फ़ाइलें जोड़ने के लिए चैट का उपयोग करें।\",\n askBusy: \"मौजूदा उत्तर तैयार होने पर आप पूछ सकते हैं।\",\n askUnavailable: \"चैट अभी उपलब्ध नहीं है।\",\n gettingAnswer: \"उत्तर लाया जा रहा है…\",\n startWhenReady: \"तैयार होने पर शुरू करें\",\n armed: \"उत्तर तैयार होते ही अवतार शुरू होगा।\",\n cancel: \"रद्द करें\",\n armedCancelled:\n \"अवतार शुरू नहीं हुआ। फिर से कोशिश करने के लिए “तैयार होने पर शुरू करें” दबाएँ।\",\n notSpoken:\n \"यह उत्तर चैट में टेक्स्ट के रूप में रहेगा। अवतार केवल वही उत्तर पढ़ता है जो उसकी वाणी जाँच में पास होते हैं।\",\n answerFailed: \"सहायक उत्तर नहीं दे सका। फिर से पूछकर देखें।\",\n declined: \"कोई बात नहीं। उत्तर चैट में है।\",\n askHere: \"उत्तर सुनने के लिए, यहाँ पूछें।\",\n newChatForAvatar: \"अवतार के लिए नई चैट\",\n newChatNote: \"आपकी मौजूदा चैट इतिहास में रहेगी।\",\n newChatStarted: \"अवतार के लिए नई चैट शुरू की गई।\",\n readInChat: \"उत्तर और स्रोत चैट में पढ़ें\",\n usedToday:\n \"आज का अवतार सत्र आप ले चुके हैं। उत्तर यहाँ टेक्स्ट के रूप में दिखेंगे।\",\n needsAnswerAny: \"यहाँ प्रश्न पूछें, और अवतार उत्तर ज़ोर से पढ़ेगा।\",\n startNewChatDetailAny:\n \"अवतार केवल अवतार टैब में शुरू की गई नई चैट का पहला उत्तर ज़ोर से पढ़ता है, बशर्ते वह वाणी जाँच में पास हो।\",\n notEligibleAny:\n \"अवतार यह उत्तर ज़ोर से नहीं पढ़ सकता। उत्तर और स्रोत चैट में हैं।\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"es\" is in REVIEWED.\nconst ES: AvatarLiveStrings = {\n checking: \"Comprobando si el avatar en vivo está disponible…\",\n needsAnswer: \"Primero elige una pregunta sugerida en el chat.\",\n needsAnswerDetail:\n \"El avatar solo puede leer en voz alta la primera respuesta.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"Inicia un chat nuevo para usar el avatar.\",\n startNewChatDetail:\n \"El avatar solo lee en voz alta la primera respuesta de un chat, si es la de una pregunta sugerida y en un plazo de quince minutos. Inicia un chat nuevo y elige una pregunta sugerida.\",\n start: \"Iniciar el avatar en vivo\",\n notNow: \"Ahora no\",\n opensInNewTab: \"(se abre en una pestaña nueva)\",\n botCheck: \"Comprobando tu navegador…\",\n connecting: \"Conectando con el avatar en vivo…\",\n speaking: \"El avatar está hablando.\",\n badge: \"Avatar de IA · no es una persona real\",\n video: \"Vídeo del avatar de IA en vivo\",\n captions: \"Subtítulos\",\n timeLeft: \"Tiempo restante\",\n stop: \"Detener\",\n tapForSound: \"Toca para activar el sonido\",\n finished: \"El avatar en vivo ha terminado.\",\n stopped: \"Has detenido el avatar.\",\n failed: \"No se pudo iniciar el avatar en vivo.\",\n interrupted: \"El avatar en vivo se detuvo antes de tiempo.\",\n answerInChat: \"La respuesta completa está en el chat.\",\n backToChat: \"Volver al chat\",\n busy: \"El avatar en vivo está ocupado en este momento. Vuelve a intentarlo en unos minutos.\",\n limits:\n \"El avatar en vivo ha alcanzado su límite por ahora. Vuelve a intentarlo más tarde.\",\n region: \"El avatar en vivo aún no está disponible en tu región.\",\n locale: \"El avatar en vivo aún no está disponible en este idioma.\",\n paused: \"El avatar en vivo está en pausa en este momento.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"El avatar lee la primera respuesta a una pregunta sugerida, en un plazo de quince minutos. Inicia un chat nuevo y elige una pregunta sugerida.\",\n answerClaimed: \"El avatar ya ha leído esta respuesta.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"Haz una pregunta y el avatar leerá la respuesta en voz alta.\",\n askLabel: \"Pregunta para el avatar\",\n askPlaceholder: \"Pregunta al avatar…\",\n askFooter:\n \"Las respuestas las genera la IA y pueden contener errores. No incluyas datos personales.\",\n askNoFiles: \"Para adjuntar archivos, usa el chat.\",\n askBusy: \"Podrás preguntar cuando la respuesta actual esté lista.\",\n askUnavailable: \"El chat no está disponible en este momento.\",\n gettingAnswer: \"Obteniendo la respuesta…\",\n startWhenReady: \"Iniciar cuando esté lista\",\n armed: \"El avatar empezará cuando la respuesta esté lista.\",\n cancel: \"Cancelar\",\n armedCancelled:\n \"El avatar no se ha iniciado. Pulsa Iniciar cuando esté lista para volver a intentarlo.\",\n notSpoken:\n \"Esta respuesta se queda en el chat como texto. El avatar solo lee respuestas que superan sus comprobaciones de voz.\",\n answerFailed: \"El asistente no pudo responder. Vuelve a preguntar.\",\n declined: \"De acuerdo. La respuesta está en el chat.\",\n askHere: \"Para escuchar una respuesta, pregunta aquí.\",\n newChatForAvatar: \"Chat nuevo para el avatar\",\n newChatNote: \"Tu chat actual se queda en el historial.\",\n newChatStarted: \"Se ha iniciado un chat nuevo para el avatar.\",\n readInChat: \"Leer la respuesta y las fuentes en el chat\",\n usedToday:\n \"Ya has usado la sesión de avatar de hoy. Las respuestas se mostrarán aquí como texto.\",\n needsAnswerAny:\n \"Haz una pregunta aquí y el avatar leerá la respuesta en voz alta.\",\n startNewChatDetailAny:\n \"El avatar solo lee en voz alta la primera respuesta de un chat nuevo iniciado en la pestaña Avatar, si supera las comprobaciones de voz.\",\n notEligibleAny:\n \"El avatar no puede leer esta respuesta en voz alta. La respuesta y las fuentes están en el chat.\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed, including its right-to-left layout. Not shown\n// until \"ar\" is in REVIEWED.\nconst AR: AvatarLiveStrings = {\n checking: \"جارٍ التحقق من توفر الأفاتار المباشر…\",\n needsAnswer: \"اختر أولًا سؤالًا مقترحًا في الدردشة.\",\n needsAnswerDetail: \"يمكن للأفاتار قراءة الإجابة الأولى فقط بصوت عالٍ.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"ابدأ دردشة جديدة لاستخدام الأفاتار.\",\n startNewChatDetail:\n \"يقرأ الأفاتار بصوت عالٍ الإجابة الأولى في الدردشة فقط، إذا كانت إجابة عن سؤال مقترح وخلال خمس عشرة دقيقة. ابدأ دردشة جديدة واختر سؤالًا مقترحًا.\",\n start: \"بدء الأفاتار المباشر\",\n notNow: \"ليس الآن\",\n opensInNewTab: \"(يُفتح في علامة تبويب جديدة)\",\n botCheck: \"جارٍ التحقق من متصفحك…\",\n connecting: \"جارٍ الاتصال بالأفاتار المباشر…\",\n speaking: \"الأفاتار يتحدث الآن.\",\n badge: \"أفاتار بالذكاء الاصطناعي · ليس شخصًا حقيقيًا\",\n video: \"فيديو الأفاتار المباشر بالذكاء الاصطناعي\",\n captions: \"التسميات التوضيحية\",\n timeLeft: \"الوقت المتبقي\",\n stop: \"إيقاف\",\n tapForSound: \"انقر لتشغيل الصوت\",\n finished: \"انتهى الأفاتار المباشر.\",\n stopped: \"لقد أوقفت الأفاتار.\",\n failed: \"تعذّر بدء الأفاتار المباشر.\",\n interrupted: \"توقف الأفاتار المباشر قبل أن ينتهي.\",\n answerInChat: \"الإجابة الكاملة موجودة في الدردشة.\",\n backToChat: \"العودة إلى الدردشة\",\n busy: \"الأفاتار المباشر مشغول الآن. يُرجى المحاولة مرة أخرى بعد بضع دقائق.\",\n limits: \"بلغ الأفاتار المباشر حدّه في الوقت الحالي. يُرجى المحاولة لاحقًا.\",\n region: \"الأفاتار المباشر غير متاح في منطقتك بعد.\",\n locale: \"الأفاتار المباشر غير متاح بهذه اللغة بعد.\",\n paused: \"الأفاتار المباشر متوقف مؤقتًا الآن.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"يقرأ الأفاتار الإجابة الأولى عن سؤال مقترح، خلال خمس عشرة دقيقة. ابدأ دردشة جديدة واختر سؤالًا مقترحًا.\",\n answerClaimed: \"قرأ الأفاتار هذه الإجابة من قبل.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"اطرح سؤالًا، وسيقرأ الأفاتار الإجابة بصوت عالٍ.\",\n askLabel: \"سؤال للأفاتار\",\n askPlaceholder: \"اسأل الأفاتار…\",\n askFooter:\n \"الإجابات مُولَّدة بالذكاء الاصطناعي وقد تكون خاطئة. لا تضمّن بيانات شخصية.\",\n askNoFiles: \"لإرفاق ملفات، استخدم الدردشة.\",\n askBusy: \"يمكنك السؤال عندما تصبح الإجابة الحالية جاهزة.\",\n askUnavailable: \"الدردشة غير متاحة الآن.\",\n gettingAnswer: \"جارٍ الحصول على الإجابة…\",\n startWhenReady: \"البدء عند الجاهزية\",\n armed: \"سيبدأ الأفاتار عندما تصبح الإجابة جاهزة.\",\n cancel: \"إلغاء\",\n armedCancelled:\n \"لم يبدأ الأفاتار. اضغط على البدء عند الجاهزية للمحاولة مرة أخرى.\",\n notSpoken:\n \"تبقى هذه الإجابة في الدردشة نصًا. يقرأ الأفاتار فقط الإجابات التي تجتاز فحوص النطق.\",\n answerFailed: \"تعذّر على المساعد الإجابة. حاول السؤال مرة أخرى.\",\n declined: \"لا بأس. الإجابة موجودة في الدردشة.\",\n askHere: \"لسماع إجابة، اسأل هنا.\",\n newChatForAvatar: \"دردشة جديدة للأفاتار\",\n newChatNote: \"تبقى دردشتك الحالية في السجل.\",\n newChatStarted: \"بدأت دردشة جديدة للأفاتار.\",\n readInChat: \"اقرأ الإجابة والمصادر في الدردشة\",\n usedToday: \"لقد استخدمت جلسة الأفاتار لهذا اليوم. ستظهر الإجابات هنا نصًا.\",\n needsAnswerAny: \"اطرح سؤالًا هنا، وسيقرأ الأفاتار الإجابة بصوت عالٍ.\",\n startNewChatDetailAny:\n \"يقرأ الأفاتار بصوت عالٍ الإجابة الأولى فقط في دردشة جديدة بدأت في علامة تبويب الأفاتار، بشرط أن تجتاز فحوص النطق.\",\n notEligibleAny:\n \"لا يمكن للأفاتار قراءة هذه الإجابة بصوت عالٍ. الإجابة والمصادر موجودة في الدردشة.\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"ta\" is in REVIEWED.\nconst TA: AvatarLiveStrings = {\n checking: \"நேரலை அவதார் கிடைக்கிறதா எனச் சரிபார்க்கிறது…\",\n needsAnswer:\n \"முதலில் அரட்டையில் பரிந்துரைக்கப்பட்ட ஒரு கேள்வியைத் தேர்ந்தெடுக்கவும்.\",\n needsAnswerDetail: \"அவதார் முதல் பதிலை மட்டுமே உரக்கப் படிக்க முடியும்.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"அவதாரைப் பயன்படுத்த புதிய அரட்டையைத் தொடங்கவும்.\",\n startNewChatDetail:\n \"ஓர் அரட்டையின் முதல் பதிலை மட்டுமே, அதுவும் பரிந்துரைக்கப்பட்ட கேள்விக்கான பதிலை, பதினைந்து நிமிடங்களுக்குள் மட்டுமே அவதார் உரக்கப் படிக்கும். புதிய அரட்டையைத் தொடங்கி, பரிந்துரைக்கப்பட்ட ஒரு கேள்வியைத் தேர்ந்தெடுக்கவும்.\",\n start: \"நேரலை அவதாரைத் தொடங்கு\",\n notNow: \"இப்போது வேண்டாம்\",\n opensInNewTab: \"(புதிய தாவலில் திறக்கும்)\",\n botCheck: \"உங்கள் உலாவியைச் சரிபார்க்கிறது…\",\n connecting: \"நேரலை அவதாருடன் இணைக்கிறது…\",\n speaking: \"அவதார் பேசுகிறது.\",\n badge: \"AI அவதார் · உண்மையான நபர் அல்ல\",\n video: \"நேரலை AI அவதார் வீடியோ\",\n captions: \"வசனங்கள்\",\n timeLeft: \"மீதமுள்ள நேரம்\",\n stop: \"நிறுத்து\",\n tapForSound: \"ஒலியை இயக்கத் தட்டவும்\",\n finished: \"நேரலை அவதார் முடிவடைந்தது.\",\n stopped: \"நீங்கள் அவதாரை நிறுத்தினீர்கள்.\",\n failed: \"நேரலை அவதாரைத் தொடங்க முடியவில்லை.\",\n interrupted: \"நேரலை அவதார் இடையிலேயே நின்றுவிட்டது.\",\n answerInChat: \"முழுப் பதில் அரட்டையில் உள்ளது.\",\n backToChat: \"அரட்டைக்குத் திரும்பு\",\n busy: \"நேரலை அவதார் இப்போது வேறு பயன்பாட்டில் உள்ளது. சில நிமிடங்களில் மீண்டும் முயலவும்.\",\n limits:\n \"நேரலை அவதார் தற்போதைக்குத் தன் வரம்பை எட்டிவிட்டது. பிறகு மீண்டும் முயலவும்.\",\n region: \"உங்கள் பகுதியில் நேரலை அவதார் இன்னும் கிடைக்கவில்லை.\",\n locale: \"இந்த மொழியில் நேரலை அவதார் இன்னும் கிடைக்கவில்லை.\",\n paused: \"நேரலை அவதார் இப்போது இடைநிறுத்தப்பட்டுள்ளது.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"பரிந்துரைக்கப்பட்ட கேள்விக்கான முதல் பதிலை மட்டுமே, பதினைந்து நிமிடங்களுக்குள், அவதார் படிக்கும். புதிய அரட்டையைத் தொடங்கி, பரிந்துரைக்கப்பட்ட ஒரு கேள்வியைத் தேர்ந்தெடுக்கவும்.\",\n answerClaimed: \"இந்தப் பதிலை அவதார் ஏற்கெனவே படித்துவிட்டது.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"ஒரு கேள்வியைக் கேளுங்கள், அவதார் பதிலை உரக்கப் படிக்கும்.\",\n askLabel: \"அவதாருக்கான கேள்வி\",\n askPlaceholder: \"அவதாரிடம் கேளுங்கள்…\",\n askFooter:\n \"பதில்கள் AI உருவாக்கியவை, தவறாக இருக்கலாம். தனிப்பட்ட விவரங்களைச் சேர்க்க வேண்டாம்.\",\n askNoFiles: \"கோப்புகளை இணைக்க, அரட்டையைப் பயன்படுத்தவும்.\",\n askBusy: \"தற்போதைய பதில் தயாரானதும் நீங்கள் கேட்கலாம்.\",\n askUnavailable: \"அரட்டை இப்போது கிடைக்கவில்லை.\",\n gettingAnswer: \"பதிலைப் பெறுகிறது…\",\n startWhenReady: \"தயாரானதும் தொடங்கு\",\n armed: \"பதில் தயாரானதும் அவதார் தொடங்கும்.\",\n cancel: \"ரத்துசெய்\",\n armedCancelled:\n \"அவதார் தொடங்கவில்லை. மீண்டும் முயல, தயாரானதும் தொடங்கு என்பதை அழுத்தவும்.\",\n notSpoken:\n \"இந்தப் பதில் அரட்டையில் உரையாகவே இருக்கும். பேச்சுச் சரிபார்ப்புகளில் தேறும் பதில்களை மட்டுமே அவதார் படிக்கும்.\",\n answerFailed:\n \"உதவியாளரால் பதிலளிக்க முடியவில்லை. மீண்டும் கேட்டுப் பாருங்கள்.\",\n declined: \"பரவாயில்லை. பதில் அரட்டையில் உள்ளது.\",\n askHere: \"பதிலைக் கேட்க, இங்கே கேளுங்கள்.\",\n newChatForAvatar: \"அவதாருக்கான புதிய அரட்டை\",\n newChatNote: \"உங்கள் தற்போதைய அரட்டை வரலாற்றில் இருக்கும்.\",\n newChatStarted: \"அவதாருக்காகப் புதிய அரட்டை தொடங்கப்பட்டது.\",\n readInChat: \"பதிலையும் ஆதாரங்களையும் அரட்டையில் படிக்கவும்\",\n usedToday:\n \"இன்றைய அவதார் அமர்வை நீங்கள் பயன்படுத்திவிட்டீர்கள். பதில்கள் இங்கே உரையாகக் காட்டப்படும்.\",\n needsAnswerAny:\n \"இங்கே ஒரு கேள்வியைக் கேளுங்கள், அவதார் பதிலை உரக்கப் படிக்கும்.\",\n startNewChatDetailAny:\n \"அவதார் தாவலில் தொடங்கிய புதிய அரட்டையின் முதல் பதிலை மட்டுமே, அது பேச்சுச் சரிபார்ப்புகளில் தேறினால், அவதார் உரக்கப் படிக்கும்.\",\n notEligibleAny:\n \"இந்தப் பதிலை அவதாரால் உரக்கப் படிக்க முடியாது. பதிலும் ஆதாரங்களும் அரட்டையில் உள்ளன.\",\n};\n\nconst STRINGS: Record<ExploreLocale, AvatarLiveStrings> = {\n en: EN,\n zh: ZH,\n hi: HI,\n es: ES,\n ar: AR,\n ta: TA,\n};\n\nexport function avatarLiveStrings(locale: ExploreLocale): AvatarLiveStrings {\n return STRINGS[locale] ?? EN;\n}\n\n/** One version of the consent card's copy, in one locale. */\nexport interface AvatarConsentCopy {\n title: string;\n /**\n * What the avatar is and does, for a site with a product name. Takes `{product}`. Null in a product-neutral version:\n * every site, named or not, shows {@link AvatarConsentCopy.intro}, so the card's words are the same on every site.\n */\n introProduct: string | null;\n /** The same without a product name, and the only intro of a product-neutral version. */\n intro: string;\n /** Who processes what when the visitor starts. */\n processing: string;\n /** What is and is not used, recorded and kept, and who it is for. */\n storage: string;\n /** The link to the site's privacy notice, `/privacy#live-avatar`. */\n privacyLink: string;\n /**\n * The bot check `processing` tells the visitor about: `turnstile` where it says Cloudflare checks for bots, `off`\n * where it says nothing of one. The card is shown only where the server's `botCheck` is the same, so the notice a\n * visitor agrees to never describes a check that does not run, or leaves out one that does.\n */\n botCheck: AvatarBotCheck;\n /**\n * Which first questions the words describe: `suggested` where they speak of a suggested question only, `any` where\n * they say a question the visitor typed is read too. The card is shown only where the server's `questions` is the\n * same (contract v1.3), and the Avatar tab's own question box only under `any`.\n */\n questions: AvatarQuestions;\n}\n\n/**\n * The consent copy the server's `consentVersion` names, by version and then by locale. A version is added here, never\n * edited: changed wording is a new version, which the server starts asking for at the same time.\n */\nconst CONSENT: ReadonlyMap<\n string,\n Readonly<Partial<Record<ExploreLocale, AvatarConsentCopy>>>\n> = new Map([\n [\n \"web-consent-2026-11\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested {product} question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Your browser connects to LiveKit, which sees your IP address. LiveKit fetches our temporary audio file and passes the voice to Protoface, which makes the avatar video streamed through LiveKit.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session. We temporarily store the generated voice file and keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The voice is no longer a stored file: the server holds it in memory and plays it into the LiveKit room for Protoface.\n \"web-consent-2026-10-31\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested {product} question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The words of web-consent-2026-10-31 with no product name in them: one notice, byte for byte, on every product's\n // site, because the server binds one consent version and one notice digest for all of them.\n \"web-consent-2026-11-02\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The words of web-consent-2026-11-02 without \"When you start, Cloudflare checks for bots.\", for a server that runs\n // no bot check (its availability's botCheck is `off`). Product-neutral too: one notice and one digest for every site.\n \"web-consent-2026-11-03\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"off\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The Avatar tab's own question box (contract v1.3, `questions: \"any\"`): the first answer in a new chat started in\n // the Avatar tab is read whether the visitor chose a suggested question or typed their own, so the intro says so and\n // warns against personal details in a typed one. Product-neutral, with the bot check: one notice and one digest for\n // every site (gitops docs/avatar-web/en-web-consent-2026-11-05.txt).\n \"web-consent-2026-11-05\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads aloud, for up to a minute, the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"any\",\n },\n },\n ],\n [\n // The words of web-consent-2026-11-05 without \"When you start, Cloudflare checks for bots.\", for a server that runs\n // no bot check (gitops docs/avatar-web/en-web-consent-2026-11-06.txt).\n \"web-consent-2026-11-06\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads aloud, for up to a minute, the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.\",\n processing:\n \"The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"off\",\n questions: \"any\",\n },\n },\n ],\n]);\n\n/** The consent copy for exactly `version` in `locale`, or null when the SDK has none to show for it. */\nexport function avatarConsentCopy(\n version: string,\n locale: ExploreLocale,\n): AvatarConsentCopy | null {\n if (!isAvatarLiveLocaleReviewed(locale)) return null;\n return CONSENT.get(version)?.[locale] ?? null;\n}\n","/**\n * BOFF-9797. Cloudflare Turnstile, for the live avatar's start only.\n *\n * Nothing here runs until the visitor presses Start on the live avatar's consent card: the script is added to the page\n * then, once, and a widget is rendered for that one start (action `avatar_start`). The widget stays invisible unless\n * Cloudflare needs the visitor to interact with it. The token it returns goes to the gateway in a header and is used\n * once.\n *\n * The widget is rendered with `cData`, the binding of this check to the create request it is for (web API contract\n * v1.1: see `avatarBotBinding` in `explore-avatar-api.ts`), so it cannot be rendered before the binding is known.\n */\n\nconst SCRIPT_SRC =\n \"https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit\";\n/** How long the script may take to load before the start is given up. */\nconst SCRIPT_TIMEOUT_MS = 15_000;\n\n/** The part of Turnstile's render options used here. */\ninterface TurnstileRenderOptions {\n sitekey: string;\n action: string;\n /** Customer data Turnstile returns with the verified token: the binding to the create request. */\n cData: string;\n appearance: \"interaction-only\";\n size: \"flexible\";\n \"response-field\": false;\n callback: (token: string) => void;\n \"error-callback\": () => boolean;\n \"expired-callback\": () => void;\n \"timeout-callback\": () => void;\n}\n\n/** The part of `window.turnstile` used here. */\ninterface TurnstileApi {\n render: (\n container: HTMLElement,\n options: TurnstileRenderOptions,\n ) => string | null | undefined;\n remove: (widgetId: string) => void;\n}\n\nfunction readApi(): TurnstileApi | null {\n if (typeof window === \"undefined\") return null;\n const api = (window as unknown as { turnstile?: Partial<TurnstileApi> })\n .turnstile;\n return api &&\n typeof api.render === \"function\" &&\n typeof api.remove === \"function\"\n ? (api as TurnstileApi)\n : null;\n}\n\nlet loading: Promise<TurnstileApi> | null = null;\n\n/** Turnstile's API, adding its script to the page the first time. A failed load can be tried again later. */\nexport function loadTurnstile(): Promise<TurnstileApi> {\n const ready = readApi();\n if (ready) return Promise.resolve(ready);\n if (loading) return loading;\n loading = new Promise<TurnstileApi>((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = SCRIPT_SRC;\n script.async = true;\n script.setAttribute(\"data-boff-explore\", \"avatar-live-turnstile\");\n const fail = () => {\n clearTimeout(timer);\n loading = null;\n script.remove();\n reject(new Error(\"The bot check could not be loaded.\"));\n };\n const timer = setTimeout(fail, SCRIPT_TIMEOUT_MS);\n script.addEventListener(\"load\", () => {\n const api = readApi();\n if (!api) {\n fail();\n return;\n }\n clearTimeout(timer);\n resolve(api);\n });\n script.addEventListener(\"error\", fail);\n document.head.appendChild(script);\n });\n return loading;\n}\n\nexport interface TurnstileRun {\n /** The token, once Cloudflare has one; rejects when the check fails, expires, times out or is cancelled. */\n token: Promise<string>;\n /** Remove the widget, and reject `token` if it is still waiting. Safe to call more than once. */\n cancel: () => void;\n}\n\n/**\n * Run one bot check in `container` with `siteKey`, for `action`, bound to `cData` (or to what it resolves to: the widget\n * is rendered once its script has loaded AND the binding is known, and a binding that cannot be made fails the check).\n */\nexport function runTurnstile(\n container: HTMLElement | null,\n siteKey: string,\n action: string,\n cData: string | Promise<string>,\n): TurnstileRun {\n // A binding that cannot be made fails `token`; it is never an unhandled rejection of its own.\n Promise.resolve(cData).catch(() => undefined);\n let settled = false;\n let cancelled = false;\n let widget: { api: TurnstileApi; id: string } | null = null;\n let rejectToken: (error: Error) => void = () => undefined;\n\n const removeWidget = () => {\n if (!widget) return;\n const { api, id } = widget;\n widget = null;\n try {\n api.remove(id);\n } catch {\n // Already gone with its container.\n }\n };\n\n const token = new Promise<string>((resolve, reject) => {\n rejectToken = (error: Error) => {\n if (settled) return;\n settled = true;\n reject(error);\n };\n if (!container) {\n rejectToken(new Error(\"No place for the bot check.\"));\n return;\n }\n Promise.all([loadTurnstile(), cData]).then(\n ([api, binding]) => {\n if (cancelled || settled) return;\n const failed = () => {\n removeWidget();\n rejectToken(new Error(\"The bot check did not pass.\"));\n };\n const id = api.render(container, {\n sitekey: siteKey,\n action,\n cData: binding,\n appearance: \"interaction-only\",\n size: \"flexible\",\n \"response-field\": false,\n callback: (value: string) => {\n if (settled) return;\n settled = true;\n resolve(value);\n },\n \"error-callback\": () => {\n failed();\n // Handled here: Turnstile need not report it again.\n return true;\n },\n \"expired-callback\": failed,\n \"timeout-callback\": failed,\n });\n if (typeof id === \"string\" && id !== \"\") {\n widget = { api, id };\n if (settled) removeWidget();\n } else if (!settled) {\n rejectToken(new Error(\"The bot check could not start.\"));\n }\n },\n (error: unknown) => {\n rejectToken(\n error instanceof Error\n ? error\n : new Error(\"The bot check could not be loaded.\"),\n );\n },\n );\n });\n\n // A cancelled check nobody waits on any more is not an error worth reporting.\n token.catch(() => undefined);\n\n return {\n token,\n cancel: () => {\n cancelled = true;\n removeWidget();\n rejectToken(new Error(\"The bot check was cancelled.\"));\n },\n };\n}\n","/**\n * AvatarLiveView — the Avatar tab's live avatar (BOFF-9797), opt-in: its view and its state machine.\n *\n * `ExploreAvatarLive` (`explore-avatar-live.tsx`) renders this, and only once the Avatar view has been opened on a panel\n * whose host passes `avatar.live`. This file, and the requests, the words and the bot check it brings with it, is a\n * chunk of its own that a site downloads at that moment and not before; a site that never passes `avatar.live` never\n * does. It reads nothing from the page's React contexts (the package builds each entry on its own, so a context read\n * here would be a second, empty one): everything it needs comes in as props from `ExploreAvatarLive`.\n *\n * The visitor watches and listens; their browser never sends the avatar anything to say. What happens, in order:\n *\n * 1. **The tab opens** (never on page load): one availability request to the gateway's web branch. Nothing else is\n * loaded or asked for until the visitor agrees.\n * 2. **Offered, with the conversation's first answer:** a consent card (its copy is versioned; the panel shows only\n * copy written for the version the server names), Start, Not now and a link to the privacy notice. The avatar reads\n * one answer only: a conversation that is exactly a suggested question and its completed answer, while that answer\n * is fresh (see {@link ANSWER_OFFER_MS}). A failed first answer, a second question or an answer that is too old asks\n * the visitor to start a new chat instead, with a New chat button.\n * 3. **Start:** the live module (`live.load`) and, where the server checks for bots (availability's `botCheck`, contract\n * v1.2), the bot check load, then one create request: the contract's six fields, an `Idempotency-Key` and the bot\n * check's token, without credentials. The bot check is bound to that very request (`cData`, contract v1.1), so the\n * body is made once, before the widget is rendered. Where the server runs no bot check, no Cloudflare script or\n * widget is loaded and the request carries no token.\n * 4. **Created:** the room is joined to watch only. The avatar's video, its captions, a badge saying it is an AI and\n * not a person, a countdown (never announced), Stop and Continue in Chat.\n * 5. **Ending:** Stop, closing the panel, leaving the page (`pagehide`) or the live avatar going off asks the server to\n * end the session with a `keepalive` request. The server ends it on its own deadlines either way. Once the create has\n * been sent, switching to the Chat tab or to another browser tab does not end it: the pane is only hidden, so the\n * room's video and audio stay attached and the avatar speaks to its planned end (see `leave`). Before the create,\n * both still call off what is under way, with nothing created. Where the host sets `live.endUnattended`, a session\n * out of sight also ends once its answer has played out, and soon when the browser holds its sound back (see\n * `attend`): an idle tail after an answer runs only while the Avatar view is in sight.\n *\n * **Asking in the Avatar tab** (contract v1.3): where the server reads the answer to a question the visitor typed too\n * (availability's `questions` is `any`) and this SDK holds consent copy written for that, the tab has a question box of\n * its own, with the suggested questions as chips. A question asked there (`surface: \"AVATAR\"`) is the first of a new\n * chat, and its first answer is the only one offered: the consent card shows while the answer is written, with \"Start\n * when ready\", which waits for the answer, asks availability again and checks the answer as the service will, and only\n * then creates the session. Any other conversation is never read: the tab offers \"New chat for the avatar\", and never\n * resets a conversation by itself. After the day's session (a `limits` refusal, or this browser's own note of one) the\n * box asks ordinary questions, and the answer shows as text. Under `suggested`, or with a server older than v1.3, the\n * tab is as it was.\n *\n * Any refusal is one short sentence and \"Continue in Chat\". A route that is not there, a refused origin or a network\n * failure shows the tab as it was before the live avatar. The conversation token goes into the create request and\n * nowhere else; the session's secret and room token are kept in refs, never in the page.\n */\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ClipboardEvent as ReactClipboardEvent,\n type DragEvent as ReactDragEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from \"react\";\n\nimport {\n avatarBotBinding,\n canBindBotCheck,\n isAvatarConversationToken,\n isAvatarMessageId,\n newIdempotencyKey,\n requestAvailability,\n requestCreate,\n sendEnd,\n type AvatarAvailability,\n type AvatarBotCheck,\n type AvatarCreateBody,\n type AvatarCreateResult,\n type AvatarEndReason,\n type AvatarOffer,\n type AvatarQuestions,\n type AvatarRefusal,\n type AvatarSession,\n} from \"./explore-avatar-api\";\nimport {\n avatarConsentCopy,\n avatarLiveStrings,\n type AvatarConsentCopy,\n type AvatarLiveStrings,\n} from \"./explore-avatar-i18n\";\nimport { turnstileSiteKeyOf } from \"./explore-avatar-live-config\";\nimport { runTurnstile, type TurnstileRun } from \"./explore-avatar-turnstile\";\nimport { fill } from \"./explore-fill\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n AvatarConversation,\n ExplorePanelAvatarLive,\n} from \"./explore-avatar-live-config\";\nimport type { ExploreLocale } from \"./explore-i18n\";\nimport type { ExploreMessage } from \"./explore-types\";\nimport type {\n AvatarLiveModule,\n ReceiveOnlyEvent,\n ReceiveOnlySession,\n} from \"../avatar-live/types\";\n\n/** Where the consent card's privacy link goes: the site's privacy notice, at its live avatar section. */\nconst PRIVACY_HREF = \"/privacy#live-avatar\";\n\n/** How long a joined room waits for the avatar's video before the session is given up. */\nconst SPEAKER_WAIT_MS = 30_000;\n/** Past a session's end, how long before the browser leaves a room that is somehow still open. */\nconst END_GRACE_MS = 10_000;\n/** How far the server's end may sit from this browser's clock before the browser counts down on its own clock. */\nconst CLOCK_TOLERANCE_MS = 5_000;\n/**\n * Under `endUnattended`: out of sight, how long a session whose sound the browser holds back goes on before it is ended\n * (see `attend`). Long enough for a visitor who has just switched to the Chat tab or another browser tab to come back\n * and find \"Tap to turn on sound\"; short enough that a session nobody can hear is not paid for to its end.\n */\nconst UNHEARD_GRACE_MS = 5_000;\n/**\n * Under `endUnattended`: from the end of the speech at its source (`speech-ended`) to the answer's playout as the\n * visitor hears it. The worker's voice lags its source, and the server keeps a session for that lag: its planned end is\n * the speech's first frame + its length + a 3 s tail allowance (global-speech-svc `docs/AVATAR_WEB_API.md`, \"Timing\").\n * This is that allowance plus 2 s, so the last words are never cut, and the server's own end, which counts as a natural\n * finish only when no end request came before it, comes first while the server ends a session after its answer.\n */\nconst PLAYOUT_TAIL_MS = 5_000;\n\n/**\n * The avatar service refuses an answer more than fifteen minutes old (`not_eligible`; `MAX_AGE_MS` in global-speech-svc\n * `src/avatar/web/eligibility.ts`, measured from the answer's `createdAt` on the service's clock). If it changes, this\n * and the \"fifteen minutes\" in the `notEligible` and `startNewChatDetail` strings change with it.\n */\nconst SERVICE_MAX_AGE_MS = 15 * 60_000;\n/**\n * How long after an answer was created the view offers the avatar for it: a minute less than the service allows, so\n * that a visitor who reads the consent card near the edge is not sent through Start and a create request the service\n * will refuse. A visitor on the consent card when the answer crosses this age is moved to the start-over step (one\n * timer, set for that moment). Once Start is pressed, the create is skipped only past the service's own limit.\n */\nconst ANSWER_OFFER_MS = SERVICE_MAX_AGE_MS - 60_000;\n/** The longest delay a browser's `setTimeout` keeps (about 24.8 days): a longer one fires at once. */\nconst MAX_TIMER_MS = 2_147_483_647;\n\n/**\n * The longest question the Avatar tab's own box takes: the avatar service's limit for a question the visitor typed (the\n * chat's own limit is longer).\n */\nconst ASK_MAX_LENGTH = 300;\n/** The most references an answer the avatar service reads may cite (`eligibility.ts`); it needs at least one. */\nconst MAX_REFERENCES = 64;\n/**\n * Where this browser notes the day (UTC) it had a live session, so the box can say the day's session is used and ask in\n * text. A hint only: the limits are the server's.\n */\nconst USED_ON_KEY = \"boff.explore.avatarUsedOn\";\n\n/** The control each step puts focus on when the one the visitor was on has gone. */\nconst PRIMARY =\n '[data-avatar-primary], [data-boff-explore=\"panel-continue-chat\"]';\n\ninterface Offer extends AvatarOffer {\n /** The locale availability was asked for: the consent copy shown and the create request are both in this one. */\n locale: ExploreLocale;\n copy: AvatarConsentCopy;\n}\n\n/** What the page shows of a session: never its secret or its room token. */\ninterface ShownSession {\n /** When this browser counts the session as over, on its own clock. */\n endsAt: number;\n captions: { locale: string; text: string };\n}\n\n/**\n * How a session ended. `finished` means the server closed the room (the worker left, or the room was closed by the\n * server) while the avatar was live, or the session's time ran out with the room still open: the browser cannot tell the\n * avatar reading to the end from a server-side stop or a hand-over, so the words for it say only that the live avatar\n * has ended.\n */\ntype EndedHow = \"finished\" | \"stopped\" | \"failed\" | \"interrupted\";\n\ntype Phase =\n | { name: \"idle\" }\n | { name: \"checking\" }\n | { name: \"inert\" }\n | { name: \"needs-answer\"; offer: Offer }\n | { name: \"consent\"; offer: Offer; messageId: string }\n /** Under `any`: Not now. The card is offered again when the tab next opens, while the answer is fresh. */\n | { name: \"declined\"; offer: Offer }\n /** Under `any`: \"Start when ready\" pressed while the answer is still being written (see {@link WaitRun}). */\n | { name: \"waiting\"; offer: Offer }\n | { name: \"refused\"; reason: AvatarRefusal }\n | { name: \"bot-check\"; offer: Offer; messageId: string }\n | { name: \"creating\" }\n | { name: \"pending\"; session: ShownSession }\n | { name: \"live\"; session: ShownSession }\n | { name: \"ended\"; how: EndedHow };\n\nconst IDLE: Phase = { name: \"idle\" };\nconst INERT: Phase = { name: \"inert\" };\n\n/** One press of Start, until its create request has answered. */\ninterface StartRun {\n /** Set when the visitor (or the page) gave up on it, with the reason to end a session it still creates. */\n cancelled: AvatarEndReason | null;\n turnstile: TurnstileRun | null;\n}\n\n/**\n * One press of \"Start when ready\", until the answer is ready and checked (or the start is called off). The press is the\n * visitor's consent for exactly what it is bound to: this conversation, its first question and the answer on its way,\n * the site, the locale and the page, and the consent version and bot check that availability named. Any of them\n * changing calls it off with nothing created; once the answer is ready, availability is asked again and the answer\n * checked again, and anything that differs shows the card again instead of creating.\n */\ninterface WaitRun {\n bound: {\n token: string;\n questionId: string;\n answerId: string;\n site: string;\n locale: ExploreLocale;\n path: string;\n consentVersion: string;\n botCheck: AvatarBotCheck;\n };\n /** The room module, loading while the answer is written. */\n module: Promise<AvatarLiveModule>;\n /** The availability question asked again once the answer is ready; null until then. */\n check: AbortController | null;\n}\n\n/** A created session, from its 201 until it ends. */\ninterface SessionHandle {\n session: AvatarSession;\n base: string;\n headers: Readonly<Record<string, string>>;\n module: AvatarLiveModule;\n /** The join, once started. */\n room: Promise<ReceiveOnlySession | null> | null;\n /** The joined room, once joined: `enablePlayback` must be called inside the visitor's tap, so not via a promise. */\n joined: ReceiveOnlySession | null;\n /** When this browser counts the session as over, on its own clock (see `begin`). */\n endsAt: number;\n /** The avatar's video has arrived. */\n speakerArrived: boolean;\n /**\n * The avatar's voice (its audio track) has arrived. Until then a held-back sound is the room's guess (it reports a\n * suspended audio context as soon as it connects, and takes it back once the voice actually plays), not a voice\n * speaking to nobody.\n */\n voiceArrived: boolean;\n /** The browser holds the avatar's sound back (`playback-blocked`'s `sound`): nobody hears it until a tap. */\n soundHeld: boolean;\n /** The answer has played out: its speech ended at the source, and {@link PLAYOUT_TAIL_MS} has passed since. */\n playedOut: boolean;\n /** The attention rule's timers (see `attend`): the grace for held-back sound, and the playout tail. */\n unheard: ReturnType<typeof setTimeout> | null;\n tail: ReturnType<typeof setTimeout> | null;\n done: boolean;\n}\n\n/** Clear the attention rule's timers (see `attend`): the session has ended, or the view has gone. */\nfunction stopAttending(handle: SessionHandle): void {\n if (handle.unheard !== null) clearTimeout(handle.unheard);\n if (handle.tail !== null) clearTimeout(handle.tail);\n handle.unheard = null;\n handle.tail = null;\n}\n\nconst REFUSAL_TEXT: Record<AvatarRefusal, keyof AvatarLiveStrings> = {\n busy: \"busy\",\n limits: \"limits\",\n region: \"region\",\n locale: \"locale\",\n paused: \"paused\",\n not_eligible: \"notEligible\",\n answer_claimed: \"answerClaimed\",\n};\n\n/**\n * What the first exchange is. `answer` is the one the avatar may read; the others say why there is none yet, or never in\n * this conversation:\n *\n * - `empty`: nothing asked yet; `asking`: the first question, its answer on its way;\n * - `text-only` (under `any`): a completed first answer that fails a check the service makes and this browser can make\n * too (it cites none of the site's documentation, more references than the service takes, files with the question);\n * - `failed` (under `any`): the first answer failed;\n * - `ask-here` (under `any`): the first answer to a question that was not asked in this tab as the first of a new chat;\n * - `start-over`: anything else (a second question, an answer whose id the service cannot take, one too old).\n */\ntype ExchangeKind =\n | \"empty\"\n | \"asking\"\n | \"answer\"\n | \"text-only\"\n | \"failed\"\n | \"ask-here\"\n | \"start-over\";\n\n/** What the conversation offers the avatar to read. */\ninterface Exchange {\n kind: ExchangeKind;\n /** The answer the avatar may read, or null: set for `answer` only. */\n answerId: string | null;\n /**\n * The conversation can never be read: its first answer failed or is unusable, or it has gone past the first\n * exchange. Only a new chat can be. False while there is simply nothing to read yet.\n */\n startOver: boolean;\n /**\n * With an answer: until when (this browser's clock, in milliseconds) it is offered, {@link ANSWER_OFFER_MS} after its\n * `createdAt`. `NaN` for an answer whose `createdAt` is missing or cannot be read, which is never offered (the\n * service would refuse it). `NaN` without an answer too.\n */\n offerUntil: number;\n /** The first question, while the conversation is its first exchange; null otherwise. */\n question: ExploreMessage | null;\n /** Asking: the id the server gave the answer on its way (the one it keeps once complete), or null before then. */\n pendingAnswerId: string | null;\n /** Under `any`: the first question was asked in this tab, as the first of a new chat, in this page's visit. */\n askedHere: boolean;\n}\n\nconst EMPTY: Exchange = {\n kind: \"empty\",\n answerId: null,\n startOver: false,\n offerUntil: NaN,\n question: null,\n pendingAnswerId: null,\n askedHere: false,\n};\nconst START_OVER: Exchange = { ...EMPTY, kind: \"start-over\", startOver: true };\n\n/**\n * A question this tab asked as the first of a new chat, recorded only once the chat's `send` has actually added it: the\n * id of the USER message it added, and the conversation's token as that send ended (null when the server never named\n * one: a send that failed before the server took it). Not its text: the server stores the question normalized (line\n * endings, control characters, runs of blank lines: `normalizeExploreMessage` in global-support-svc), so the words in\n * the chat can differ from the ones the box sent, and the id alone already names the one message.\n */\ninterface AskedHere {\n messageId: string;\n token: string | null;\n}\n\n/**\n * Which rules the exchange is read by: the server's `questions`, the question this tab asked as the first of a new\n * chat (null when none), the conversation's token now, and whether the chat has a question on its way (`sending` or\n * `streaming`).\n */\ninterface ExchangeRules {\n any: boolean;\n askedHere: AskedHere | null;\n token: string | null;\n inFlight: boolean;\n}\n\nconst SUGGESTED_RULES: ExchangeRules = {\n any: false,\n askedHere: null,\n token: null,\n inFlight: false,\n};\n\n/**\n * Whether `question` is the one this tab asked: the very USER message its send added (its id), in the conversation that\n * send ended in. A question asked in Chat is never it, whatever it says (the same words included), and neither is a\n * conversation opened from History whose first question happens to read the same.\n */\nfunction isAskedHere(question: ExploreMessage, rules: ExchangeRules): boolean {\n const asked = rules.askedHere;\n return (\n rules.any &&\n asked !== null &&\n question.id === asked.messageId &&\n asked.token === rules.token\n );\n}\n\n/** A message's `createdAt` in milliseconds, or `NaN` when it is missing or not a date. */\nfunction createdAtOf(message: ExploreMessage): number {\n const raw: unknown = message.createdAt;\n return typeof raw === \"string\" && raw !== \"\" ? Date.parse(raw) : NaN;\n}\n\n/**\n * The exchange as it stands at `now`: an answer past its {@link Exchange.offerUntil} (or with no readable time) is\n * no longer offered, and only a new chat can be.\n */\nfunction offeredAt(exchange: Exchange, now: number): Exchange {\n // `!(now < …)` and not `now >= …`: with a `NaN` deadline (no readable `createdAt`) it is true, so the answer is not\n // offered.\n return exchange.answerId !== null && !(now < exchange.offerUntil)\n ? START_OVER\n : exchange;\n}\n\n/**\n * The checks on a first answer that the avatar service makes and this browser can make as well (`eligibility.ts` in\n * global-speech-svc): it is an answer (`answered`), it cites between one and {@link MAX_REFERENCES} references, and no\n * files came with the question. The service stays the judge: this only keeps the card from offering what it refuses.\n */\nfunction readable(question: ExploreMessage, answer: ExploreMessage): boolean {\n const references = answer.references?.length ?? 0;\n return (\n answer.answered === true &&\n references >= 1 &&\n references <= MAX_REFERENCES &&\n (question.attachments?.length ?? 0) === 0\n );\n}\n\n/**\n * The one answer the avatar may read, and why there is none. The avatar service accepts a conversation only when it\n * holds EXACTLY two messages: the first USER message and the first ASSISTANT answer, COMPLETED. This is the same rule,\n * so the avatar is never offered, and the visitor never goes through consent and the bot check, for a conversation the\n * service would refuse:\n *\n * - exactly that exchange: its answer;\n * - nothing asked yet, or the question asked and its answer still on its way: nothing yet (the view says to choose a\n * suggested question, or that the answer is coming, and offers the avatar once the answer completes);\n * - anything else (a failed or empty first answer, a second question, whatever came after a failed answer asked\n * again without Retry): never, in this conversation (the view says to start a new chat).\n *\n * The service also refuses an answer more than fifteen minutes old: a conversation restored from this browser's\n * history, say. That depends on the time as well as the messages, so it is applied on top of this (`offeredAt`), with\n * the answer's {@link Exchange.offerUntil}.\n *\n * Under `suggested`, that the question is one of the suggested ones is the service's to judge (`not_eligible`), not the\n * browser's. Under `any` (the Avatar tab's own box), the answer is offered only to a question this tab asked as the\n * first of a new chat, and only when it passes the checks this browser can make too ({@link readable}); a failed\n * first answer is told apart, so the tab can say so.\n */\nfunction firstExchange(\n messages: readonly ExploreMessage[] | undefined,\n rules: ExchangeRules = SUGGESTED_RULES,\n): Exchange {\n if (!messages || messages.length === 0) return EMPTY;\n if (messages.length > 2) return START_OVER;\n const [question, answer] = messages;\n if (question?.role !== \"USER\") return START_OVER;\n const first = { question, askedHere: isAskedHere(question, rules) };\n if (answer === undefined) {\n // The question alone. On its way: the answer is coming. Otherwise none is: the chat drops a failed answer that\n // had no text (and one a reload cut short), so under `any` the tab says the answer failed; under `suggested`, as\n // before, nothing has been answered yet.\n if (rules.inFlight) return { ...EMPTY, ...first, kind: \"asking\" };\n return rules.any ? { ...START_OVER, ...first, kind: \"failed\" } : EMPTY;\n }\n if (answer.role !== \"ASSISTANT\") return START_OVER;\n if (answer.status === \"PENDING\" || answer.status === \"RUNNING\") {\n return {\n ...EMPTY,\n ...first,\n kind: \"asking\",\n pendingAnswerId: isAvatarMessageId(answer.id) ? answer.id : null,\n };\n }\n if (rules.any && answer.status === \"FAILED\") {\n return { ...START_OVER, ...first, kind: \"failed\" };\n }\n if (\n answer.status !== \"COMPLETED\" ||\n answer.content.trim() === \"\" ||\n !isAvatarMessageId(answer.id)\n ) {\n return START_OVER;\n }\n if (rules.any && !first.askedHere) {\n return { ...START_OVER, ...first, kind: \"ask-here\" };\n }\n if (rules.any && !readable(question, answer)) {\n return { ...START_OVER, ...first, kind: \"text-only\" };\n }\n return {\n ...EMPTY,\n ...first,\n kind: \"answer\",\n answerId: answer.id,\n offerUntil: createdAtOf(answer) + ANSWER_OFFER_MS,\n };\n}\n\n/** Whether the chat has a question on its way. */\nfunction inFlight(conversation: AvatarConversation | null): boolean {\n return (\n conversation?.phase === \"sending\" || conversation?.phase === \"streaming\"\n );\n}\n\n/** Today, as UTC: the day the box's note of a used session is for. */\nfunction utcToday(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\n/** Whether this browser noted a live session today. Storage that cannot be read (a private window) is no note. */\nfunction usedTodayHere(): boolean {\n try {\n return window.localStorage.getItem(USED_ON_KEY) === utcToday();\n } catch {\n return false;\n }\n}\n\n/** Note today's live session, where this browser lets the page keep it. */\nfunction noteUsedToday(): void {\n try {\n window.localStorage.setItem(USED_ON_KEY, utcToday());\n } catch {\n // Storage blocked: the box simply does not know, and the server's limits still hold.\n }\n}\n\n/** A tenth of a second of silence, as a WAV data URI, made once, the first time a Start needs it. */\nlet silence: string | null = null;\n\nfunction silentWav(): string {\n if (silence !== null) return silence;\n // 8 kHz, 8-bit mono: 800 samples at the mid level (128) is silence.\n const rate = 8_000;\n const samples = rate / 10;\n const bytes = new Uint8Array(44 + samples);\n const view = new DataView(bytes.buffer);\n const text = (at: number, value: string) => {\n for (let i = 0; i < value.length; i += 1) {\n bytes[at + i] = value.charCodeAt(i);\n }\n };\n text(0, \"RIFF\");\n view.setUint32(4, 36 + samples, true);\n text(8, \"WAVE\");\n text(12, \"fmt \");\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true); // PCM\n view.setUint16(22, 1, true); // mono\n view.setUint32(24, rate, true);\n view.setUint32(28, rate, true); // bytes a second\n view.setUint16(32, 1, true); // bytes a frame\n view.setUint16(34, 8, true); // bits a sample\n text(36, \"data\");\n view.setUint32(40, samples, true);\n bytes.fill(128, 44);\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n silence = `data:audio/wav;base64,${btoa(binary)}`;\n return silence;\n}\n\n/**\n * Let the page play sound later: called straight from the visitor's tap on Start (browsers allow sound only from inside\n * a gesture, and Safari on iOS keeps an element locked until then), it plays a tenth of a second of silence on the\n * element the room's audio will use, and pauses it. \"Tap to turn on sound\" stays for a browser that still holds sound\n * back. An element already playing a room's audio is left alone.\n */\nfunction unlockSound(audio: HTMLAudioElement | null): void {\n if (audio === null || audio.srcObject) return;\n try {\n audio.src = silentWav();\n void Promise.resolve(audio.play()).then(\n () => audio.pause(),\n () => undefined,\n );\n } catch {\n // A browser that cannot play it now: the room's own playback, and the sound button, still work.\n }\n}\n\n/**\n * The step that offers `messageId` to the visitor: the consent card, unless this visit has already used that answer\n * (`claimed` holds every answer a session was created for, or that the server said it already has one for), in which\n * case it says so instead. The ways back to a consent card for an answer that may have been used in the meantime go\n * through here: the availability answer, and returning from a bot check.\n */\nfunction offering(\n offer: Offer,\n messageId: string,\n claimed: ReadonlySet<string>,\n): Phase {\n return claimed.has(messageId)\n ? { name: \"refused\", reason: \"answer_claimed\" }\n : { name: \"consent\", offer, messageId };\n}\n\nasync function loadModule(\n load: () => Promise<AvatarLiveModule>,\n): Promise<AvatarLiveModule> {\n const loaded: unknown = await load();\n const join =\n loaded !== null && typeof loaded === \"object\"\n ? (loaded as Partial<AvatarLiveModule>).joinReceiveOnly\n : undefined;\n if (typeof join !== \"function\") {\n throw new Error(\"The live avatar module could not be loaded.\");\n }\n return loaded as AvatarLiveModule;\n}\n\n/** `m:ss`. */\nfunction clock(seconds: number): string {\n const whole = Math.max(0, Math.ceil(seconds));\n return `${Math.floor(whole / 60)}:${String(whole % 60).padStart(2, \"0\")}`;\n}\n\nexport interface AvatarLiveViewProps {\n live: ExplorePanelAvatarLive;\n /** The Avatar view is showing: the panel is open and its Avatar tab is selected. */\n active: boolean;\n /**\n * The panel is open, whichever tab it shows. With `active` it tells the Chat tab (open, not active: the pane is only\n * hidden, and a session under way keeps playing) from the panel closing (not open: what is under way ends).\n */\n open: boolean;\n locale: ExploreLocale;\n /** The product the panel speaks for, when it is one product's own; null on the portfolio's. */\n productName: string | null;\n /** The approved still picture. */\n still: { src: string; alt: string };\n /** The Avatar tab as it was before the live avatar: shown whenever the live avatar is not offered or not reachable. */\n fallback: ReactNode;\n /**\n * Back to the Chat tab. Like the Chat tab itself, it calls off a start that has not been sent yet, and leaves a\n * session under way speaking.\n */\n onContinueInChat: () => void;\n /**\n * Told whenever the avatar's voice starts or stops being the page's: its status line while a session is being\n * created, joined or played (\"Connecting to the live avatar…\", \"The avatar is speaking.\"), and null otherwise (and\n * when the view goes). The panel holds Chat's own read-aloud and dictation meanwhile, so the page never speaks in two\n * voices and the microphone never takes down the avatar's.\n */\n onVoiceHold?: (line: string | null) => void;\n /** \"Continue in Chat\" in the panel's language: the panel's own word for it, so this chunk carries none of the panel's. */\n continueInChat: string;\n /**\n * \"New chat\" in the panel's language, the panel's own word for it: the button that starts over (the conversation's\n * `reset`, as the chat's own New chat button does, then the Chat tab) where this conversation can never be read.\n */\n newChat: string;\n /** \"Send\" and \"Try asking\" in the panel's language, for the Avatar tab's own question box. */\n send: string;\n tryAsking: string;\n /** The suggested questions the chat view shows: the box's chips. */\n prompts: readonly string[];\n /** No precise pointer: the box is not focused by itself, so the keyboard does not cover the view. */\n touchFirst: boolean;\n /** The host router's path, when it has one: a \"Start when ready\" is called off when it changes. */\n currentPath: string | undefined;\n /**\n * Nothing to ask the server about: an incomplete config, no gateway, no shared conversation to read (no provider, or a\n * read-only shared one), or a locale whose strings have not been reviewed. The tab stays as it was. Decided by\n * `ExploreAvatarLive`, which also decides whether this view is loaded at all; it can change while this view is\n * mounted (the panel's locale switching), and what is under way then ends.\n */\n off: boolean;\n /** {@link avatarApiBase} of the SDK's gateway, null when there is none to use. */\n base: string | null;\n /** Headers every request carries: the alpha gateway's access headers, and nothing on production. */\n headers: Readonly<Record<string, string>>;\n /** The panel's conversation, null when there is no provider. */\n conversation: AvatarConversation | null;\n}\n\nexport function AvatarLiveView({\n live,\n active,\n open,\n locale,\n productName,\n still,\n fallback,\n onContinueInChat,\n onVoiceHold,\n continueInChat,\n newChat,\n send,\n tryAsking,\n prompts,\n touchFirst,\n currentPath,\n off,\n base,\n headers,\n conversation,\n}: AvatarLiveViewProps) {\n const S = avatarLiveStrings(locale);\n const uid = useId();\n const consentTitleId = `${uid}-consent`;\n\n /**\n * Which first questions the server reads the answer to, as its last availability answer said (`suggested` until one\n * says `any`). Kept in a ref as well, for the steps that read it between renders.\n */\n const [questions, setQuestions] = useState<AvatarQuestions>(\"suggested\");\n const questionsRef = useRef<AvatarQuestions>(\"suggested\");\n /**\n * The question this tab asked as the first of a new chat, in this page's visit; null when none. Recorded only once the\n * chat's `send` says which message it added (see `ask`), and set and cleared through {@link setAskedHere} alone.\n */\n const askedHereRef = useRef<AskedHere | null>(null);\n /**\n * Counts every ask from the box and every clearing of {@link askedHereRef}: an ask whose send resolves after a New\n * chat, a reset, another conversation or a later ask records nothing.\n */\n const askSeqRef = useRef(0);\n /** Re-renders the view when {@link askedHereRef} changes: a ref alone would leave the card unshown. */\n const [, setAskedHereTick] = useState(0);\n const setAskedHere = useCallback((next: AskedHere | null) => {\n if (next === null) {\n askSeqRef.current += 1;\n if (askedHereRef.current === null) return;\n }\n askedHereRef.current = next;\n setAskedHereTick((tick) => tick + 1);\n }, []);\n\n // Compared, never shown: see `getConversationToken`.\n const token = conversation?.getConversationToken() ?? null;\n const exchange = firstExchange(conversation?.messages, {\n any: questions === \"any\",\n askedHere: askedHereRef.current,\n token,\n inFlight: inFlight(conversation),\n });\n // Re-rendered by the timer below at the moment the answer stops being offered: the time is read here, on each render.\n const [ageTick, setAgeTick] = useState(0);\n const shown = offeredAt(exchange, Date.now());\n const { answerId, startOver } = shown;\n /** Until when the answer is offered, while one is. */\n const offerUntil = answerId === null ? null : exchange.offerUntil;\n\n const [phase, setPhase] = useState<Phase>(IDLE);\n const [blocked, setBlocked] = useState(false);\n const [now, setNow] = useState(() => Date.now());\n /** The box's text: the view's own, never the chat's draft. */\n const [draft, setDraft] = useState(\"\");\n /**\n * The longest question the box takes: the avatar service's limit, or the chat's own (the live catalog's) where that is\n * shorter, since the chat refuses a longer one without adding it.\n */\n const chatMaxLength = conversation?.catalog.limits.maxMessageLength;\n const askMaxLength =\n chatMaxLength !== undefined &&\n Number.isFinite(chatMaxLength) &&\n chatMaxLength >= 1\n ? Math.min(ASK_MAX_LENGTH, Math.floor(chatMaxLength))\n : ASK_MAX_LENGTH;\n /** A line the view owes the visitor: a new chat was started for the avatar, or a \"Start when ready\" was called off. */\n const [note, setNote] = useState<\"new-chat\" | \"cancelled\" | null>(null);\n /** This browser noted a live session today (read once the view is on the page). */\n const [usedToday, setUsedToday] = useState(false);\n\n /**\n * The live view is on the page: the Avatar tab is selected in an open panel, and the live avatar is on. It is also\n * hidden while `off` puts the fallback in its place (the panel's locale switching to one whose strings have not been\n * reviewed, say), which unmounts the video and audio elements a room is attached to.\n */\n const showing = active && !off;\n /**\n * Hidden only because the open panel shows its Chat tab: the pane is CSS-hidden, its video and audio elements stay\n * mounted and attached, so a session under way can keep playing (see `leave`).\n */\n const behindChat = open && !active && !off;\n\n const phaseRef = useRef<Phase>(IDLE);\n /** This render's view of everything the asynchronous steps read, so they never act on a stale one. */\n const latest = useRef({\n live,\n locale,\n base,\n headers,\n off,\n currentPath,\n showing,\n });\n latest.current = { live, locale, base, headers, off, currentPath, showing };\n const conversationRef = useRef(conversation);\n conversationRef.current = conversation;\n const waitRef = useRef<WaitRun | null>(null);\n /** A question from the box is on its way to the chat: a second press sends nothing. */\n const sendingRef = useRef(false);\n /** The box asks ordinary questions, whose answers stay text (set each render; see `textBox`). */\n const textBoxRef = useRef(false);\n\n const checkRef = useRef<AbortController | null>(null);\n /**\n * The locale the last availability question was asked for (or settled without asking): a later change of locale asks\n * again (see the effect on `locale`), and a view that has just asked for the new locale does not ask twice.\n */\n const askedLocale = useRef(locale);\n const startRef = useRef<StartRun | null>(null);\n const sessionRef = useRef<SessionHandle | null>(null);\n /**\n * Every answer whose session this visit has already created (or found already read): none of them is offered again.\n * A set and not the latest one: a create the visitor gave up on can answer long after they moved to another chat and\n * used its first answer, and what it reports is added to what is known, never put in its place.\n */\n const claimedRef = useRef<Set<string>>(new Set());\n\n const rootRef = useRef<HTMLDivElement>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const audioRef = useRef<HTMLAudioElement>(null);\n const botBoxRef = useRef<HTMLDivElement>(null);\n\n const go = useCallback((next: Phase) => {\n phaseRef.current = next;\n setPhase(next);\n }, []);\n\n /**\n * Whether the visitor can see the view: it is showing, and the page is not hidden. Out of sight, a browser may hold a\n * muted video back (Chrome pauses one that is off screen or in a background tab), so its `playing` cannot be waited\n * for there (see `goLive`).\n */\n const inSight = useCallback(\n (): boolean =>\n latest.current.showing &&\n (typeof document === \"undefined\" ||\n document.visibilityState !== \"hidden\"),\n [],\n );\n\n const setMode = useCallback((next: AvatarQuestions) => {\n questionsRef.current = next;\n setQuestions(next);\n }, []);\n\n /**\n * The exchange right now, read when a step needs it rather than from the last render: the answer may have stopped\n * being offered since (it grew too old while nothing re-rendered), and the server's `questions` may have just changed.\n */\n const exchangeNow = useCallback(\n (): Exchange =>\n offeredAt(\n firstExchange(conversationRef.current?.messages, {\n any: questionsRef.current === \"any\",\n askedHere: askedHereRef.current,\n token: conversationRef.current?.getConversationToken() ?? null,\n inFlight: inFlight(conversationRef.current),\n }),\n Date.now(),\n ),\n [],\n );\n\n /** The answer offered right now (see {@link exchangeNow}). */\n const offeredNow = useCallback(\n (): string | null => exchangeNow().answerId,\n [exchangeNow],\n );\n\n /** The page the visitor is on: the host router's path, else the window's. */\n const pathNow = useCallback(\n (): string =>\n latest.current.currentPath ??\n (typeof window === \"undefined\" ? \"\" : window.location.pathname),\n [],\n );\n\n /** Back to what the offer shows for the answer offered now: its consent card, or the step without one. */\n const reoffer = useCallback(\n (offer: Offer): Phase => {\n const messageId = offeredNow();\n return messageId === null\n ? { name: \"needs-answer\", offer }\n : offering(offer, messageId, claimedRef.current);\n },\n [offeredNow],\n );\n\n /** End the session: tell the server (unless it ended it), leave the room, and show how it ended. */\n const finish = useCallback(\n (how: EndedHow, reason: AvatarEndReason | null) => {\n const handle = sessionRef.current;\n if (!handle || handle.done) return;\n handle.done = true;\n stopAttending(handle);\n sessionRef.current = null;\n if (reason !== null) {\n sendEnd({\n base: handle.base,\n headers: handle.headers,\n sessionId: handle.session.sessionId,\n secret: handle.session.endSecret,\n reason,\n });\n }\n const room = handle.joined;\n handle.joined = null;\n if (room) void room.leave().catch(() => undefined);\n setBlocked(false);\n go({ name: \"ended\", how });\n },\n [go],\n );\n\n /**\n * The avatar is on: its video plays (`playing`), or, while the view is out of sight (the Chat tab, a hidden page),\n * its video has arrived. A browser may hold a muted video back out of sight and play it only once it shows again, so\n * waiting for `playing` there would leave a session that is speaking counted as never started, and ended as failed\n * when the server closes it. Under `any`, the box notes the day's session as used (a hint for the visitor: the limits\n * are the server's).\n */\n const goLive = useCallback(() => {\n const current = phaseRef.current;\n const handle = sessionRef.current;\n if (current.name !== \"pending\" || !handle) return;\n handle.speakerArrived = true;\n if (questionsRef.current === \"any\") {\n noteUsedToday();\n setUsedToday(true);\n }\n go({ name: \"live\", session: current.session });\n }, [go]);\n\n /**\n * The attention rule, under `live.endUnattended` (without it, nothing here runs and nothing changes): a paid session\n * never outlives the visitor's attention. Out of sight (behind the Chat tab, on a hidden page) the answer under way\n * still plays to its end; past that, nothing is paid for that nobody can see or hear:\n *\n * - **Played out** (its speech ended at the source, and {@link PLAYOUT_TAIL_MS} has passed): a live session out of\n * sight ends at once, as finished. This is the lifecycle rule every later stage keeps: **an idle tail after an\n * answer runs only while the Avatar view is in sight**, and going out of sight during it ends the session then. (A\n * session still waiting for the avatar's video is the speaker wait's, {@link SPEAKER_WAIT_MS}.)\n * - **Sound held back** (`playback-blocked`'s `sound`: autoplay refused, or the room's audio context suspended), once\n * the avatar's voice has arrived: in sight, \"Tap to turn on sound\" shows and nothing ends. Out of sight nobody can\n * tap it, so after {@link UNHEARD_GRACE_MS} the session ends early: \"The live avatar stopped early.\" and \"The full\n * answer is in Chat.\". Back in sight, or the sound let through, within the grace: nothing ends.\n *\n * Both send the end with reason `user`, and once (`finish`). Run whenever what it reads changes: the view's sight, the\n * page's, the sound and the playout.\n */\n const attend = useCallback(() => {\n const handle = sessionRef.current;\n if (!handle || handle.done || latest.current.live.endUnattended !== true) {\n return;\n }\n const current = phaseRef.current.name;\n if (current !== \"pending\" && current !== \"live\") return;\n const away = !inSight();\n if (away && handle.playedOut && current === \"live\") {\n finish(\"finished\", \"user\");\n return;\n }\n if (!(away && handle.soundHeld && handle.voiceArrived)) {\n if (handle.unheard !== null) {\n clearTimeout(handle.unheard);\n handle.unheard = null;\n }\n return;\n }\n if (handle.unheard !== null) return;\n handle.unheard = setTimeout(() => {\n handle.unheard = null;\n if (\n sessionRef.current === handle &&\n !handle.done &&\n latest.current.live.endUnattended === true &&\n handle.soundHeld &&\n handle.voiceArrived &&\n !inSight()\n ) {\n finish(\"interrupted\", \"user\");\n }\n }, UNHEARD_GRACE_MS);\n }, [finish, inSight]);\n\n /** Give up on a Start still on its way to a session. A session it still creates is ended with `reason`. */\n const cancelStart = useCallback((reason: AvatarEndReason) => {\n const run = startRef.current;\n if (!run) return;\n startRef.current = null;\n run.cancelled = reason;\n run.turnstile?.cancel();\n }, []);\n\n /**\n * Go to the step an availability answer, asked in `locale`, leads to. A `refused` answer still says which questions the\n * server reads, for the box (a `limits` refusal under `any` keeps the box, asking in text).\n */\n const applyAvailability = useCallback(\n (result: AvatarAvailability, locale: ExploreLocale) => {\n const { live } = latest.current;\n if (result.kind === \"inert\") {\n setMode(\"suggested\");\n go(INERT);\n return;\n }\n if (result.kind === \"refused\") {\n setMode(result.questions);\n go({ name: \"refused\", reason: result.reason });\n return;\n }\n // A fresh answer from the server, a fresh look at this browser's note of the day's session.\n setUsedToday(usedTodayHere());\n // The copy for the version the server named, in the locale it was asked about (a later locale change asks\n // again: see the effect on `locale`).\n const copy = avatarConsentCopy(result.offer.consentVersion, locale);\n // A consent version this SDK has no reviewed copy for: no card, rather than words the server does not record. Nor\n // copy that describes another bot check than the one the server runs, or other questions than the ones it reads:\n // the visitor would agree to a notice that is wrong about it.\n if (\n copy === null ||\n copy.botCheck !== result.offer.botCheck ||\n copy.questions !== result.offer.questions\n ) {\n setMode(\"suggested\");\n go(INERT);\n return;\n }\n // A server that checks for bots, and no site key this page may use for its check: no start could pass it.\n if (\n result.offer.botCheck === \"turnstile\" &&\n turnstileSiteKeyOf(live) === null\n ) {\n setMode(\"suggested\");\n go(INERT);\n return;\n }\n setMode(result.offer.questions);\n go(reoffer({ ...result.offer, locale, copy }));\n },\n [go, reoffer, setMode],\n );\n\n const check = useCallback(() => {\n const { live, locale, base, headers, off } = latest.current;\n checkRef.current?.abort();\n checkRef.current = null;\n askedLocale.current = locale;\n if (off || base === null) {\n go(INERT);\n return;\n }\n const controller = new AbortController();\n checkRef.current = controller;\n go({ name: \"checking\" });\n void requestAvailability({\n base,\n headers,\n site: live.site,\n locale,\n signal: controller.signal,\n }).then((result) => {\n if (checkRef.current !== controller) return;\n checkRef.current = null;\n applyAvailability(result, locale);\n });\n }, [applyAvailability, go]);\n\n const begin = useCallback(\n (\n session: AvatarSession,\n module: AvatarLiveModule,\n offer: Offer,\n target: { base: string; headers: Readonly<Record<string, string>> },\n ) => {\n // Count down on the server's end when this browser's clock agrees with it, else on this browser's own clock.\n const received = Date.now();\n const longest = offer.maxSessionSeconds * 1000;\n const ahead = session.endsAt - received;\n const endsAt =\n ahead > 0 && ahead <= longest + CLOCK_TOLERANCE_MS\n ? session.endsAt\n : received + longest;\n sessionRef.current = {\n session,\n base: target.base,\n headers: target.headers,\n module,\n room: null,\n joined: null,\n endsAt,\n speakerArrived: false,\n voiceArrived: false,\n soundHeld: false,\n playedOut: false,\n unheard: null,\n tail: null,\n done: false,\n };\n setBlocked(false);\n setNow(received);\n go({\n name: \"pending\",\n session: { endsAt, captions: session.captions },\n });\n },\n [go],\n );\n\n const settle = useCallback(\n (\n result: AvatarCreateResult,\n run: StartRun,\n context: {\n module: AvatarLiveModule;\n offer: Offer;\n messageId: string;\n base: string;\n headers: Readonly<Record<string, string>>;\n },\n ) => {\n const created =\n result.kind === \"created\"\n ? {\n sessionId: result.session.sessionId,\n secret: result.session.endSecret,\n }\n : result.kind === \"unusable\"\n ? { sessionId: result.sessionId, secret: result.endSecret }\n : null;\n // A session now exists for this answer (this create made it, or the server says an earlier one did): it is used.\n const claimed =\n created !== null ||\n (result.kind === \"refused\" && result.reason === \"answer_claimed\");\n if (claimed) claimedRef.current.add(context.messageId);\n if (run.cancelled !== null) {\n // Given up while the request was on its way: a session it created is ended at once.\n if (created !== null) {\n sendEnd({\n base: context.base,\n headers: context.headers,\n sessionId: created.sessionId,\n secret: created.secret,\n reason: run.cancelled,\n });\n }\n // The visitor may be back on the consent card for this very answer by now (they left during the create and came\n // back before it answered): it has been read, so the card gives way to saying so rather than offering it again.\n const shown = phaseRef.current;\n if (\n claimed &&\n shown.name === \"consent\" &&\n shown.messageId === context.messageId\n ) {\n go({ name: \"refused\", reason: \"answer_claimed\" });\n }\n return;\n }\n switch (result.kind) {\n case \"created\":\n begin(result.session, context.module, context.offer, context);\n return;\n case \"unusable\":\n sendEnd({\n base: context.base,\n headers: context.headers,\n sessionId: result.sessionId,\n secret: result.endSecret,\n reason: \"client_error\",\n });\n go({ name: \"ended\", how: \"failed\" });\n return;\n case \"refused\":\n go({ name: \"refused\", reason: result.reason });\n return;\n case \"consent\":\n // The consent version moved on: ask again, and show the consent that is current now.\n check();\n return;\n case \"inert\":\n go(INERT);\n return;\n case \"failed\":\n go({ name: \"ended\", how: \"failed\" });\n return;\n }\n },\n [begin, check, go],\n );\n\n /**\n * From the visitor's consent to a session for `messageId`: Start on the card, or a \"Start when ready\" whose answer is\n * now ready and checked (with the room module it has been loading meanwhile, `preloaded`). One create request, never\n * sent again by itself: a failed create ends as failed, and only another tap can start again.\n */\n const launch = useCallback(\n (\n offer: Offer,\n messageId: string,\n preloaded: Promise<AvatarLiveModule> | null,\n ) => {\n const { live, base, headers } = latest.current;\n if (base === null) return;\n const exchangeAtStart = exchangeNow();\n // The answer has grown too old for the service since the card was shown (a timer that has not run yet: a throttled\n // background tab, say), or the conversation has moved on: no request the service would refuse.\n if (exchangeAtStart.answerId !== messageId) {\n go(reoffer(offer));\n return;\n }\n // Already read in this visit (a \"Start when ready\" whose answer a session elsewhere in this visit used): say so.\n if (claimedRef.current.has(messageId)) {\n go({ name: \"refused\", reason: \"answer_claimed\" });\n return;\n }\n // When the service will refuse this answer as too old: the module and a bot check can take a while, and a create\n // that starts after this is not sent.\n const refusedFrom =\n exchangeAtStart.offerUntil - ANSWER_OFFER_MS + SERVICE_MAX_AGE_MS;\n // The key for the bot check, where the server runs one; null where it runs none.\n const siteKey =\n offer.botCheck === \"turnstile\" ? turnstileSiteKeyOf(live) : null;\n // A bot check with no key this page may use, or with no WebCrypto (a page that is not a secure context) to bind it\n // to a create request: no live avatar can start here. Nothing is loaded for a start that cannot happen (no module,\n // no bot-check script), and the tab stays as it was.\n if (\n offer.botCheck === \"turnstile\" &&\n (siteKey === null || !canBindBotCheck())\n ) {\n go(INERT);\n return;\n }\n // The create request's values, read once, here. A bot check is bound to exactly these (`avatarBotBinding`, before its\n // widget is rendered), so the request that follows it carries this same body and reads nothing again.\n const conversationToken =\n conversationRef.current?.getConversationToken() ?? null;\n const idempotencyKey = newIdempotencyKey();\n if (\n conversationToken === null ||\n !isAvatarConversationToken(conversationToken) ||\n idempotencyKey === null\n ) {\n // Nothing to create a session for: no module, no bot check.\n go({ name: \"ended\", how: \"failed\" });\n return;\n }\n const body: AvatarCreateBody = {\n site: live.site,\n locale: offer.locale,\n conversationToken,\n messageId,\n consentVersion: offer.consentVersion,\n manifestVersion: live.manifestVersion,\n };\n const run: StartRun = { cancelled: null, turnstile: null };\n startRef.current = run;\n // Only now that the visitor has agreed: the live module (already loading, for a \"Start when ready\"), and the bot\n // check where the server runs one. Where it runs none, there is no Cloudflare script, no widget and no token: the\n // module loads and the request follows.\n const module = preloaded ?? loadModule(live.load);\n let turnstile: TurnstileRun | null = null;\n if (siteKey === null) {\n go({ name: \"creating\" });\n } else {\n go({ name: \"bot-check\", offer, messageId });\n turnstile = runTurnstile(\n botBoxRef.current,\n siteKey,\n \"avatar_start\",\n avatarBotBinding(body),\n );\n run.turnstile = turnstile;\n }\n void (async () => {\n let loaded: AvatarLiveModule;\n let botToken: string | undefined;\n try {\n [loaded, botToken] = await Promise.all([module, turnstile?.token]);\n } catch {\n turnstile?.cancel();\n if (run.cancelled === null) {\n startRef.current = null;\n go(INERT);\n }\n return;\n }\n // The widget has done its work.\n turnstile?.cancel();\n if (run.cancelled !== null) return;\n // The answer grew too old for the service while the module or the bot check took their time: nothing is created,\n // and the view says to start a new chat (it reads the answer as too old now).\n if (!(Date.now() < refusedFrom)) {\n startRef.current = null;\n go({ name: \"needs-answer\", offer });\n return;\n }\n if (turnstile !== null) go({ name: \"creating\" });\n const result = await requestCreate({\n base,\n headers,\n idempotencyKey,\n botToken,\n body,\n });\n if (startRef.current === run) startRef.current = null;\n settle(result, run, {\n module: loaded,\n offer,\n messageId,\n base,\n headers,\n });\n })();\n },\n [exchangeNow, go, reoffer, settle],\n );\n\n /** Start, on the consent card. Under `any`, the tap also lets the page play the avatar's sound later. */\n const start = useCallback(() => {\n const current = phaseRef.current;\n if (current.name !== \"consent\") return;\n if (current.offer.questions === \"any\") unlockSound(audioRef.current);\n launch(current.offer, current.messageId, null);\n }, [launch]);\n\n /**\n * Call off a \"Start when ready\": nothing is created, and the view goes back to the answer being written (or to what\n * the conversation now is). `told`: the visitor did not cancel it themselves, so the view says it did not start.\n */\n const cancelWaiting = useCallback(\n (told: boolean) => {\n const wait = waitRef.current;\n waitRef.current = null;\n wait?.check?.abort();\n const current = phaseRef.current;\n if (current.name !== \"waiting\") return;\n if (told) setNote(\"cancelled\");\n go({ name: \"needs-answer\", offer: current.offer });\n },\n [go],\n );\n\n /** Whether what a \"Start when ready\" was bound to still holds, for the exchange as it is now. */\n const bindingHolds = useCallback(\n (bound: WaitRun[\"bound\"], exchange: Exchange): boolean => {\n const { live, locale } = latest.current;\n return (\n conversationRef.current?.getConversationToken() === bound.token &&\n exchange.question?.id === bound.questionId &&\n live.site === bound.site &&\n locale === bound.locale &&\n pathNow() === bound.path\n );\n },\n [pathNow],\n );\n\n /**\n * \"Start when ready\", on the card shown while the answer is written: the visitor's consent for this conversation's\n * first answer, once it is ready (see {@link WaitRun}). Pressed only for a question this tab asked as the first of a\n * new chat, once the server has taken it.\n */\n const startWhenReady = useCallback(() => {\n const current = phaseRef.current;\n if (current.name !== \"needs-answer\") return;\n const { live, locale } = latest.current;\n const exchange = exchangeNow();\n const token = conversationRef.current?.getConversationToken() ?? null;\n if (\n exchange.kind !== \"asking\" ||\n !exchange.askedHere ||\n exchange.question === null ||\n exchange.pendingAnswerId === null ||\n token === null ||\n !isAvatarConversationToken(token)\n ) {\n return;\n }\n unlockSound(audioRef.current);\n const module = loadModule(live.load);\n // Read when the answer is ready; a failure then is the start's. Until then, nothing is left unhandled.\n module.catch(() => undefined);\n waitRef.current = {\n bound: {\n token,\n questionId: exchange.question.id,\n answerId: exchange.pendingAnswerId,\n site: live.site,\n locale,\n path: pathNow(),\n consentVersion: current.offer.consentVersion,\n botCheck: current.offer.botCheck,\n },\n module,\n check: null,\n };\n setNote(null);\n go({ name: \"waiting\", offer: current.offer });\n }, [exchangeNow, go, pathNow]);\n\n /**\n * The answer a \"Start when ready\" waited for is ready: ask availability again (no cache) and check the answer again,\n * and create only if nothing differs. Anything that does (another consent version or bot check, a refusal, the answer\n * or the conversation) shows what is offered now instead: the card again, or why there is none.\n */\n const confirm = useCallback(\n (offer: Offer, wait: WaitRun) => {\n const { live, locale, base, headers } = latest.current;\n if (base === null) {\n cancelWaiting(true);\n return;\n }\n const controller = new AbortController();\n wait.check = controller;\n void requestAvailability({\n base,\n headers,\n site: live.site,\n locale,\n signal: controller.signal,\n }).then((result) => {\n if (waitRef.current !== wait || phaseRef.current.name !== \"waiting\") {\n return;\n }\n waitRef.current = null;\n // (A change of locale while this was asked has already called the start off, dropping this answer: see the\n // effect on `locale`. So it is the answer for the locale the panel is in.)\n const exchange = exchangeNow();\n const same =\n result.kind === \"available\" &&\n result.offer.consentVersion === wait.bound.consentVersion &&\n result.offer.botCheck === wait.bound.botCheck &&\n result.offer.questions === \"any\" &&\n exchange.kind === \"answer\" &&\n exchange.answerId === wait.bound.answerId &&\n bindingHolds(wait.bound, exchange);\n if (!same || result.kind !== \"available\") {\n applyAvailability(result, locale);\n return;\n }\n // The offer as it is now (the same version, bot check and questions; the session's length may have moved).\n launch({ ...offer, ...result.offer }, wait.bound.answerId, wait.module);\n });\n },\n [applyAvailability, bindingHolds, cancelWaiting, exchangeNow, launch],\n );\n\n /** The visitor's Stop, at any step from Start on (and Cancel, for a \"Start when ready\"). */\n const stop = useCallback(() => {\n const current = phaseRef.current;\n if (current.name === \"waiting\") {\n cancelWaiting(false);\n return;\n }\n if (current.name === \"bot-check\") {\n // Nothing was created: back to the consent card, if its answer is still offered.\n cancelStart(\"user\");\n go(reoffer(current.offer));\n return;\n }\n if (current.name === \"creating\") {\n cancelStart(\"user\");\n go({ name: \"ended\", how: \"stopped\" });\n return;\n }\n if (current.name === \"pending\" || current.name === \"live\") {\n finish(\"stopped\", \"user\");\n }\n }, [cancelStart, cancelWaiting, finish, go, reoffer]);\n\n /**\n * The view going out of the visitor's sight, by what took it away:\n *\n * - `user`: the panel closing, or the live avatar going off (the fallback takes the view's place, unmounting the\n * video and audio a room is attached to, and Stop with them). Everything under way ends, a session with `user`.\n * - `chat`: the open panel showing its Chat tab instead. Before the create is sent nothing paid exists, so it is\n * called off as `user` would (C3): a check is dropped (opening the view asks again), a \"Start when ready\" and a bot\n * check are called off with nothing created. From the create on (`creating`, `pending`, `live`) nothing ends: the\n * pane is only hidden, the room's video and audio stay attached, and the avatar speaks to its planned end.\n * - `hidden`: the page hidden (another browser tab, another app). A \"Start when ready\" is called off and a bot check\n * goes back to the consent card, so the view is as the visitor left it when they come back; a check is kept. From\n * the create on nothing ends, as for `chat`: the server ends the session at its planned end, so a hidden page adds\n * no paid time.\n * - `page_hide`: the page being left (`pagehide`). Everything ends, a session with `page_hide`; a check is kept.\n *\n * Out of sight with a session whose video has already arrived, it is counted as live (see `goLive`). What a session\n * kept out of sight may still end on is the attention rule's (`attend`), under `live.endUnattended`.\n */\n const leave = useCallback(\n (event: \"user\" | \"chat\" | \"hidden\" | \"page_hide\") => {\n const current = phaseRef.current;\n const reason: AvatarEndReason =\n event === \"user\" || event === \"chat\" ? \"user\" : \"page_hide\";\n const how: EndedHow = reason === \"user\" ? \"stopped\" : \"interrupted\";\n /** Once the create has been sent, only the panel closing, the live avatar going off and leaving the page end it. */\n const keepsSession = event === \"chat\" || event === \"hidden\";\n switch (current.name) {\n case \"checking\": {\n if (reason !== \"user\") return;\n const controller = checkRef.current;\n checkRef.current = null;\n controller?.abort();\n go(IDLE);\n return;\n }\n case \"waiting\":\n // A \"Start when ready\" is for this view as the visitor left it: called off, with nothing created.\n cancelWaiting(true);\n return;\n case \"bot-check\":\n cancelStart(reason);\n go(reason === \"user\" ? IDLE : reoffer(current.offer));\n return;\n case \"creating\":\n if (keepsSession) return;\n cancelStart(reason);\n go({ name: \"ended\", how });\n return;\n case \"pending\":\n case \"live\":\n if (keepsSession) {\n if (\n current.name === \"pending\" &&\n sessionRef.current?.speakerArrived\n ) {\n goLive();\n }\n return;\n }\n finish(how, reason);\n return;\n default:\n return;\n }\n },\n [cancelStart, cancelWaiting, finish, go, goLive, reoffer],\n );\n\n // The Avatar view showing, and hiding. Opening it asks again, except where this visit has already used the answer,\n // and except during a session, which shows as it is, counting down to its end.\n //\n // Hidden behind the Chat tab, a session under way keeps playing (`leave(\"chat\")`). Anything else that hides the view\n // (the panel closing, the live avatar going off) ends whatever is under way (`leave(\"user\")`): a bot check is called\n // off, a create in flight is ended once it answers, a session is ended and its room left. Coming back asks again.\n useEffect(() => {\n if (!showing) {\n leave(behindChat ? \"chat\" : \"user\");\n return;\n }\n const current = phaseRef.current;\n if (\n current.name === \"creating\" ||\n current.name === \"pending\" ||\n current.name === \"live\"\n ) {\n // Back during a session, after the Chat tab: nothing is asked again and nothing reset. The countdown is to the\n // session's end as `begin` set it, and is brought up to date at once rather than at its next tick.\n setNow(Date.now());\n return;\n }\n const offered = offeredNow();\n const used = offered !== null && claimedRef.current.has(offered);\n if (current.name === \"ended\" && used) return;\n if (\n current.name === \"refused\" &&\n current.reason === \"answer_claimed\" &&\n used\n ) {\n return;\n }\n if (\n current.name === \"idle\" ||\n current.name === \"inert\" ||\n current.name === \"refused\" ||\n current.name === \"needs-answer\" ||\n current.name === \"consent\" ||\n current.name === \"declined\" ||\n current.name === \"ended\" ||\n // Asking, with nothing actually asking: React's strict mode unmounts and mounts a component again with the state it\n // left, and the unmount in between dropped the question. (This view mounts already showing, the first time the\n // Avatar view opens.)\n (current.name === \"checking\" && checkRef.current === null)\n ) {\n check();\n }\n }, [showing, behindChat, check, leave, offeredNow]);\n\n // The attention rule (`attend`), each time the view comes into sight or goes out of it, once the effect above has\n // dealt with the move (the page's own sight is the visibility handler's, below).\n useEffect(() => {\n attend();\n }, [showing, attend]);\n\n // The panel's locale changing before Start: an availability answer, and the consent copy chosen for it, belong to the\n // locale they were asked about, so the view asks again (or, hidden, starts over when it next opens). A session already\n // under way keeps its own. A \"Start when ready\" is bound to its locale: it is called off, with nothing created (and\n // the availability question it may be asking again for the old locale is dropped with it), and the view asks again\n // for the new one.\n useEffect(() => {\n if (askedLocale.current === locale) return;\n askedLocale.current = locale;\n if (phaseRef.current.name === \"waiting\") cancelWaiting(true);\n const current = phaseRef.current.name;\n if (\n current !== \"checking\" &&\n current !== \"needs-answer\" &&\n current !== \"consent\" &&\n current !== \"declined\" &&\n current !== \"refused\" &&\n current !== \"inert\"\n ) {\n return;\n }\n if (active) {\n check();\n } else {\n checkRef.current?.abort();\n checkRef.current = null;\n go(IDLE);\n }\n }, [active, cancelWaiting, check, go, locale]);\n\n // The first answer arriving (it may complete while the Avatar view shows), or the conversation starting over.\n const kind = shown.kind;\n useEffect(() => {\n const current = phaseRef.current;\n if (current.name === \"needs-answer\" && answerId !== null) {\n go({ name: \"consent\", offer: current.offer, messageId: answerId });\n } else if (current.name === \"consent\" && current.messageId !== answerId) {\n go(\n answerId === null\n ? { name: \"needs-answer\", offer: current.offer }\n : { ...current, messageId: answerId },\n );\n } else if (current.name === \"declined\" && answerId === null) {\n // Not now, and then the conversation moved on (a new chat, say): nothing is declined any more.\n if (kind !== \"asking\") go({ name: \"needs-answer\", offer: current.offer });\n }\n }, [answerId, kind, go]);\n\n // A \"Start when ready\" while its answer is written: on every render, whatever changed (the conversation, its answer,\n // the page, the locale). It holds while the answer it is bound to is on its way; once that answer is ready and passes\n // the checks this browser can make, it is confirmed (`confirm`); anything else calls it off, with nothing created. A\n // failed or unreadable answer then says why itself; anything else says the start was called off.\n useEffect(() => {\n const current = phaseRef.current;\n const wait = waitRef.current;\n if (current.name !== \"waiting\" || wait === null || wait.check !== null) {\n return;\n }\n const now = exchangeNow();\n const holds = bindingHolds(wait.bound, now);\n if (\n holds &&\n now.kind === \"asking\" &&\n now.pendingAnswerId === wait.bound.answerId\n ) {\n return;\n }\n if (\n !holds ||\n now.kind !== \"answer\" ||\n now.answerId !== wait.bound.answerId\n ) {\n cancelWaiting(now.kind !== \"failed\" && now.kind !== \"text-only\");\n return;\n }\n confirm(current.offer, wait);\n });\n\n // A question asked here that Chat's Retry sent again is still the one asked here: the retry's question replaces it\n // (first the one shown while it is on its way, then the server's own, with the token the server may have just\n // minted; each names every id the question had). Declared before the two effects below, which run in the same commit\n // as the change it follows: the record moves to the new question (and its token) before they compare it.\n const resent = conversation?.resent ?? null;\n useEffect(() => {\n const asked = askedHereRef.current;\n if (\n resent === null ||\n asked === null ||\n !resent.replacedMessageIds.includes(asked.messageId)\n ) {\n return;\n }\n setAskedHere({\n messageId: resent.sent.userMessageId,\n token: resent.sent.conversationToken,\n });\n }, [resent, setAskedHere]);\n\n // The question this tab asked is the first of its chat only while that chat lasts: a conversation that empties (New\n // chat, in either tab) has no question asked here.\n const empty = (conversation?.messages.length ?? 0) === 0;\n useEffect(() => {\n if (empty) setAskedHere(null);\n }, [empty, setAskedHere]);\n // And it belongs to the conversation its send ended in, and no other: another token (a conversation opened from\n // History, say, whatever its first question says) ends it.\n useEffect(() => {\n const asked = askedHereRef.current;\n if (asked !== null && asked.token !== token) setAskedHere(null);\n }, [token, setAskedHere]);\n\n // This browser's note of a session today, read each time the view shows (never while rendering on a server), so a\n // page left open past midnight (UTC) has the new day's session.\n useEffect(() => {\n if (showing) setUsedToday(usedTodayHere());\n }, [showing]);\n\n // The answer stops being offered at `offerUntil`: one timer for that moment, set again for a new answer, and cleared\n // when the answer changes or the view goes. It re-renders the view, which then reads the answer as too old (and the\n // effect above moves a consent card to the start-over step). A timer that ran early, or a deadline past the longest\n // delay a timer keeps, is simply set again (`ageTick`).\n useEffect(() => {\n if (offerUntil === null) return;\n const timer = setTimeout(\n () => setAgeTick((tick) => tick + 1),\n Math.min(MAX_TIMER_MS, Math.max(0, offerUntil - Date.now())),\n );\n return () => clearTimeout(timer);\n }, [offerUntil, ageTick]);\n\n /** Start over: the chat's own New chat (the conversation's `reset`), then the Chat tab and its suggested questions. */\n const startNewChat = useCallback(() => {\n conversationRef.current?.reset();\n onContinueInChat();\n }, [onContinueInChat]);\n\n const onRoomEvent = useCallback(\n (handle: SessionHandle, event: ReceiveOnlyEvent) => {\n if (handle.done || sessionRef.current !== handle) return;\n const wasLive = phaseRef.current.name === \"live\";\n switch (event.type) {\n case \"speaker-track\":\n if (event.kind !== \"video\") {\n handle.voiceArrived = true;\n attend();\n return;\n }\n handle.speakerArrived = true;\n // Out of sight, the video's own `playing` may not come until the view shows again.\n if (!inSight()) goLive();\n return;\n case \"playback-blocked\":\n setBlocked(event.blocked);\n handle.soundHeld = event.sound ?? event.blocked;\n attend();\n return;\n case \"speech-ended\":\n // Under `endUnattended` only: the answer counts as played out once the worker's lag has had its time.\n if (\n latest.current.live.endUnattended !== true ||\n handle.tail !== null ||\n handle.playedOut\n ) {\n return;\n }\n handle.tail = setTimeout(() => {\n handle.tail = null;\n if (sessionRef.current !== handle || handle.done) return;\n handle.playedOut = true;\n attend();\n }, PLAYOUT_TAIL_MS);\n return;\n case \"speaker-left\":\n finish(\n wasLive ? \"finished\" : \"failed\",\n wasLive ? null : \"client_error\",\n );\n return;\n case \"disconnected\":\n if (event.byServer) finish(wasLive ? \"finished\" : \"failed\", null);\n else finish(wasLive ? \"interrupted\" : \"failed\", \"client_error\");\n return;\n }\n },\n [attend, finish, goLive, inSight],\n );\n\n // A created session: join its room once the video and audio elements are on the page.\n useEffect(() => {\n if (phase.name !== \"pending\") return;\n const handle = sessionRef.current;\n if (!handle || handle.room !== null || handle.done) return;\n const video = videoRef.current;\n const audio = audioRef.current;\n if (!video || !audio) {\n finish(\"failed\", \"client_error\");\n return;\n }\n let joining: Promise<ReceiveOnlySession>;\n try {\n joining = handle.module.joinReceiveOnly({\n url: handle.session.join.livekitUrl,\n token: handle.session.join.participantToken,\n workerIdentity: handle.session.join.workerIdentity,\n video,\n audio,\n onEvent: (event) => onRoomEvent(handle, event),\n });\n } catch (error) {\n joining = Promise.reject(error);\n }\n handle.room = joining.then(\n (room) => {\n if (handle.done) {\n void room.leave().catch(() => undefined);\n return null;\n }\n handle.joined = room;\n return room;\n },\n () => {\n if (!handle.done) finish(\"failed\", \"client_error\");\n return null;\n },\n );\n }, [phase.name, finish, onRoomEvent]);\n\n // While a session lasts: give up on a speaker who never comes, and leave a room still open after the session's end.\n useEffect(() => {\n if (phase.name !== \"pending\" && phase.name !== \"live\") return;\n const handle = sessionRef.current;\n if (!handle) return;\n const timers: Array<ReturnType<typeof setTimeout>> = [];\n if (phase.name === \"pending\") {\n timers.push(\n setTimeout(() => {\n if (sessionRef.current === handle && !handle.speakerArrived) {\n finish(\"failed\", \"client_error\");\n }\n }, SPEAKER_WAIT_MS),\n );\n }\n timers.push(\n setTimeout(\n () => {\n if (sessionRef.current !== handle) return;\n finish(\n phaseRef.current.name === \"live\" ? \"finished\" : \"failed\",\n \"client_error\",\n );\n },\n Math.max(0, handle.endsAt + END_GRACE_MS - Date.now()),\n ),\n );\n return () => timers.forEach((timer) => clearTimeout(timer));\n }, [phase.name, finish]);\n\n // The countdown: once a second while a session lasts.\n const ticking = phase.name === \"pending\" || phase.name === \"live\";\n useEffect(() => {\n if (!ticking) return;\n const timer = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(timer);\n }, [ticking]);\n\n // The avatar's voice is the page's from the create until the session ends: the panel is told its status line then,\n // and null otherwise (and when the view goes), and holds Chat's own read-aloud and dictation meanwhile.\n const voiceLine =\n phase.name === \"live\"\n ? S.speaking\n : phase.name === \"creating\" || phase.name === \"pending\"\n ? S.connecting\n : null;\n const onVoiceHoldRef = useRef(onVoiceHold);\n onVoiceHoldRef.current = onVoiceHold;\n useEffect(() => {\n onVoiceHoldRef.current?.(voiceLine);\n }, [voiceLine]);\n useEffect(() => () => onVoiceHoldRef.current?.(null), []);\n\n // Leaving the page ends a session. Hiding it (another browser tab, another app) calls off only what has not been sent\n // yet: a session keeps playing to its planned end, which the server keeps either way (see `leave`), unless the\n // attention rule ends it sooner (`attend`). The page showing again brings the countdown up to date at once: a hidden\n // page's timers may have been held back.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onPageHide = () => leave(\"page_hide\");\n const onVisibility = () => {\n if (document.visibilityState === \"hidden\") {\n leave(\"hidden\");\n attend();\n return;\n }\n const current = phaseRef.current.name;\n if (current === \"pending\" || current === \"live\") setNow(Date.now());\n attend();\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onVisibility);\n return () => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n };\n }, [attend, leave]);\n\n // Unmounted with something under way: end it, as closing the panel would.\n useEffect(\n () => () => {\n const controller = checkRef.current;\n checkRef.current = null;\n controller?.abort();\n const run = startRef.current;\n startRef.current = null;\n if (run) {\n run.cancelled = \"user\";\n run.turnstile?.cancel();\n }\n const wait = waitRef.current;\n waitRef.current = null;\n wait?.check?.abort();\n const handle = sessionRef.current;\n sessionRef.current = null;\n if (handle && !handle.done) {\n handle.done = true;\n stopAttending(handle);\n sendEnd({\n base: handle.base,\n headers: handle.headers,\n sessionId: handle.session.sessionId,\n secret: handle.session.endSecret,\n reason: \"user\",\n });\n if (handle.joined) void handle.joined.leave().catch(() => undefined);\n }\n },\n [],\n );\n\n const any = questions === \"any\";\n /**\n * Under `any`, the tab asks in text: the day's session is used (this browser's note of it, which a session that\n * played and has now ended leaves too), or the server says its limit is reached. The box then sends ordinary\n * questions, without `surface`, and their answers show here as text (after a session, under how it ended).\n */\n const textMode =\n any &&\n ((usedToday &&\n (phase.name === \"needs-answer\" ||\n phase.name === \"consent\" ||\n phase.name === \"declined\" ||\n phase.name === \"ended\")) ||\n (phase.name === \"refused\" && phase.reason === \"limits\"));\n // The box asks in text exactly where the tab shows the answers as text (see `ask`).\n textBoxRef.current = textMode;\n /** Under `any`: which of the Avatar tab's states shows, on the view's root (for tests and a site's own checks). */\n const askState = !any\n ? undefined\n : textMode\n ? \"text\"\n : phase.name === \"needs-answer\"\n ? kind === \"empty\"\n ? \"ready\"\n : kind\n : phase.name;\n\n /**\n * Not now. Under `any` the visitor stays on the tab, told the answer is in Chat (the card is offered again when the tab\n * next opens, while the answer is fresh); otherwise, as before, back to the Chat tab.\n */\n const notNow = useCallback(() => {\n const current = phaseRef.current;\n if (\n (current.name === \"consent\" || current.name === \"needs-answer\") &&\n current.offer.questions === \"any\"\n ) {\n go({ name: \"declined\", offer: current.offer });\n return;\n }\n onContinueInChat();\n }, [go, onContinueInChat]);\n\n /**\n * Ask `text` from the box (or a chip). For the avatar, it is the first question of a new chat, sent with `surface:\n * \"AVATAR\"`, so its answer is the one the card offers. It is remembered as asked here only once the chat's `send` says\n * it added it, bound to the USER message it added and the conversation it ended in; a send that added nothing (too\n * long a question, another question already on its way, a disabled chat) leaves nothing remembered, so the same words\n * asked later in Chat never get the card, and puts the question back in the box. In text (see `textMode`), an ordinary question, without `surface`, into the\n * chat as it is. Never resets the conversation: a chat that is not new is started over only by the visitor's own \"New\n * chat for the avatar\". One question at a time: a second press while the first is on its way sends nothing.\n */\n const ask = useCallback(\n (text: string) => {\n const conversation = conversationRef.current;\n const question = text.trim();\n if (conversation === null || question === \"\" || sendingRef.current) {\n return;\n }\n const spoken = !textBoxRef.current;\n if (spoken && conversation.messages.length > 0) return;\n sendingRef.current = true;\n // Whatever was remembered goes: only this ask's own send can put a question back.\n setAskedHere(null);\n const seq = askSeqRef.current;\n setNote(null);\n setDraft(\"\");\n void conversation\n .send(question, [], spoken ? { surface: \"AVATAR\" } : {})\n .then((added) => {\n // The chat added nothing (over its own length or turn limit, another question on its way, a disabled chat):\n // the question goes back into the box, unless the visitor has typed something else since, so it is never\n // silently lost.\n if (added === null) {\n setDraft((current) => (current === \"\" ? question : current));\n }\n if (\n !spoken ||\n added === null ||\n askSeqRef.current !== seq ||\n added.conversationToken !==\n (conversationRef.current?.getConversationToken() ?? null)\n ) {\n return;\n }\n setAskedHere({\n messageId: added.userMessageId,\n token: added.conversationToken,\n });\n })\n .finally(() => {\n sendingRef.current = false;\n });\n },\n [setAskedHere],\n );\n\n /**\n * \"New chat for the avatar\": the visitor's own start over, where this conversation can no longer be read. The chat's\n * New chat (the conversation's `reset`, so the chat being left stays in History), staying on the Avatar tab, whose\n * box then asks for the avatar. A failed question goes back into the box, if the box is empty.\n */\n const newChatForAvatar = useCallback(() => {\n const conversation = conversationRef.current;\n if (conversation === null) return;\n const now = exchangeNow();\n const failedQuestion =\n now.kind === \"failed\" ? (now.question?.content ?? null) : null;\n conversation.reset();\n setAskedHere(null);\n setNote(\"new-chat\");\n if (failedQuestion !== null) {\n setDraft((current) => (current === \"\" ? failedQuestion : current));\n }\n const current = phaseRef.current;\n if (\n current.name === \"needs-answer\" ||\n current.name === \"consent\" ||\n current.name === \"declined\"\n ) {\n go({ name: \"needs-answer\", offer: current.offer });\n } else {\n // From a refusal or a session's end: ask again whether the avatar is offered, for the new chat.\n check();\n }\n }, [check, exchangeNow, go, setAskedHere]);\n\n // Each step's own control takes focus when the one the visitor was on has gone (Start, once pressed, say): focus\n // left on the page's body would also take Escape out of the panel. \"Tap to turn on sound\" is one of those controls:\n // it goes the moment playback resumes (`blocked` clears), so focus moves on to Stop rather than falling to the body.\n useEffect(() => {\n if (!active) return;\n const focused = document.activeElement;\n if (focused && focused !== document.body && focused.isConnected) return;\n rootRef.current?.querySelector<HTMLElement>(PRIMARY)?.focus();\n // (The card's arrival while the answer is written is a step of its own here: its Start when ready takes focus from\n // the box the question was asked from, which has gone.)\n }, [active, phase.name, askState, shown.pendingAnswerId, blocked]);\n\n // The avatar's video plays: the session is live (`goLive`).\n const onPlaying = goLive;\n\n const enablePlayback = useCallback(() => {\n // Called straight from the tap: browsers allow sound only from inside the visitor's gesture.\n void sessionRef.current?.joined?.enablePlayback().catch(() => undefined);\n }, []);\n\n if (off || phase.name === \"inert\") {\n return (\n // `display: contents`: the earlier Avatar view's picture, line and button lay out in the pane exactly as before.\n <div\n ref={rootRef}\n style={{ display: \"contents\" }}\n data-boff-explore=\"avatar-live\"\n data-phase={off ? \"off\" : \"inert\"}\n >\n {fallback}\n </div>\n );\n }\n\n const primaryButton =\n \"inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background motion-reduce:transition-none\";\n const secondaryButton =\n \"inline-flex items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background motion-reduce:transition-none\";\n const stillPicture = (small: boolean) => (\n <img\n src={still.src}\n alt={still.alt}\n decoding=\"async\"\n width={small ? 64 : 128}\n height={small ? 64 : 128}\n className={cn(\n \"shrink-0 rounded-full border border-border object-cover shadow-sm\",\n small\n ? \"h-16 w-16\"\n : any\n ? \"h-[min(12rem,32dvh)] w-[min(12rem,32dvh)]\"\n : \"h-32 w-32\",\n )}\n />\n );\n const continueButton = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-continue\"\n className={primaryButton}\n onClick={onContinueInChat}\n >\n {continueInChat}\n </button>\n );\n /** Where this conversation can never be read: New chat first, and Continue in Chat beside it. */\n const startOverActions = (\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-new-chat\"\n className={primaryButton}\n onClick={startNewChat}\n >\n {newChat}\n </button>\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-continue\"\n className={secondaryButton}\n onClick={onContinueInChat}\n >\n {continueInChat}\n </button>\n </div>\n );\n const stopButton = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-stop\"\n className={secondaryButton}\n onClick={stop}\n >\n {S.stop}\n </button>\n );\n /** Under `any`: to the Chat tab, where the answer and its sources are. */\n const readInChatButton = (primary: boolean) => (\n <button\n type=\"button\"\n data-avatar-primary={primary ? \"\" : undefined}\n data-boff-explore=\"avatar-live-read-in-chat\"\n className={primary ? primaryButton : secondaryButton}\n onClick={onContinueInChat}\n >\n {S.readInChat}\n </button>\n );\n /** The consent card: exactly its four lines and the privacy link (the notice's digest is taken over them). */\n const consentCard = (copy: AvatarConsentCopy) => (\n <section\n aria-labelledby={consentTitleId}\n data-boff-explore=\"avatar-live-consent\"\n className=\"w-full max-w-sm rounded-lg border border-border p-4 text-start\"\n >\n <h2 id={consentTitleId} className=\"text-base font-semibold\">\n {copy.title}\n </h2>\n <p className=\"mt-2 text-sm\">\n {productName === null || copy.introProduct === null\n ? copy.intro\n : fill(copy.introProduct, { product: productName })}\n </p>\n <p className=\"mt-2 text-sm text-muted-foreground\">{copy.processing}</p>\n <p className=\"mt-2 text-sm text-muted-foreground\">{copy.storage}</p>\n <a\n href={PRIVACY_HREF}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-boff-explore=\"avatar-live-privacy\"\n className=\"mt-2 inline-block text-sm font-medium text-primary underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {copy.privacyLink}\n <span className=\"sr-only\"> {S.opensInNewTab}</span>\n </a>\n </section>\n );\n /** The card's buttons: Start (or, while the answer is written, Start when ready) and Not now. */\n const consentActions = (whenReady: boolean) => (\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore={\n whenReady ? \"avatar-live-start-when-ready\" : \"avatar-live-start\"\n }\n className={primaryButton}\n onClick={whenReady ? startWhenReady : start}\n >\n {whenReady ? S.startWhenReady : S.start}\n </button>\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-not-now\"\n className={secondaryButton}\n onClick={notNow}\n >\n {S.notNow}\n </button>\n </div>\n );\n const liveMedia = (playing: boolean) => (\n <div\n className={cn(\n \"relative shrink-0 overflow-hidden rounded-xl border border-border bg-muted\",\n any ? \"h-[min(12rem,32dvh)] w-[min(12rem,32dvh)]\" : \"h-48 w-48\",\n )}\n >\n <video\n ref={videoRef}\n aria-label={S.video}\n data-boff-explore=\"avatar-live-video\"\n playsInline\n autoPlay\n muted\n onPlaying={onPlaying}\n className={cn(\"h-full w-full object-cover\", !playing && \"opacity-0\")}\n />\n {playing ? null : (\n <img\n src={still.src}\n alt=\"\"\n decoding=\"async\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n )}\n {/* Under `any`, the audio element is the view's own, so that Start's tap can let it play (see `unlockSound`). */}\n {any ? null : (\n <audio ref={audioRef} data-boff-explore=\"avatar-live-audio\" />\n )}\n </div>\n );\n const liveBody = (session: ShownSession) => (\n <>\n <section\n aria-label={S.captions}\n data-boff-explore=\"avatar-live-captions\"\n lang={session.captions.locale || undefined}\n dir=\"auto\"\n tabIndex={0}\n className=\"max-h-32 w-full max-w-sm overflow-y-auto rounded-lg bg-muted p-3 text-start text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {session.captions.text}\n </section>\n <p className=\"text-xs text-muted-foreground\">{S.answerInChat}</p>\n <p className=\"text-sm tabular-nums text-muted-foreground\">\n {S.timeLeft}{\" \"}\n <span role=\"timer\" data-boff-explore=\"avatar-live-countdown\">\n {clock(Math.max(0, (session.endsAt - now) / 1000))}\n </span>\n </p>\n </>\n );\n /** A session's buttons: the sound, where the browser holds it back, Stop, and the way back to the chat. */\n const liveActions = (back: ReactNode) => (\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n {blocked ? (\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-sound\"\n className={primaryButton}\n onClick={enablePlayback}\n >\n {S.tapForSound}\n </button>\n ) : null}\n {stopButton}\n {back}\n </div>\n );\n const badge = (\n <p\n data-boff-explore=\"avatar-live-badge\"\n className=\"rounded-full bg-muted px-3 py-1 text-xs font-medium text-foreground\"\n >\n {S.badge}\n </p>\n );\n\n if (any) {\n // The Avatar tab with its own question box: a stage that scrolls (the picture or the video, the status, the card or\n // the captions, the question) over a foot that stays (the chips, the box and the line under it).\n let status = \"\";\n let outcome = false;\n let lead: ReactNode = null;\n let top: ReactNode = null;\n let media: ReactNode = stillPicture(false);\n let body: ReactNode = null;\n let actions: ReactNode = null;\n let newChatOffer = false;\n let box: \"spoken\" | \"text\" | null = null;\n const first = exchange.question;\n const questionLine =\n first === null ? null : (\n <p\n data-boff-explore=\"avatar-live-question\"\n dir=\"auto\"\n className=\"line-clamp-2 w-full max-w-sm break-words text-sm font-medium\"\n >\n {first.content}\n </p>\n );\n const activity = conversation?.activity ?? null;\n const activityLine =\n activity === null ? null : (\n <p\n data-boff-explore=\"avatar-live-activity\"\n className=\"text-xs text-muted-foreground\"\n >\n {activity}\n </p>\n );\n\n if (textMode) {\n // The day's session is used (or the server says its limit is reached): the box asks ordinary questions, and the\n // answer shows here as text.\n const messages = conversation?.messages ?? [];\n let questionAt = messages.length - 1;\n while (questionAt >= 0 && messages[questionAt]?.role !== \"USER\") {\n questionAt -= 1;\n }\n const lastQuestion = questionAt === -1 ? undefined : messages[questionAt];\n // Only that question's own answer, the message right after it: the chat adds the question at once and its answer\n // only once the server takes it (and none when the send fails), so an earlier answer is never shown under it.\n const after = questionAt === -1 ? undefined : messages[questionAt + 1];\n const lastAnswer = after?.role === \"ASSISTANT\" ? after : undefined;\n const chatPhase = conversation?.phase;\n /** The question has no answer yet: on its way, failed (the chat's error is the send's), or neither. */\n const unanswered =\n lastQuestion === undefined || lastAnswer !== undefined\n ? null\n : chatPhase === \"sending\" || chatPhase === \"streaming\"\n ? \"waiting\"\n : chatPhase === \"error\" || chatPhase === \"limited\"\n ? \"failed\"\n : null;\n if (phase.name === \"refused\") {\n status = S[REFUSAL_TEXT[phase.reason]];\n outcome = true;\n } else if (phase.name === \"ended\") {\n // After the day's session: how it ended stays said, over the last question and its answer.\n status = S[phase.how];\n outcome = true;\n }\n body = (\n <>\n {lastQuestion === undefined ? null : (\n <p\n data-boff-explore=\"avatar-live-question\"\n dir=\"auto\"\n className=\"line-clamp-2 w-full max-w-sm break-words text-sm font-medium\"\n >\n {lastQuestion.content}\n </p>\n )}\n {lastAnswer === undefined ? (\n unanswered === \"waiting\" ? (\n <p className=\"text-xs text-muted-foreground\">\n {activity ?? S.gettingAnswer}\n </p>\n ) : unanswered === \"failed\" ? (\n <p className=\"text-sm text-muted-foreground\">{S.answerFailed}</p>\n ) : null\n ) : lastAnswer.status === \"PENDING\" ||\n lastAnswer.status === \"RUNNING\" ? (\n <p className=\"text-xs text-muted-foreground\">\n {activity ?? S.gettingAnswer}\n </p>\n ) : lastAnswer.status === \"FAILED\" ? (\n <p className=\"text-sm text-muted-foreground\">{S.answerFailed}</p>\n ) : (\n <p\n data-boff-explore=\"avatar-live-text-answer\"\n dir=\"auto\"\n className=\"line-clamp-6 w-full max-w-sm whitespace-pre-wrap break-words text-start text-sm\"\n >\n {lastAnswer.content}\n </p>\n )}\n </>\n );\n // After a session, \"Read the answer and sources in Chat\" stays the step's own control, as it was before the box\n // asked anything (focus moves there from Stop).\n const ended = phase.name === \"ended\";\n // A send that failed before any answer came is retried in Chat, so the way there is offered for it too.\n actions =\n lastAnswer === undefined && unanswered !== \"failed\" && !ended\n ? null\n : readInChatButton(ended);\n box = \"text\";\n } else {\n switch (phase.name) {\n case \"checking\":\n status = S.checking;\n break;\n case \"needs-answer\":\n switch (shown.kind) {\n case \"empty\":\n status = note === \"new-chat\" ? S.newChatStarted : \"\";\n lead = <p className=\"text-base font-semibold\">{S.askHeadline}</p>;\n box = \"spoken\";\n break;\n case \"asking\":\n case \"answer\": {\n // The card shows while the answer is written, for a question asked here as the first of a new chat, once\n // the server has taken it.\n const card = shown.askedHere && shown.pendingAnswerId !== null;\n status =\n note === \"cancelled\" ? S.armedCancelled : S.gettingAnswer;\n if (card) media = stillPicture(true);\n body = (\n <>\n {questionLine}\n {activityLine}\n {card ? consentCard(phase.offer.copy) : null}\n </>\n );\n actions = card ? consentActions(true) : null;\n break;\n }\n case \"text-only\":\n status = S.notSpoken;\n outcome = true;\n body = questionLine;\n actions = readInChatButton(false);\n newChatOffer = true;\n break;\n case \"failed\":\n status = S.answerFailed;\n outcome = true;\n body = questionLine;\n newChatOffer = true;\n break;\n case \"ask-here\":\n status = S.askHere;\n outcome = true;\n actions = readInChatButton(false);\n newChatOffer = true;\n break;\n default:\n status = S.startNewChat;\n outcome = true;\n body = (\n <p className=\"text-sm text-muted-foreground\">\n {S.startNewChatDetailAny}\n </p>\n );\n actions = readInChatButton(false);\n newChatOffer = true;\n break;\n }\n break;\n case \"consent\":\n media = stillPicture(true);\n body = (\n <>\n {questionLine}\n {consentCard(phase.offer.copy)}\n </>\n );\n actions = consentActions(false);\n break;\n case \"declined\":\n status = S.declined;\n actions = readInChatButton(true);\n break;\n case \"waiting\":\n status = S.armed;\n body = questionLine;\n actions = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-cancel\"\n className={secondaryButton}\n onClick={stop}\n >\n {S.cancel}\n </button>\n );\n break;\n case \"refused\":\n outcome = true;\n if (\n phase.reason === \"not_eligible\" ||\n phase.reason === \"answer_claimed\"\n ) {\n // This chat's answer will not be read: a new chat for the avatar can be.\n status =\n phase.reason === \"not_eligible\"\n ? S.notEligibleAny\n : S.answerClaimed;\n actions = readInChatButton(false);\n newChatOffer = true;\n } else {\n status = S[REFUSAL_TEXT[phase.reason]];\n actions = continueButton;\n }\n break;\n case \"bot-check\":\n status = S.botCheck;\n actions = stopButton;\n break;\n case \"creating\":\n status = S.connecting;\n actions = stopButton;\n break;\n case \"pending\":\n case \"live\":\n status = phase.name === \"live\" ? S.speaking : S.connecting;\n top = badge;\n media = liveMedia(phase.name === \"live\");\n body = liveBody(phase.session);\n actions = liveActions(readInChatButton(false));\n break;\n case \"ended\":\n status = S[phase.how];\n outcome = true;\n actions = readInChatButton(true);\n // A session that never played leaves no note of the day's: a new chat for the avatar can still be. (One that\n // played is in text mode, above.)\n newChatOffer = true;\n break;\n default:\n break;\n }\n }\n\n const reason = inFlight(conversation)\n ? S.askBusy\n : conversation?.canSend\n ? null\n : S.askUnavailable;\n const chips =\n box !== null && shown.kind === \"empty\" && prompts.length > 0 ? (\n <div className=\"flex flex-col gap-1\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n {tryAsking}\n </p>\n <div className=\"flex max-h-28 flex-wrap gap-2 overflow-y-auto\">\n {prompts.map((prompt) => (\n <button\n key={prompt}\n type=\"button\"\n data-boff-explore=\"avatar-live-chip\"\n aria-disabled={reason !== null ? \"true\" : undefined}\n className=\"min-h-11 rounded-full border border-border bg-background px-3 py-2 text-start text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:transition-none\"\n onClick={() => {\n if (reason === null) ask(prompt);\n }}\n >\n {prompt}\n </button>\n ))}\n </div>\n </div>\n ) : null;\n const foot =\n box === null && !newChatOffer ? null : (\n <div\n data-boff-explore=\"avatar-live-foot\"\n className=\"flex shrink-0 flex-col gap-2 border-t border-border bg-background p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]\"\n >\n {newChatOffer ? (\n <div className=\"flex flex-col items-center gap-1 text-center\">\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-new-chat-avatar\"\n className={cn(primaryButton, \"min-h-11\")}\n onClick={newChatForAvatar}\n >\n {S.newChatForAvatar}\n </button>\n <p className=\"text-xs text-muted-foreground\">{S.newChatNote}</p>\n </div>\n ) : null}\n {chips}\n {box !== null && usedToday ? (\n <p\n data-boff-explore=\"avatar-live-used-today\"\n className=\"text-xs text-muted-foreground\"\n >\n {S.usedToday}\n </p>\n ) : null}\n {box === null ? null : (\n <AskBox\n value={draft}\n maxLength={askMaxLength}\n onChange={setDraft}\n onAsk={ask}\n reason={reason}\n label={S.askLabel}\n placeholder={S.askPlaceholder}\n send={send}\n footer={S.askFooter}\n noFiles={S.askNoFiles}\n hint={box === \"spoken\" ? S.needsAnswerAny : null}\n touchFirst={touchFirst}\n />\n )}\n </div>\n );\n\n return (\n <div\n ref={rootRef}\n data-boff-explore=\"avatar-live\"\n data-phase={phase.name}\n data-ask={askState}\n className=\"absolute inset-0 flex flex-col bg-background\"\n >\n <div className=\"flex min-h-0 flex-1 flex-col items-center gap-4 overflow-y-auto p-6 text-center\">\n {top}\n {media}\n {lead}\n <p\n role=\"status\"\n data-boff-explore=\"avatar-live-status\"\n className={\n outcome\n ? \"text-base font-semibold\"\n : \"text-sm text-muted-foreground\"\n }\n >\n {status}\n </p>\n {body}\n <div ref={botBoxRef} data-boff-explore=\"avatar-live-bot-check\" />\n {actions}\n </div>\n {foot}\n <audio ref={audioRef} data-boff-explore=\"avatar-live-audio\" />\n </div>\n );\n }\n\n // The headline of each step, in the one polite status region: announced as it changes, the countdown never.\n const headline: Record<Phase[\"name\"], string> = {\n idle: \"\",\n checking: S.checking,\n inert: \"\",\n // A question asked and its answer on its way: the answer is coming (the avatar is offered once it completes).\n \"needs-answer\": startOver\n ? S.startNewChat\n : shown.kind === \"asking\"\n ? S.gettingAnswer\n : S.needsAnswer,\n consent: \"\",\n declined: S.declined,\n waiting: S.armed,\n refused: phase.name === \"refused\" ? S[REFUSAL_TEXT[phase.reason]] : \"\",\n \"bot-check\": S.botCheck,\n creating: S.connecting,\n pending: S.connecting,\n live: S.speaking,\n ended: phase.name === \"ended\" ? S[phase.how] : \"\",\n };\n const outcome =\n phase.name === \"needs-answer\" ||\n phase.name === \"refused\" ||\n phase.name === \"ended\";\n\n let top: ReactNode = null;\n let media: ReactNode = stillPicture(false);\n let body: ReactNode = null;\n let actions: ReactNode = null;\n\n switch (phase.name) {\n case \"needs-answer\":\n // Nothing to read yet (choose a suggested question), or never in this conversation (start a new chat).\n body = (\n <p className=\"text-sm text-muted-foreground\">\n {startOver ? S.startNewChatDetail : S.needsAnswerDetail}\n </p>\n );\n actions = startOver ? startOverActions : continueButton;\n break;\n case \"consent\":\n media = stillPicture(true);\n body = consentCard(phase.offer.copy);\n actions = consentActions(false);\n break;\n case \"refused\":\n // An answer the service will not read (not one of the suggested questions, or too old by its clock): only a new\n // chat can be.\n actions =\n phase.reason === \"not_eligible\" ? startOverActions : continueButton;\n break;\n case \"bot-check\":\n case \"creating\":\n actions = stopButton;\n break;\n case \"pending\":\n case \"live\":\n top = badge;\n media = liveMedia(phase.name === \"live\");\n body = liveBody(phase.session);\n actions = liveActions(\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-continue\"\n className={secondaryButton}\n onClick={onContinueInChat}\n >\n {continueInChat}\n </button>,\n );\n break;\n case \"ended\":\n body = <p className=\"text-sm text-muted-foreground\">{S.answerInChat}</p>;\n actions = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-back\"\n className={primaryButton}\n onClick={onContinueInChat}\n >\n {S.backToChat}\n </button>\n );\n break;\n default:\n break;\n }\n\n // The same slots in every step, so the status region and the bot check's box stay the same elements throughout.\n return (\n <div\n ref={rootRef}\n data-boff-explore=\"avatar-live\"\n data-phase={phase.name}\n className=\"flex max-h-full w-full flex-col items-center gap-4 overflow-y-auto\"\n >\n {top}\n {media}\n <p\n role=\"status\"\n data-boff-explore=\"avatar-live-status\"\n className={\n outcome ? \"text-base font-semibold\" : \"text-sm text-muted-foreground\"\n }\n >\n {headline[phase.name]}\n </p>\n {body}\n <div ref={botBoxRef} data-boff-explore=\"avatar-live-bot-check\" />\n {actions}\n </div>\n );\n}\n\ninterface AskBoxProps {\n value: string;\n /** The longest question the box takes: {@link ASK_MAX_LENGTH}, or the chat's own limit where that is shorter. */\n maxLength: number;\n onChange: (value: string) => void;\n /** Ask `question`. Called only with text, and only while {@link AskBoxProps.reason} is null. */\n onAsk: (question: string) => void;\n /** Why Send cannot be pressed now (an answer on its way, a chat that cannot ask), or null when it can. */\n reason: string | null;\n label: string;\n placeholder: string;\n send: string;\n /** The line under the box, always shown with it. */\n footer: string;\n /** Said when a file is pasted or dropped on the box. */\n noFiles: string;\n /** What the box is for, read with it by a screen reader; null for nothing more than its name. */\n hint: string | null;\n touchFirst: boolean;\n}\n\n/**\n * The Avatar tab's own question box. Its text is the view's (never the chat's draft); it takes text only, up to\n * {@link AskBoxProps.maxLength} characters. Send is never `disabled` (a disabled control cannot be focused or explained): it is\n * `aria-disabled`, described by why. Enter asks and Shift+Enter breaks the line; while an input method is composing,\n * Enter is the input method's, and so is Escape, which then does not reach the panel. 44 px controls.\n */\nfunction AskBox({\n value,\n maxLength,\n onChange,\n onAsk,\n reason,\n label,\n placeholder,\n send,\n footer,\n noFiles,\n hint,\n touchFirst,\n}: AskBoxProps) {\n const uid = useId();\n const reasonId = `${uid}-reason`;\n const hintId = `${uid}-hint`;\n const footerId = `${uid}-footer`;\n const [refusedFiles, setRefusedFiles] = useState(false);\n const empty = value.trim() === \"\";\n\n const submit = () => {\n if (reason !== null || empty) return;\n onAsk(value);\n };\n const onKeyDown = (event: ReactKeyboardEvent<HTMLTextAreaElement>) => {\n if (event.nativeEvent.isComposing || event.keyCode === 229) {\n if (event.key === \"Escape\") event.stopPropagation();\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n }\n };\n // Files are the chat's: one pasted or dropped here is refused, with a word on where to attach it.\n const onPaste = (event: ReactClipboardEvent<HTMLTextAreaElement>) => {\n if (event.clipboardData.files.length === 0) return;\n event.preventDefault();\n setRefusedFiles(true);\n };\n const onDrop = (event: ReactDragEvent<HTMLTextAreaElement>) => {\n if (!Array.from(event.dataTransfer.types).includes(\"Files\")) return;\n event.preventDefault();\n setRefusedFiles(true);\n };\n\n return (\n <form\n data-boff-explore=\"avatar-live-ask\"\n className=\"flex w-full flex-col gap-1\"\n onSubmit={(event) => {\n event.preventDefault();\n submit();\n }}\n >\n <div className=\"flex items-end gap-2\">\n <textarea\n value={value}\n rows={1}\n maxLength={maxLength}\n aria-label={label}\n aria-describedby={hint === null ? footerId : `${hintId} ${footerId}`}\n placeholder={placeholder}\n dir=\"auto\"\n data-avatar-primary={touchFirst ? undefined : \"\"}\n data-boff-explore=\"avatar-live-ask-input\"\n className=\"max-h-32 min-h-11 flex-1 resize-none rounded-md border border-border bg-background px-3 py-2.5 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring sm:text-sm\"\n onChange={(event) => {\n setRefusedFiles(false);\n onChange(event.target.value);\n }}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n onDrop={onDrop}\n />\n <button\n type=\"submit\"\n aria-disabled={reason !== null || empty ? \"true\" : undefined}\n aria-describedby={reason !== null ? reasonId : undefined}\n data-avatar-primary={touchFirst ? \"\" : undefined}\n data-boff-explore=\"avatar-live-ask-send\"\n className=\"inline-flex h-11 min-w-11 shrink-0 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:transition-none\"\n >\n {send}\n </button>\n </div>\n {reason === null ? null : (\n <p\n id={reasonId}\n data-boff-explore=\"avatar-live-ask-reason\"\n className=\"text-xs text-muted-foreground\"\n >\n {reason}\n </p>\n )}\n {refusedFiles ? (\n <p\n data-boff-explore=\"avatar-live-ask-files\"\n className=\"text-xs text-muted-foreground\"\n >\n {noFiles}\n </p>\n ) : null}\n {hint === null ? null : (\n <p id={hintId} className=\"sr-only\">\n {hint}\n </p>\n )}\n <p id={footerId} className=\"text-xs text-muted-foreground\">\n {footer}\n </p>\n </form>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/components/explore-avatar-api.ts","../../src/components/explore-avatar-i18n.ts","../../src/components/explore-avatar-turnstile.ts","../../src/components/explore-avatar-live-view.tsx"],"names":["INERT","locale","live","base","headers","off","shown","body","exchange","token","now","conversation","current","outcome","top","media","actions"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * BOFF-9797. The website live avatar's three requests, as a visitor's browser makes them.\n *\n * They go to the global gateway's web branch, under the SDK's configured gateway (`/api/web-avatar/v1/*` on its\n * origin), and follow the website avatar web API, v1:\n *\n * GET /availability?site=…&locale=… when the Avatar tab opens, never on page load\n * POST /sessions after the visitor's consent (and the bot check, where the server runs one)\n * POST /sessions/{id}/end Stop, leaving the tab, closing the panel, hiding the page\n *\n * - **Never with credentials** (`credentials: 'omit'`): a website visitor has no account, no cookie and no workspace\n * here.\n * - **The bot check's token** goes in the `x-web-avatar-bot-token` header, on create only, and only when the server\n * checks for bots: availability says whether it does (`botCheck`, contract v1.2). The gateway verifies it and drops\n * it; the body is exactly the contract's six fields. The check itself is bound to that body (contract v1.1): see\n * {@link avatarBotBinding}. A server that runs no bot check gets no header at all.\n * - **The end is a simple request** (see {@link sendEnd}): no `Content-Type` of our own, so a page being hidden has no\n * CORS preflight to wait for.\n * - **Every answer is read into one of a few outcomes** the Avatar tab can show. A missing route, a forbidden one, a\n * refused origin and a network failure are all `inert`: the tab shows what it showed before there was a live\n * avatar. Nothing a server says is shown as it was said.\n * - Nothing here logs. The conversation token goes into the create body and nowhere else, and the session's secret\n * only into the end body.\n */\n\nimport { isAvatarSite, isAvatarVersion } from \"./explore-avatar-live-config\";\n\n// The few helpers the panel itself needs (where the requests go, and the shapes a config may take) live in\n// `explore-avatar-live-config.ts`, so that they do not drag this file into every site's bundle; they are re-exported\n// here, where the rest of the contract's grammar is.\nexport {\n AVATAR_WEB_API_PATH,\n avatarApiBase,\n isAvatarSite,\n isAvatarVersion,\n} from \"./explore-avatar-live-config\";\n\n/** How long the Avatar tab waits to hear whether the live avatar is offered. */\nconst AVAILABILITY_TIMEOUT_MS = 8_000;\n/** How long a create may take: past the gateway's own deadline for it, so the gateway's answer is what decides. */\nconst CREATE_TIMEOUT_MS = 30_000;\n\n/** The refusals the Avatar tab explains, each in a short sentence of its own. */\nexport type AvatarRefusal =\n | \"busy\"\n | \"limits\"\n | \"region\"\n | \"locale\"\n | \"paused\"\n | \"not_eligible\"\n | \"answer_claimed\";\n\n/** Why the browser ends a session. Analytics only: the secret is what ends it. */\nexport type AvatarEndReason = \"user\" | \"page_hide\" | \"client_error\";\n\n/**\n * Whether the server checks for bots when a session is created: `turnstile` (a Cloudflare Turnstile token is required on\n * create) or `off` (none is; the server's own caps decide). A server older than contract v1.2 names no mode and always\n * checks, so it is read as `turnstile`.\n */\nexport type AvatarBotCheck = \"off\" | \"turnstile\";\n\n/**\n * Which first questions the server reads the answer to (contract v1.3, BOFF-9797): `suggested` (only the exact\n * suggested questions of the site's manifest) or `any` (a question the visitor typed too). A server older than v1.3\n * names none and reads suggested questions only, so it is read as `suggested`. The Avatar tab offers its own question\n * box only under `any`, and only with consent copy written for it.\n */\nexport type AvatarQuestions = \"any\" | \"suggested\";\n\n/** What an `ok` availability offers. */\nexport interface AvatarOffer {\n /** The consent version the visitor must agree to: the panel shows only copy written for exactly this version. */\n consentVersion: string;\n /** The longest a session can last, in seconds. */\n maxSessionSeconds: number;\n /** Whether a bot check runs before the create request. */\n botCheck: AvatarBotCheck;\n /** Which first questions the server reads the answer to. */\n questions: AvatarQuestions;\n}\n\nexport type AvatarAvailability =\n | { kind: \"available\"; offer: AvatarOffer }\n /**\n * `questions` is the server's (contract v1.3 reports it with every answer): under `any` a `limits` refusal leaves the\n * Avatar tab's box asking in text. Read leniently here, since a refusal offers nothing: anything but `any` is\n * `suggested`.\n */\n | { kind: \"refused\"; reason: AvatarRefusal; questions: AvatarQuestions }\n /** Not offered here, or not reachable: the Avatar tab stays as it was before the live avatar. */\n | { kind: \"inert\" };\n\n/** A created session: what the browser needs to watch it and to end it. */\nexport interface AvatarSession {\n sessionId: string;\n /** Returned once; ends this session and nothing else. Kept out of the page's markup. */\n endSecret: string;\n /** When the server ends the session, in epoch milliseconds. */\n endsAt: number;\n join: {\n livekitUrl: string;\n /** Subscribe-only and short-lived. Kept out of the page's markup. */\n participantToken: string;\n workerIdentity: string;\n };\n captions: { locale: string; text: string };\n /**\n * The server speaks only a whole-sentence first part of the answer, labelled as such, because the whole answer does\n * not fit the session (contract v1.4, Stage B: only under the server's `AVATAR_WEB_SIZE_BY_AUDIO`). The full answer\n * stays in Chat. False when the 201 says false, says nothing (an older server, or the setting off) or says anything\n * but `true`: the field is additive, so a value it cannot read never makes a session unusable.\n */\n excerpt: boolean;\n}\n\nexport type AvatarCreateResult =\n | { kind: \"created\"; session: AvatarSession }\n /** A session was created, but its answer cannot be used: the browser ends it at once. */\n | { kind: \"unusable\"; sessionId: string; endSecret: string }\n | { kind: \"refused\"; reason: AvatarRefusal }\n /** The consent version moved on since availability: ask again, and show the consent that is current. */\n | { kind: \"consent\" }\n | { kind: \"inert\" }\n | { kind: \"failed\" };\n\n/** The create body: exactly these six fields, in the contract's order. */\nexport interface AvatarCreateBody {\n site: string;\n locale: string;\n conversationToken: string;\n messageId: string;\n consentVersion: string;\n manifestVersion: string;\n}\n\nconst MESSAGE_ID = /^[A-Za-z0-9_-]{1,64}$/;\nconst CONVERSATION_TOKEN = /^[A-Za-z0-9._~+/=-]{16,512}$/;\nconst LOCALE = /^[A-Za-z0-9-]{1,16}$/;\nconst SESSION_ID = /^avs_[0-9a-f]{32}$/;\nconst END_SECRET = /^[A-Za-z0-9_-]{43}$/;\n\nconst INERT = { kind: \"inert\" } as const;\nconst FAILED = { kind: \"failed\" } as const;\n\n/** An answer id the contract accepts. */\nexport function isAvatarMessageId(value: string): boolean {\n return MESSAGE_ID.test(value);\n}\n\n/** A conversation token the contract accepts. */\nexport function isAvatarConversationToken(value: string): boolean {\n return CONVERSATION_TOKEN.test(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/** What each availability `reason` other than `ok` means for the Avatar tab. A reason not listed is inert. */\nconst AVAILABILITY_REASONS: ReadonlyMap<string, AvatarRefusal | \"inert\"> =\n new Map<string, AvatarRefusal | \"inert\">([\n [\"site\", \"inert\"],\n [\"unavailable\", \"inert\"],\n [\"region\", \"region\"],\n [\"locale\", \"locale\"],\n [\"paused\", \"paused\"],\n [\"busy\", \"busy\"],\n [\"limits\", \"limits\"],\n ]);\n\nconst BOT_CHECK_MODES: ReadonlySet<string> = new Set<AvatarBotCheck>([\n \"off\",\n \"turnstile\",\n]);\n\n/**\n * An `ok` answer's `botCheck` (contract v1.2): exactly `{\"mode\":\"off\"}` or `{\"mode\":\"turnstile\"}`. Absent, from a\n * server older than v1.2: `turnstile`, as that server always checks. Anything else (an unknown mode, another field, a\n * value of another type) is null: the browser cannot tell what the server will require, so it offers nothing.\n */\nfunction readBotCheck(value: unknown): AvatarBotCheck | null {\n if (value === undefined) return \"turnstile\";\n if (!isRecord(value)) return null;\n const keys = Object.keys(value);\n const { mode } = value;\n if (\n keys.length !== 1 ||\n keys[0] !== \"mode\" ||\n typeof mode !== \"string\" ||\n !BOT_CHECK_MODES.has(mode)\n ) {\n return null;\n }\n return mode === \"off\" ? \"off\" : \"turnstile\";\n}\n\nconst QUESTION_MODES: ReadonlySet<string> = new Set<AvatarQuestions>([\n \"any\",\n \"suggested\",\n]);\n\n/**\n * An `ok` answer's `questions` (contract v1.3): exactly `\"any\"` or `\"suggested\"`. Absent, from a server older than v1.3:\n * `suggested`, which is all that server reads. Anything else is null: the browser cannot tell which questions the\n * server will read, so it offers nothing.\n */\nfunction readQuestions(value: unknown): AvatarQuestions | null {\n if (value === undefined) return \"suggested\";\n if (typeof value !== \"string\" || !QUESTION_MODES.has(value)) return null;\n return value === \"any\" ? \"any\" : \"suggested\";\n}\n\n/**\n * Read an availability answer: its HTTP status and its parsed JSON body (or null). Only an `ok` answer's `botCheck` is\n * read, and only an `ok` answer's `questions` strictly: a refusal offers nothing for them to change.\n */\nexport function readAvailability(\n status: number,\n body: unknown,\n): AvatarAvailability {\n if (status !== 200 || !isRecord(body)) return INERT;\n const { available, reason } = body;\n if (typeof available !== \"boolean\" || typeof reason !== \"string\") {\n return INERT;\n }\n if (reason === \"ok\") {\n const { consentVersion, maxSessionSeconds } = body;\n const botCheck = readBotCheck(body.botCheck);\n const questions = readQuestions(body.questions);\n if (\n available !== true ||\n typeof consentVersion !== \"string\" ||\n !isAvatarVersion(consentVersion) ||\n typeof maxSessionSeconds !== \"number\" ||\n !Number.isInteger(maxSessionSeconds) ||\n maxSessionSeconds < 1 ||\n botCheck === null ||\n questions === null\n ) {\n return INERT;\n }\n return {\n kind: \"available\",\n offer: { consentVersion, maxSessionSeconds, botCheck, questions },\n };\n }\n const meaning = available ? undefined : AVAILABILITY_REASONS.get(reason);\n return meaning === undefined || meaning === \"inert\"\n ? INERT\n : {\n kind: \"refused\",\n reason: meaning,\n questions: body.questions === \"any\" ? \"any\" : \"suggested\",\n };\n}\n\n/** The create error codes the Avatar tab explains. */\nconst CREATE_REFUSALS: ReadonlyMap<string, AvatarRefusal> = new Map<\n string,\n AvatarRefusal\n>([\n [\"busy\", \"busy\"],\n [\"limits\", \"limits\"],\n [\"region\", \"region\"],\n [\"locale\", \"locale\"],\n [\"paused\", \"paused\"],\n [\"not_eligible\", \"not_eligible\"],\n [\"answer_claimed\", \"answer_claimed\"],\n]);\n\nfunction errorCode(body: unknown): string | null {\n if (!isRecord(body) || !isRecord(body.error)) return null;\n const { code } = body.error;\n return typeof code === \"string\" ? code : null;\n}\n\nfunction readCreated(body: unknown): AvatarCreateResult {\n if (!isRecord(body)) return FAILED;\n const { sessionId, endSecret } = body;\n if (\n typeof sessionId !== \"string\" ||\n !SESSION_ID.test(sessionId) ||\n typeof endSecret !== \"string\" ||\n !END_SECRET.test(endSecret)\n ) {\n return FAILED;\n }\n const unusable = { kind: \"unusable\", sessionId, endSecret } as const;\n const { state, join, captions } = body;\n const endsAt =\n typeof body.endsAt === \"string\" ? Date.parse(body.endsAt) : NaN;\n if (\n state !== \"pending\" ||\n !Number.isFinite(endsAt) ||\n !isRecord(join) ||\n !isRecord(captions)\n ) {\n return unusable;\n }\n const { livekitUrl, participantToken, workerIdentity } = join;\n const { locale, text } = captions;\n if (\n typeof livekitUrl !== \"string\" ||\n !livekitUrl.startsWith(\"wss://\") ||\n typeof participantToken !== \"string\" ||\n participantToken === \"\" ||\n typeof workerIdentity !== \"string\" ||\n workerIdentity === \"\" ||\n typeof locale !== \"string\" ||\n typeof text !== \"string\"\n ) {\n return unusable;\n }\n return {\n kind: \"created\",\n session: {\n sessionId,\n endSecret,\n endsAt,\n join: { livekitUrl, participantToken, workerIdentity },\n captions: { locale, text },\n excerpt: body.excerpt === true,\n },\n };\n}\n\n/**\n * Read a create answer: its HTTP status and its parsed JSON body (or null).\n *\n * - 201: the session, or `unusable` when its fields cannot be used (the browser then ends it).\n * - `busy`, `limits`, `region`, `locale`, `paused`, `not_eligible`, `answer_claimed`: a refusal the tab explains.\n * - `consent`: the consent version moved on.\n * - Any other 401, 403, 404 or 405 (`untrusted_caller`, `bot_check`, `site`, `invalid_route`, `method_not_allowed`):\n * inert, as if there were no live avatar here.\n * - Anything else (`invalid_request`, `conflict`, `idempotency_mismatch`, `unavailable`, a gateway error page):\n * failed.\n */\nexport function readCreate(status: number, body: unknown): AvatarCreateResult {\n if (status === 201) return readCreated(body);\n const code = errorCode(body);\n if (code !== null) {\n const refusal = CREATE_REFUSALS.get(code);\n if (refusal !== undefined) return { kind: \"refused\", reason: refusal };\n if (code === \"consent\") return { kind: \"consent\" };\n }\n if (status === 401 || status === 403 || status === 404 || status === 405) {\n return INERT;\n }\n return FAILED;\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n try {\n return (await response.json()) as unknown;\n } catch {\n return null;\n }\n}\n\n/** An abort signal for `timeoutMs`, also aborted with `outer`; `done` clears its timer. */\nfunction deadline(\n timeoutMs: number,\n outer?: AbortSignal,\n): { signal: AbortSignal; done: () => void } {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const onOuter = () => controller.abort();\n if (outer?.aborted) controller.abort();\n else outer?.addEventListener(\"abort\", onOuter, { once: true });\n return {\n signal: controller.signal,\n done: () => {\n clearTimeout(timer);\n outer?.removeEventListener(\"abort\", onOuter);\n },\n };\n}\n\nexport interface AvatarRequestTarget {\n /** {@link avatarApiBase} of the SDK's gateway. */\n base: string;\n /** Headers every request carries: the alpha gateway's access headers, and nothing on production. */\n headers: Readonly<Record<string, string>>;\n}\n\n/** Ask whether the live avatar is offered for `site` in `locale`. Never throws: a failure is `inert`. */\nexport async function requestAvailability(\n target: AvatarRequestTarget & {\n site: string;\n locale: string;\n signal?: AbortSignal;\n },\n): Promise<AvatarAvailability> {\n if (!isAvatarSite(target.site) || !LOCALE.test(target.locale)) return INERT;\n const query = new URLSearchParams({\n site: target.site,\n locale: target.locale,\n });\n const timer = deadline(AVAILABILITY_TIMEOUT_MS, target.signal);\n try {\n const response = await fetch(`${target.base}/availability?${query}`, {\n method: \"GET\",\n credentials: \"omit\",\n cache: \"no-store\",\n headers: { ...target.headers },\n signal: timer.signal,\n });\n return readAvailability(response.status, await readJson(response));\n } catch {\n return INERT;\n } finally {\n timer.done();\n }\n}\n\n/**\n * Create a session. `botToken` is the bot check's token, for the gateway alone, and is sent only when there is one: a\n * server that runs no bot check gets no `x-web-avatar-bot-token` header. Never throws: a network failure is `inert`, an\n * answer that cannot be read is `failed`.\n */\nexport async function requestCreate(\n target: AvatarRequestTarget & {\n body: AvatarCreateBody;\n idempotencyKey: string;\n botToken?: string;\n },\n): Promise<AvatarCreateResult> {\n const { body } = target;\n // Exactly the contract's six fields, in its order: nothing else of the page's goes along.\n const payload = JSON.stringify({\n site: body.site,\n locale: body.locale,\n conversationToken: body.conversationToken,\n messageId: body.messageId,\n consentVersion: body.consentVersion,\n manifestVersion: body.manifestVersion,\n });\n const timer = deadline(CREATE_TIMEOUT_MS);\n try {\n const response = await fetch(`${target.base}/sessions`, {\n method: \"POST\",\n credentials: \"omit\",\n cache: \"no-store\",\n headers: {\n ...target.headers,\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": target.idempotencyKey,\n ...(target.botToken === undefined\n ? {}\n : { \"x-web-avatar-bot-token\": target.botToken }),\n },\n body: payload,\n signal: timer.signal,\n });\n return readCreate(response.status, await readJson(response));\n } catch {\n return INERT;\n } finally {\n timer.done();\n }\n}\n\n/**\n * Ask the server to end a session, without waiting for it: a `keepalive` request, sent in this same tick, so it still\n * goes when the page is being hidden or unloaded. The server ends the session on its own deadlines whether or not this\n * arrives.\n *\n * **A simple CORS request.** The body is a plain string and this sets no `Content-Type`, so the browser sends it as\n * `text/plain;charset=UTF-8`: a type the gateway's end route reads as JSON for exactly this reason. The session id is\n * in the URL, so a preflight could never be answered from the browser's cache, and one that has to complete while the\n * page unloads may never finish. On production nothing else is added, so no preflight is made. (On the alpha gateway\n * hosts the Access headers in `target.headers` are custom headers, which do bring a preflight there: see the README.)\n */\nexport function sendEnd(\n target: AvatarRequestTarget & {\n sessionId: string;\n secret: string;\n reason: AvatarEndReason;\n },\n): void {\n try {\n void fetch(\n `${target.base}/sessions/${encodeURIComponent(target.sessionId)}/end`,\n {\n method: \"POST\",\n keepalive: true,\n credentials: \"omit\",\n cache: \"no-store\",\n headers: { ...target.headers },\n body: JSON.stringify({ secret: target.secret, reason: target.reason }),\n },\n ).catch(() => undefined);\n } catch {\n // No fetch at all: the server's own deadlines end the session.\n }\n}\n\n/** What scopes the bot check's binding to this contract, and its version. */\nconst BOT_BINDING_PREFIX = \"boff-web-avatar-cdata/v1\";\n\n/** The browser's WebCrypto `subtle`, or null where it has none to offer (a page that is not a secure context). */\nfunction webCryptoSubtle(): SubtleCrypto | null {\n const subtle = globalThis.crypto?.subtle;\n return typeof subtle?.digest === \"function\" ? subtle : null;\n}\n\n/**\n * Whether this browser can make the bot check's binding ({@link avatarBotBinding}): it needs WebCrypto's SHA-256.\n * Without it no live avatar can start here, so a start asks first, before it loads anything for one.\n */\nexport function canBindBotCheck(): boolean {\n return webCryptoSubtle() !== null;\n}\n\nfunction base64UrlNoPad(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\n/**\n * The value the bot check is bound to, for Turnstile's `cData` (web API contract v1.1, additive):\n *\n * base64url_nopad( SHA-256( UTF-8( \"boff-web-avatar-cdata/v1\\n\" + site + \"\\n\" + locale + \"\\n\"\n * + conversationToken + \"\\n\" + messageId ) ) )\n *\n * The gateway recomputes it from the create body and checks it against the one Cloudflare returns with the verified\n * token, so a token minted for one request cannot be used for another. It must be made from the very values the create\n * body will carry, and before the widget is rendered: the caller builds the body once and hands the same one to this\n * and to {@link requestCreate}.\n *\n * Rejects where the browser has no WebCrypto (a page that is not a secure context): the bot check cannot be bound\n * there, so the live avatar does not start. {@link canBindBotCheck} says so beforehand, so that nothing is loaded for\n * a start that cannot happen.\n */\nexport async function avatarBotBinding(\n values: Pick<\n AvatarCreateBody,\n \"site\" | \"locale\" | \"conversationToken\" | \"messageId\"\n >,\n): Promise<string> {\n const subtle = webCryptoSubtle();\n if (subtle === null) {\n throw new Error(\"The bot check cannot be bound here: no WebCrypto.\");\n }\n const text = [\n BOT_BINDING_PREFIX,\n values.site,\n values.locale,\n values.conversationToken,\n values.messageId,\n ].join(\"\\n\");\n const digest = await subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return base64UrlNoPad(new Uint8Array(digest));\n}\n\n/** A random UUID v4 for `Idempotency-Key`, or null where the browser has no cryptographic random source. */\nexport function newIdempotencyKey(): string | null {\n const crypto = globalThis.crypto;\n if (typeof crypto?.randomUUID === \"function\") return crypto.randomUUID();\n if (typeof crypto?.getRandomValues !== \"function\") return null;\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\",\n );\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n","/**\n * BOFF-9797. The words of the live avatar's Avatar tab, in the six product locales, bundled like the rest of\n * Explore's copy (see `explore-i18n.ts` for why a marketing site bundles its strings).\n *\n * ## Review\n *\n * English is the reviewed copy. The other five locales are drafts awaiting translation review: each is a complete\n * object (a missing key is a type error), but the live avatar runs only in a locale that\n * {@link isAvatarLiveLocaleReviewed} lists. In any other, the Avatar tab stays as it was before the live avatar and\n * asks the server nothing. A locale is added there (in `explore-avatar-live-config.ts`) once its strings, and its\n * consent copy, have been reviewed.\n *\n * ## Consent\n *\n * The consent card's copy is versioned: the server names the version it will accept (`consentVersion`), and the panel\n * shows a consent card only when it holds copy written for exactly that version in the visitor's locale\n * ({@link avatarConsentCopy}). A version the SDK does not know, or a locale without reviewed copy for it, offers no\n * consent card at all, so a visitor never agrees to words other than the ones the server records. Each version also says\n * which bot check its words describe ({@link AvatarConsentCopy.botCheck}), and the card is shown only where the server\n * runs that one.\n */\n\nimport { isAvatarLiveLocaleReviewed } from \"./explore-avatar-live-config\";\n\nimport type { AvatarBotCheck, AvatarQuestions } from \"./explore-avatar-api\";\nimport type { ExploreLocale } from \"./explore-i18n\";\n\n// The reviewed locales are decided in `explore-avatar-live-config.ts`, which the panel reads without loading this file.\nexport { isAvatarLiveLocaleReviewed };\n\nexport interface AvatarLiveStrings {\n /** Status while the tab asks whether the live avatar is offered. Announced politely. */\n checking: string;\n /** No answer to read yet. */\n needsAnswer: string;\n needsAnswerDetail: string;\n /**\n * The conversation can never be read: its first answer failed, it has gone past the first question and answer, or\n * the answer is too old. Only a new chat can. The headline (announced politely), then the explanation, then a New\n * chat button. The avatar service reads exactly one answer: the first, completed, to a suggested question, within\n * fifteen minutes.\n */\n startNewChat: string;\n startNewChatDetail: string;\n /** The consent card's buttons. */\n start: string;\n notNow: string;\n /** After the privacy link, for screen readers: it opens in a new tab. */\n opensInNewTab: string;\n /** Status while the bot check runs. Announced politely. */\n botCheck: string;\n /** Status while the session is created and the room joined. Announced politely. */\n connecting: string;\n /** Status once the avatar's video plays. Announced politely. */\n speaking: string;\n /** Shown over the live video, always: the visitor is watching an AI, not a person. */\n badge: string;\n /** The video's accessible name. */\n video: string;\n /** The captions' accessible name. */\n captions: string;\n /** Before the countdown, which is never announced. */\n timeLeft: string;\n stop: string;\n /** Where the browser holds sound back until a tap (Safari, iOS). */\n tapForSound: string;\n /**\n * How a session ended. Announced politely. `finished` is \"the server closed the room, or the session's time ran out\n * with the room still open\": the browser cannot tell the avatar reading to the end from a server-side stop or a\n * hand-over, so it says only that the live avatar has ended.\n */\n finished: string;\n stopped: string;\n failed: string;\n interrupted: string;\n /** Under the captions and after a session: the answer itself is still in the conversation. */\n answerInChat: string;\n /**\n * In the status line while the avatar speaks, in place of `speaking`, when the server speaks only the first part of\n * the answer because the whole of it does not fit the session (the 201's `excerpt`, contract v1.4, Stage B).\n */\n excerpt: string;\n backToChat: string;\n /**\n * The refusals, one short sentence each, with no numbers in them (a number is spelled out). `notEligible` is the one\n * with a second sentence: it comes with a New chat button, and says what to do with it.\n */\n busy: string;\n limits: string;\n region: string;\n locale: string;\n paused: string;\n notEligible: string;\n answerClaimed: string;\n /**\n * The Avatar tab's own question box (BOFF-9797, contract v1.3): shown only where the server reads the answer to a\n * question the visitor typed too (`questions: \"any\"`), with consent copy written for that. The headline over the\n * suggested questions, the box's accessible name, its placeholder and the line under it, always visible with the box.\n */\n askHeadline: string;\n askLabel: string;\n askPlaceholder: string;\n askFooter: string;\n /** A file pasted or dropped on the box: the box takes text only. */\n askNoFiles: string;\n /** Why Send cannot be pressed: an answer is on its way, or the chat cannot take a question. */\n askBusy: string;\n askUnavailable: string;\n /** While the answer is written, when the chat reports no progress line of its own. Announced politely. */\n gettingAnswer: string;\n /**\n * The consent card's button while the answer is still being written: pressed, the avatar starts once the answer is\n * ready (`armed`), unless the visitor presses `cancel` or the start is called off (`armedCancelled`: the tab left,\n * the page hidden, the chat or the page changed, and the like).\n */\n startWhenReady: string;\n armed: string;\n cancel: string;\n armedCancelled: string;\n /** A first answer the avatar does not read (it fails the speech checks this browser can make): it stays in Chat. */\n notSpoken: string;\n /** The first answer failed. */\n answerFailed: string;\n /** Not now, under `any`: the card is offered again, while the answer is fresh, when the tab opens again. */\n declined: string;\n /** An answer to a question that was not the first of a new chat asked in this tab. */\n askHere: string;\n /**\n * Where the conversation can no longer be read: the button that starts a new chat for the avatar (the chat's own New\n * chat, staying on the Avatar tab), the note beside it, and the line once it has.\n */\n newChatForAvatar: string;\n newChatNote: string;\n newChatStarted: string;\n /** The button to the Chat tab, where the answer and its sources are. */\n readInChat: string;\n /** Over the box on the day this browser has had a live session. No number: the limits are the server's. */\n usedToday: string;\n /**\n * Under `any`, in place of `needsAnswer` (the box's description), `startNewChatDetail` and `notEligible`, which\n * speak of suggested questions only.\n */\n needsAnswerAny: string;\n startNewChatDetailAny: string;\n notEligibleAny: string;\n}\n\nconst EN: AvatarLiveStrings = {\n checking: \"Checking whether the live avatar is available…\",\n needsAnswer: \"Choose a suggested question in Chat first.\",\n needsAnswerDetail: \"The avatar can read only the first answer aloud.\",\n startNewChat: \"Start a new chat to use the avatar.\",\n startNewChatDetail:\n \"The avatar reads aloud only the first answer in a chat, to a suggested question, within fifteen minutes. Start a new chat and choose a suggested question.\",\n start: \"Start live avatar\",\n notNow: \"Not now\",\n opensInNewTab: \"(opens in a new tab)\",\n botCheck: \"Checking your browser…\",\n connecting: \"Connecting to the live avatar…\",\n speaking: \"The avatar is speaking.\",\n badge: \"AI avatar · not a real person\",\n video: \"Live AI avatar video\",\n captions: \"Captions\",\n timeLeft: \"Time left\",\n stop: \"Stop\",\n tapForSound: \"Tap to turn on sound\",\n finished: \"The live avatar has ended.\",\n stopped: \"You stopped the avatar.\",\n failed: \"The live avatar couldn't start.\",\n interrupted: \"The live avatar stopped early.\",\n answerInChat: \"The full answer is in Chat.\",\n excerpt:\n \"The avatar reads the first part of this answer. The full answer is in Chat.\",\n backToChat: \"Back to Chat\",\n busy: \"The live avatar is busy right now. Please try again in a few minutes.\",\n limits:\n \"The live avatar has reached its limit for now. Please try again later.\",\n region: \"The live avatar isn't offered in your region yet.\",\n locale: \"The live avatar isn't offered in this language yet.\",\n paused: \"The live avatar is paused right now.\",\n notEligible:\n \"The avatar reads the first answer to a suggested question, within fifteen minutes. Start a new chat and choose a suggested question.\",\n answerClaimed: \"The avatar has already read this answer.\",\n askHeadline: \"Ask a question, and the avatar reads the answer aloud.\",\n askLabel: \"Question for the avatar\",\n askPlaceholder: \"Ask the avatar…\",\n askFooter:\n \"Answers are AI-generated and can be wrong. Don't include personal details.\",\n askNoFiles: \"To attach files, use Chat.\",\n askBusy: \"You can ask when the current answer is ready.\",\n askUnavailable: \"Chat isn't available right now.\",\n gettingAnswer: \"Getting the answer…\",\n startWhenReady: \"Start when ready\",\n armed: \"The avatar will start when the answer is ready.\",\n cancel: \"Cancel\",\n armedCancelled:\n \"The avatar didn't start. Press Start when ready to try again.\",\n notSpoken:\n \"This answer stays in Chat as text. The avatar reads only answers that pass its speech checks.\",\n answerFailed: \"The assistant couldn't answer. Try asking again.\",\n declined: \"No problem. The answer is in Chat.\",\n askHere: \"To hear an answer, ask it here.\",\n newChatForAvatar: \"New chat for the avatar\",\n newChatNote: \"Your current chat stays in History.\",\n newChatStarted: \"Started a new chat for the avatar.\",\n readInChat: \"Read the answer and sources in Chat\",\n usedToday:\n \"You've had today's avatar session. Answers will show here as text.\",\n needsAnswerAny: \"Ask a question here, and the avatar reads the answer aloud.\",\n startNewChatDetailAny:\n \"The avatar reads aloud only the first answer in a new chat started in the Avatar tab, provided it passes the speech checks.\",\n notEligibleAny:\n \"The avatar can't read this answer aloud. The answer and sources are in Chat.\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"zh\" is in REVIEWED.\nconst ZH: AvatarLiveStrings = {\n checking: \"正在检查实时虚拟形象是否可用…\",\n needsAnswer: \"请先在聊天中选择一个推荐问题。\",\n needsAnswerDetail: \"虚拟形象只能朗读第一个回答。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"请开始新的聊天,再使用虚拟形象。\",\n startNewChatDetail:\n \"虚拟形象只朗读一次聊天中的第一个回答,且仅限推荐问题的回答、在十五分钟内。请开始新的聊天,并选择一个推荐问题。\",\n start: \"启动实时虚拟形象\",\n notNow: \"暂不\",\n opensInNewTab: \"(在新标签页中打开)\",\n botCheck: \"正在检查您的浏览器…\",\n connecting: \"正在连接实时虚拟形象…\",\n speaking: \"虚拟形象正在讲话。\",\n badge: \"AI 虚拟形象 · 不是真人\",\n video: \"实时 AI 虚拟形象视频\",\n captions: \"字幕\",\n timeLeft: \"剩余时间\",\n stop: \"停止\",\n tapForSound: \"点按以开启声音\",\n finished: \"实时虚拟形象已结束。\",\n stopped: \"您已停止虚拟形象。\",\n failed: \"实时虚拟形象无法启动。\",\n interrupted: \"实时虚拟形象提前停止了。\",\n answerInChat: \"完整回答在聊天中。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).\n excerpt: \"虚拟形象朗读这个回答的第一部分。完整回答在聊天中。\",\n backToChat: \"返回聊天\",\n busy: \"实时虚拟形象目前繁忙,请几分钟后再试。\",\n limits: \"实时虚拟形象暂时已达到使用上限,请稍后再试。\",\n region: \"您所在的地区暂不提供实时虚拟形象。\",\n locale: \"此语言暂不提供实时虚拟形象。\",\n paused: \"实时虚拟形象目前已暂停。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"虚拟形象只朗读推荐问题的第一个回答,且须在十五分钟内。请开始新的聊天,并选择一个推荐问题。\",\n answerClaimed: \"虚拟形象已经朗读过这个回答。\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"提出问题,虚拟形象会朗读回答。\",\n askLabel: \"向虚拟形象提的问题\",\n askPlaceholder: \"向虚拟形象提问…\",\n askFooter: \"回答由 AI 生成,可能有误。请勿包含个人信息。\",\n askNoFiles: \"如需附加文件,请使用聊天。\",\n askBusy: \"当前回答准备好后即可提问。\",\n askUnavailable: \"聊天目前不可用。\",\n gettingAnswer: \"正在获取回答…\",\n startWhenReady: \"准备好后开始\",\n armed: \"回答准备好后,虚拟形象将开始。\",\n cancel: \"取消\",\n armedCancelled: \"虚拟形象未启动。可再次按“准备好后开始”。\",\n notSpoken:\n \"此回答以文字形式保留在聊天中。虚拟形象只朗读通过其语音检查的回答。\",\n answerFailed: \"助手无法回答。请重新提问。\",\n declined: \"没关系。回答在聊天中。\",\n askHere: \"如需听取回答,请在这里提问。\",\n newChatForAvatar: \"为虚拟形象开始新聊天\",\n newChatNote: \"当前聊天会保留在历史记录中。\",\n newChatStarted: \"已为虚拟形象开始新的聊天。\",\n readInChat: \"在聊天中查看回答和来源\",\n usedToday: \"您今天已使用过虚拟形象。回答将以文字显示在这里。\",\n needsAnswerAny: \"在这里提问,虚拟形象会朗读回答。\",\n startNewChatDetailAny:\n \"虚拟形象只朗读在“虚拟形象”标签页中开始的新聊天的第一个回答,且该回答须通过语音检查。\",\n notEligibleAny: \"虚拟形象无法朗读此回答。回答和来源在聊天中。\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"hi\" is in REVIEWED.\nconst HI: AvatarLiveStrings = {\n checking: \"जाँच हो रही है कि लाइव अवतार उपलब्ध है या नहीं…\",\n needsAnswer: \"पहले चैट में कोई सुझाया गया प्रश्न चुनें।\",\n needsAnswerDetail: \"अवतार केवल पहला उत्तर ज़ोर से पढ़ सकता है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"अवतार का उपयोग करने के लिए नई चैट शुरू करें।\",\n startNewChatDetail:\n \"अवतार किसी चैट का केवल पहला उत्तर ज़ोर से पढ़ता है, वह भी सुझाए गए प्रश्न का और पंद्रह मिनट के भीतर। नई चैट शुरू करें और कोई सुझाया गया प्रश्न चुनें।\",\n start: \"लाइव अवतार शुरू करें\",\n notNow: \"अभी नहीं\",\n opensInNewTab: \"(नए टैब में खुलता है)\",\n botCheck: \"आपके ब्राउज़र की जाँच हो रही है…\",\n connecting: \"लाइव अवतार से जुड़ रहे हैं…\",\n speaking: \"अवतार बोल रहा है।\",\n badge: \"AI अवतार · असली व्यक्ति नहीं\",\n video: \"लाइव AI अवतार वीडियो\",\n captions: \"कैप्शन\",\n timeLeft: \"बचा हुआ समय\",\n stop: \"रोकें\",\n tapForSound: \"आवाज़ चालू करने के लिए टैप करें\",\n finished: \"लाइव अवतार समाप्त हो गया है।\",\n stopped: \"आपने अवतार को रोक दिया।\",\n failed: \"लाइव अवतार शुरू नहीं हो सका।\",\n interrupted: \"लाइव अवतार बीच में ही रुक गया।\",\n answerInChat: \"पूरा उत्तर चैट में है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).\n excerpt: \"अवतार इस उत्तर का पहला भाग पढ़ता है। पूरा उत्तर चैट में है।\",\n backToChat: \"चैट पर वापस जाएँ\",\n busy: \"लाइव अवतार अभी व्यस्त है। कृपया कुछ मिनट बाद फिर कोशिश करें।\",\n limits:\n \"लाइव अवतार अभी अपनी सीमा तक पहुँच गया है। कृपया बाद में फिर कोशिश करें।\",\n region: \"आपके क्षेत्र में लाइव अवतार अभी उपलब्ध नहीं है।\",\n locale: \"इस भाषा में लाइव अवतार अभी उपलब्ध नहीं है।\",\n paused: \"लाइव अवतार अभी रुका हुआ है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"अवतार सुझाए गए प्रश्न का पहला उत्तर ही पढ़ता है, पंद्रह मिनट के भीतर। नई चैट शुरू करें और कोई सुझाया गया प्रश्न चुनें।\",\n answerClaimed: \"अवतार यह उत्तर पहले ही पढ़ चुका है।\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"कोई प्रश्न पूछें, और अवतार उसका उत्तर ज़ोर से पढ़ेगा।\",\n askLabel: \"अवतार के लिए प्रश्न\",\n askPlaceholder: \"अवतार से पूछें…\",\n askFooter:\n \"उत्तर AI द्वारा बनाए जाते हैं और गलत हो सकते हैं। निजी जानकारी शामिल न करें।\",\n askNoFiles: \"फ़ाइलें जोड़ने के लिए चैट का उपयोग करें।\",\n askBusy: \"मौजूदा उत्तर तैयार होने पर आप पूछ सकते हैं।\",\n askUnavailable: \"चैट अभी उपलब्ध नहीं है।\",\n gettingAnswer: \"उत्तर लाया जा रहा है…\",\n startWhenReady: \"तैयार होने पर शुरू करें\",\n armed: \"उत्तर तैयार होते ही अवतार शुरू होगा।\",\n cancel: \"रद्द करें\",\n armedCancelled:\n \"अवतार शुरू नहीं हुआ। फिर से कोशिश करने के लिए “तैयार होने पर शुरू करें” दबाएँ।\",\n notSpoken:\n \"यह उत्तर चैट में टेक्स्ट के रूप में रहेगा। अवतार केवल वही उत्तर पढ़ता है जो उसकी वाणी जाँच में पास होते हैं।\",\n answerFailed: \"सहायक उत्तर नहीं दे सका। फिर से पूछकर देखें।\",\n declined: \"कोई बात नहीं। उत्तर चैट में है।\",\n askHere: \"उत्तर सुनने के लिए, यहाँ पूछें।\",\n newChatForAvatar: \"अवतार के लिए नई चैट\",\n newChatNote: \"आपकी मौजूदा चैट इतिहास में रहेगी।\",\n newChatStarted: \"अवतार के लिए नई चैट शुरू की गई।\",\n readInChat: \"उत्तर और स्रोत चैट में पढ़ें\",\n usedToday:\n \"आज का अवतार सत्र आप ले चुके हैं। उत्तर यहाँ टेक्स्ट के रूप में दिखेंगे।\",\n needsAnswerAny: \"यहाँ प्रश्न पूछें, और अवतार उत्तर ज़ोर से पढ़ेगा।\",\n startNewChatDetailAny:\n \"अवतार केवल अवतार टैब में शुरू की गई नई चैट का पहला उत्तर ज़ोर से पढ़ता है, बशर्ते वह वाणी जाँच में पास हो।\",\n notEligibleAny:\n \"अवतार यह उत्तर ज़ोर से नहीं पढ़ सकता। उत्तर और स्रोत चैट में हैं।\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"es\" is in REVIEWED.\nconst ES: AvatarLiveStrings = {\n checking: \"Comprobando si el avatar en vivo está disponible…\",\n needsAnswer: \"Primero elige una pregunta sugerida en el chat.\",\n needsAnswerDetail:\n \"El avatar solo puede leer en voz alta la primera respuesta.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"Inicia un chat nuevo para usar el avatar.\",\n startNewChatDetail:\n \"El avatar solo lee en voz alta la primera respuesta de un chat, si es la de una pregunta sugerida y en un plazo de quince minutos. Inicia un chat nuevo y elige una pregunta sugerida.\",\n start: \"Iniciar el avatar en vivo\",\n notNow: \"Ahora no\",\n opensInNewTab: \"(se abre en una pestaña nueva)\",\n botCheck: \"Comprobando tu navegador…\",\n connecting: \"Conectando con el avatar en vivo…\",\n speaking: \"El avatar está hablando.\",\n badge: \"Avatar de IA · no es una persona real\",\n video: \"Vídeo del avatar de IA en vivo\",\n captions: \"Subtítulos\",\n timeLeft: \"Tiempo restante\",\n stop: \"Detener\",\n tapForSound: \"Toca para activar el sonido\",\n finished: \"El avatar en vivo ha terminado.\",\n stopped: \"Has detenido el avatar.\",\n failed: \"No se pudo iniciar el avatar en vivo.\",\n interrupted: \"El avatar en vivo se detuvo antes de tiempo.\",\n answerInChat: \"La respuesta completa está en el chat.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).\n excerpt:\n \"El avatar lee la primera parte de esta respuesta. La respuesta completa está en el chat.\",\n backToChat: \"Volver al chat\",\n busy: \"El avatar en vivo está ocupado en este momento. Vuelve a intentarlo en unos minutos.\",\n limits:\n \"El avatar en vivo ha alcanzado su límite por ahora. Vuelve a intentarlo más tarde.\",\n region: \"El avatar en vivo aún no está disponible en tu región.\",\n locale: \"El avatar en vivo aún no está disponible en este idioma.\",\n paused: \"El avatar en vivo está en pausa en este momento.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"El avatar lee la primera respuesta a una pregunta sugerida, en un plazo de quince minutos. Inicia un chat nuevo y elige una pregunta sugerida.\",\n answerClaimed: \"El avatar ya ha leído esta respuesta.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"Haz una pregunta y el avatar leerá la respuesta en voz alta.\",\n askLabel: \"Pregunta para el avatar\",\n askPlaceholder: \"Pregunta al avatar…\",\n askFooter:\n \"Las respuestas las genera la IA y pueden contener errores. No incluyas datos personales.\",\n askNoFiles: \"Para adjuntar archivos, usa el chat.\",\n askBusy: \"Podrás preguntar cuando la respuesta actual esté lista.\",\n askUnavailable: \"El chat no está disponible en este momento.\",\n gettingAnswer: \"Obteniendo la respuesta…\",\n startWhenReady: \"Iniciar cuando esté lista\",\n armed: \"El avatar empezará cuando la respuesta esté lista.\",\n cancel: \"Cancelar\",\n armedCancelled:\n \"El avatar no se ha iniciado. Pulsa Iniciar cuando esté lista para volver a intentarlo.\",\n notSpoken:\n \"Esta respuesta se queda en el chat como texto. El avatar solo lee respuestas que superan sus comprobaciones de voz.\",\n answerFailed: \"El asistente no pudo responder. Vuelve a preguntar.\",\n declined: \"De acuerdo. La respuesta está en el chat.\",\n askHere: \"Para escuchar una respuesta, pregunta aquí.\",\n newChatForAvatar: \"Chat nuevo para el avatar\",\n newChatNote: \"Tu chat actual se queda en el historial.\",\n newChatStarted: \"Se ha iniciado un chat nuevo para el avatar.\",\n readInChat: \"Leer la respuesta y las fuentes en el chat\",\n usedToday:\n \"Ya has usado la sesión de avatar de hoy. Las respuestas se mostrarán aquí como texto.\",\n needsAnswerAny:\n \"Haz una pregunta aquí y el avatar leerá la respuesta en voz alta.\",\n startNewChatDetailAny:\n \"El avatar solo lee en voz alta la primera respuesta de un chat nuevo iniciado en la pestaña Avatar, si supera las comprobaciones de voz.\",\n notEligibleAny:\n \"El avatar no puede leer esta respuesta en voz alta. La respuesta y las fuentes están en el chat.\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed, including its right-to-left layout. Not shown\n// until \"ar\" is in REVIEWED.\nconst AR: AvatarLiveStrings = {\n checking: \"جارٍ التحقق من توفر الأفاتار المباشر…\",\n needsAnswer: \"اختر أولًا سؤالًا مقترحًا في الدردشة.\",\n needsAnswerDetail: \"يمكن للأفاتار قراءة الإجابة الأولى فقط بصوت عالٍ.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"ابدأ دردشة جديدة لاستخدام الأفاتار.\",\n startNewChatDetail:\n \"يقرأ الأفاتار بصوت عالٍ الإجابة الأولى في الدردشة فقط، إذا كانت إجابة عن سؤال مقترح وخلال خمس عشرة دقيقة. ابدأ دردشة جديدة واختر سؤالًا مقترحًا.\",\n start: \"بدء الأفاتار المباشر\",\n notNow: \"ليس الآن\",\n opensInNewTab: \"(يُفتح في علامة تبويب جديدة)\",\n botCheck: \"جارٍ التحقق من متصفحك…\",\n connecting: \"جارٍ الاتصال بالأفاتار المباشر…\",\n speaking: \"الأفاتار يتحدث الآن.\",\n badge: \"أفاتار بالذكاء الاصطناعي · ليس شخصًا حقيقيًا\",\n video: \"فيديو الأفاتار المباشر بالذكاء الاصطناعي\",\n captions: \"التسميات التوضيحية\",\n timeLeft: \"الوقت المتبقي\",\n stop: \"إيقاف\",\n tapForSound: \"انقر لتشغيل الصوت\",\n finished: \"انتهى الأفاتار المباشر.\",\n stopped: \"لقد أوقفت الأفاتار.\",\n failed: \"تعذّر بدء الأفاتار المباشر.\",\n interrupted: \"توقف الأفاتار المباشر قبل أن ينتهي.\",\n answerInChat: \"الإجابة الكاملة موجودة في الدردشة.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).\n excerpt:\n \"يقرأ الأفاتار الجزء الأول من هذه الإجابة. الإجابة الكاملة موجودة في الدردشة.\",\n backToChat: \"العودة إلى الدردشة\",\n busy: \"الأفاتار المباشر مشغول الآن. يُرجى المحاولة مرة أخرى بعد بضع دقائق.\",\n limits: \"بلغ الأفاتار المباشر حدّه في الوقت الحالي. يُرجى المحاولة لاحقًا.\",\n region: \"الأفاتار المباشر غير متاح في منطقتك بعد.\",\n locale: \"الأفاتار المباشر غير متاح بهذه اللغة بعد.\",\n paused: \"الأفاتار المباشر متوقف مؤقتًا الآن.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"يقرأ الأفاتار الإجابة الأولى عن سؤال مقترح، خلال خمس عشرة دقيقة. ابدأ دردشة جديدة واختر سؤالًا مقترحًا.\",\n answerClaimed: \"قرأ الأفاتار هذه الإجابة من قبل.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"اطرح سؤالًا، وسيقرأ الأفاتار الإجابة بصوت عالٍ.\",\n askLabel: \"سؤال للأفاتار\",\n askPlaceholder: \"اسأل الأفاتار…\",\n askFooter:\n \"الإجابات مُولَّدة بالذكاء الاصطناعي وقد تكون خاطئة. لا تضمّن بيانات شخصية.\",\n askNoFiles: \"لإرفاق ملفات، استخدم الدردشة.\",\n askBusy: \"يمكنك السؤال عندما تصبح الإجابة الحالية جاهزة.\",\n askUnavailable: \"الدردشة غير متاحة الآن.\",\n gettingAnswer: \"جارٍ الحصول على الإجابة…\",\n startWhenReady: \"البدء عند الجاهزية\",\n armed: \"سيبدأ الأفاتار عندما تصبح الإجابة جاهزة.\",\n cancel: \"إلغاء\",\n armedCancelled:\n \"لم يبدأ الأفاتار. اضغط على البدء عند الجاهزية للمحاولة مرة أخرى.\",\n notSpoken:\n \"تبقى هذه الإجابة في الدردشة نصًا. يقرأ الأفاتار فقط الإجابات التي تجتاز فحوص النطق.\",\n answerFailed: \"تعذّر على المساعد الإجابة. حاول السؤال مرة أخرى.\",\n declined: \"لا بأس. الإجابة موجودة في الدردشة.\",\n askHere: \"لسماع إجابة، اسأل هنا.\",\n newChatForAvatar: \"دردشة جديدة للأفاتار\",\n newChatNote: \"تبقى دردشتك الحالية في السجل.\",\n newChatStarted: \"بدأت دردشة جديدة للأفاتار.\",\n readInChat: \"اقرأ الإجابة والمصادر في الدردشة\",\n usedToday: \"لقد استخدمت جلسة الأفاتار لهذا اليوم. ستظهر الإجابات هنا نصًا.\",\n needsAnswerAny: \"اطرح سؤالًا هنا، وسيقرأ الأفاتار الإجابة بصوت عالٍ.\",\n startNewChatDetailAny:\n \"يقرأ الأفاتار بصوت عالٍ الإجابة الأولى فقط في دردشة جديدة بدأت في علامة تبويب الأفاتار، بشرط أن تجتاز فحوص النطق.\",\n notEligibleAny:\n \"لا يمكن للأفاتار قراءة هذه الإجابة بصوت عالٍ. الإجابة والمصادر موجودة في الدردشة.\",\n};\n\n// TRANSLATION REVIEW PENDING (BOFF-9797): a draft, not yet reviewed. Not shown until \"ta\" is in REVIEWED.\nconst TA: AvatarLiveStrings = {\n checking: \"நேரலை அவதார் கிடைக்கிறதா எனச் சரிபார்க்கிறது…\",\n needsAnswer:\n \"முதலில் அரட்டையில் பரிந்துரைக்கப்பட்ட ஒரு கேள்வியைத் தேர்ந்தெடுக்கவும்.\",\n needsAnswerDetail: \"அவதார் முதல் பதிலை மட்டுமே உரக்கப் படிக்க முடியும்.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n startNewChat: \"அவதாரைப் பயன்படுத்த புதிய அரட்டையைத் தொடங்கவும்.\",\n startNewChatDetail:\n \"ஓர் அரட்டையின் முதல் பதிலை மட்டுமே, அதுவும் பரிந்துரைக்கப்பட்ட கேள்விக்கான பதிலை, பதினைந்து நிமிடங்களுக்குள் மட்டுமே அவதார் உரக்கப் படிக்கும். புதிய அரட்டையைத் தொடங்கி, பரிந்துரைக்கப்பட்ட ஒரு கேள்வியைத் தேர்ந்தெடுக்கவும்.\",\n start: \"நேரலை அவதாரைத் தொடங்கு\",\n notNow: \"இப்போது வேண்டாம்\",\n opensInNewTab: \"(புதிய தாவலில் திறக்கும்)\",\n botCheck: \"உங்கள் உலாவியைச் சரிபார்க்கிறது…\",\n connecting: \"நேரலை அவதாருடன் இணைக்கிறது…\",\n speaking: \"அவதார் பேசுகிறது.\",\n badge: \"AI அவதார் · உண்மையான நபர் அல்ல\",\n video: \"நேரலை AI அவதார் வீடியோ\",\n captions: \"வசனங்கள்\",\n timeLeft: \"மீதமுள்ள நேரம்\",\n stop: \"நிறுத்து\",\n tapForSound: \"ஒலியை இயக்கத் தட்டவும்\",\n finished: \"நேரலை அவதார் முடிவடைந்தது.\",\n stopped: \"நீங்கள் அவதாரை நிறுத்தினீர்கள்.\",\n failed: \"நேரலை அவதாரைத் தொடங்க முடியவில்லை.\",\n interrupted: \"நேரலை அவதார் இடையிலேயே நின்றுவிட்டது.\",\n answerInChat: \"முழுப் பதில் அரட்டையில் உள்ளது.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the note for a part-read answer (Stage B).\n excerpt:\n \"அவதார் இந்தப் பதிலின் முதல் பகுதியைப் படிக்கிறது. முழுப் பதில் அரட்டையில் உள்ளது.\",\n backToChat: \"அரட்டைக்குத் திரும்பு\",\n busy: \"நேரலை அவதார் இப்போது வேறு பயன்பாட்டில் உள்ளது. சில நிமிடங்களில் மீண்டும் முயலவும்.\",\n limits:\n \"நேரலை அவதார் தற்போதைக்குத் தன் வரம்பை எட்டிவிட்டது. பிறகு மீண்டும் முயலவும்.\",\n region: \"உங்கள் பகுதியில் நேரலை அவதார் இன்னும் கிடைக்கவில்லை.\",\n locale: \"இந்த மொழியில் நேரலை அவதார் இன்னும் கிடைக்கவில்லை.\",\n paused: \"நேரலை அவதார் இப்போது இடைநிறுத்தப்பட்டுள்ளது.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft.\n notEligible:\n \"பரிந்துரைக்கப்பட்ட கேள்விக்கான முதல் பதிலை மட்டுமே, பதினைந்து நிமிடங்களுக்குள், அவதார் படிக்கும். புதிய அரட்டையைத் தொடங்கி, பரிந்துரைக்கப்பட்ட ஒரு கேள்வியைத் தேர்ந்தெடுக்கவும்.\",\n answerClaimed: \"இந்தப் பதிலை அவதார் ஏற்கெனவே படித்துவிட்டது.\",\n // TRANSLATION REVIEW PENDING (BOFF-9797): draft, the Avatar tab's question box.\n askHeadline: \"ஒரு கேள்வியைக் கேளுங்கள், அவதார் பதிலை உரக்கப் படிக்கும்.\",\n askLabel: \"அவதாருக்கான கேள்வி\",\n askPlaceholder: \"அவதாரிடம் கேளுங்கள்…\",\n askFooter:\n \"பதில்கள் AI உருவாக்கியவை, தவறாக இருக்கலாம். தனிப்பட்ட விவரங்களைச் சேர்க்க வேண்டாம்.\",\n askNoFiles: \"கோப்புகளை இணைக்க, அரட்டையைப் பயன்படுத்தவும்.\",\n askBusy: \"தற்போதைய பதில் தயாரானதும் நீங்கள் கேட்கலாம்.\",\n askUnavailable: \"அரட்டை இப்போது கிடைக்கவில்லை.\",\n gettingAnswer: \"பதிலைப் பெறுகிறது…\",\n startWhenReady: \"தயாரானதும் தொடங்கு\",\n armed: \"பதில் தயாரானதும் அவதார் தொடங்கும்.\",\n cancel: \"ரத்துசெய்\",\n armedCancelled:\n \"அவதார் தொடங்கவில்லை. மீண்டும் முயல, தயாரானதும் தொடங்கு என்பதை அழுத்தவும்.\",\n notSpoken:\n \"இந்தப் பதில் அரட்டையில் உரையாகவே இருக்கும். பேச்சுச் சரிபார்ப்புகளில் தேறும் பதில்களை மட்டுமே அவதார் படிக்கும்.\",\n answerFailed:\n \"உதவியாளரால் பதிலளிக்க முடியவில்லை. மீண்டும் கேட்டுப் பாருங்கள்.\",\n declined: \"பரவாயில்லை. பதில் அரட்டையில் உள்ளது.\",\n askHere: \"பதிலைக் கேட்க, இங்கே கேளுங்கள்.\",\n newChatForAvatar: \"அவதாருக்கான புதிய அரட்டை\",\n newChatNote: \"உங்கள் தற்போதைய அரட்டை வரலாற்றில் இருக்கும்.\",\n newChatStarted: \"அவதாருக்காகப் புதிய அரட்டை தொடங்கப்பட்டது.\",\n readInChat: \"பதிலையும் ஆதாரங்களையும் அரட்டையில் படிக்கவும்\",\n usedToday:\n \"இன்றைய அவதார் அமர்வை நீங்கள் பயன்படுத்திவிட்டீர்கள். பதில்கள் இங்கே உரையாகக் காட்டப்படும்.\",\n needsAnswerAny:\n \"இங்கே ஒரு கேள்வியைக் கேளுங்கள், அவதார் பதிலை உரக்கப் படிக்கும்.\",\n startNewChatDetailAny:\n \"அவதார் தாவலில் தொடங்கிய புதிய அரட்டையின் முதல் பதிலை மட்டுமே, அது பேச்சுச் சரிபார்ப்புகளில் தேறினால், அவதார் உரக்கப் படிக்கும்.\",\n notEligibleAny:\n \"இந்தப் பதிலை அவதாரால் உரக்கப் படிக்க முடியாது. பதிலும் ஆதாரங்களும் அரட்டையில் உள்ளன.\",\n};\n\nconst STRINGS: Record<ExploreLocale, AvatarLiveStrings> = {\n en: EN,\n zh: ZH,\n hi: HI,\n es: ES,\n ar: AR,\n ta: TA,\n};\n\nexport function avatarLiveStrings(locale: ExploreLocale): AvatarLiveStrings {\n return STRINGS[locale] ?? EN;\n}\n\n/** One version of the consent card's copy, in one locale. */\nexport interface AvatarConsentCopy {\n title: string;\n /**\n * What the avatar is and does, for a site with a product name. Takes `{product}`. Null in a product-neutral version:\n * every site, named or not, shows {@link AvatarConsentCopy.intro}, so the card's words are the same on every site.\n */\n introProduct: string | null;\n /** The same without a product name, and the only intro of a product-neutral version. */\n intro: string;\n /** Who processes what when the visitor starts. */\n processing: string;\n /** What is and is not used, recorded and kept, and who it is for. */\n storage: string;\n /** The link to the site's privacy notice, `/privacy#live-avatar`. */\n privacyLink: string;\n /**\n * The bot check `processing` tells the visitor about: `turnstile` where it says Cloudflare checks for bots, `off`\n * where it says nothing of one. The card is shown only where the server's `botCheck` is the same, so the notice a\n * visitor agrees to never describes a check that does not run, or leaves out one that does.\n */\n botCheck: AvatarBotCheck;\n /**\n * Which first questions the words describe: `suggested` where they speak of a suggested question only, `any` where\n * they say a question the visitor typed is read too. The card is shown only where the server's `questions` is the\n * same (contract v1.3), and the Avatar tab's own question box only under `any`.\n */\n questions: AvatarQuestions;\n}\n\n/**\n * The consent copy the server's `consentVersion` names, by version and then by locale. A version is added here, never\n * edited: changed wording is a new version, which the server starts asking for at the same time.\n */\nconst CONSENT: ReadonlyMap<\n string,\n Readonly<Partial<Record<ExploreLocale, AvatarConsentCopy>>>\n> = new Map([\n [\n \"web-consent-2026-11\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested {product} question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Your browser connects to LiveKit, which sees your IP address. LiveKit fetches our temporary audio file and passes the voice to Protoface, which makes the avatar video streamed through LiveKit.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session. We temporarily store the generated voice file and keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The voice is no longer a stored file: the server holds it in memory and plays it into the LiveKit room for Protoface.\n \"web-consent-2026-10-31\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested {product} question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The words of web-consent-2026-10-31 with no product name in them: one notice, byte for byte, on every product's\n // site, because the server binds one consent version and one notice digest for all of them.\n \"web-consent-2026-11-02\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The words of web-consent-2026-11-02 without \"When you start, Cloudflare checks for bots.\", for a server that runs\n // no bot check (its availability's botCheck is `off`). Product-neutral too: one notice and one digest for every site.\n \"web-consent-2026-11-03\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads the assistant's first eligible answer to a suggested question aloud for up to a minute. The answer is AI-generated and can be wrong.\",\n processing:\n \"The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"off\",\n questions: \"suggested\",\n },\n },\n ],\n [\n // The Avatar tab's own question box (contract v1.3, `questions: \"any\"`): the first answer in a new chat started in\n // the Avatar tab is read whether the visitor chose a suggested question or typed their own, so the intro says so and\n // warns against personal details in a typed one. Product-neutral, with the bot check: one notice and one digest for\n // every site (gitops docs/avatar-web/en-web-consent-2026-11-05.txt).\n \"web-consent-2026-11-05\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads aloud, for up to a minute, the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"any\",\n },\n },\n ],\n [\n // The words of web-consent-2026-11-05 without \"When you start, Cloudflare checks for bots.\", for a server that runs\n // no bot check (gitops docs/avatar-web/en-web-consent-2026-11-06.txt).\n \"web-consent-2026-11-06\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads aloud, for up to a minute, the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.\",\n processing:\n \"The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"off\",\n questions: \"any\",\n },\n },\n ],\n [\n // Stage B (operator decision 2026-11-04): web-consent-2026-11-05 with only its timing sentence changed. A session\n // lasts up to three minutes, sized by the server to the answer's audio; an answer longer than that is read in part,\n // which the avatar says and the Avatar tab notes (`excerpt`), and the full answer stays in Chat. A cap still\n // applies, so the words never say every answer is read whole (gitops docs/avatar-web/en-web-consent-2026-11-12-b.txt).\n \"web-consent-2026-11-12-b\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads aloud the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. It reads for up to three minutes; if an answer is longer, it reads the first part, says so, and the full answer stays in Chat. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.\",\n processing:\n \"When you start, Cloudflare checks for bots. The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"turnstile\",\n questions: \"any\",\n },\n },\n ],\n [\n // The words of web-consent-2026-11-12-b without \"When you start, Cloudflare checks for bots.\", for a server that runs\n // no bot check (gitops docs/avatar-web/en-web-consent-2026-11-13-b.txt).\n \"web-consent-2026-11-13-b\",\n {\n en: {\n title: \"Live AI avatar (beta)\",\n introProduct: null,\n intro:\n \"This is an AI avatar, not a real person. It reads aloud the first answer in a new chat started in the Avatar tab, provided it passes the speech checks, whether you chose a suggested question or typed your own. It reads for up to three minutes; if an answer is longer, it reads the first part, says so, and the full answer stays in Chat. The answer is AI-generated and can be wrong. Don't put personal details in a question you type.\",\n processing:\n \"The answer text goes to Google to create the voice. Our server sends that voice through LiveKit to Protoface, which makes the avatar video streamed through LiveKit. Your browser connects to LiveKit, which sees your IP address.\",\n storage:\n \"Your microphone and camera are not used. We do not record the live session or store the generated voice. We keep a record of this consent. The privacy notice explains our safeguards, storage periods and the providers' processing. For people aged eighteen and over.\",\n privacyLink: \"How we handle this\",\n botCheck: \"off\",\n questions: \"any\",\n },\n },\n ],\n]);\n\n/** The consent copy for exactly `version` in `locale`, or null when the SDK has none to show for it. */\nexport function avatarConsentCopy(\n version: string,\n locale: ExploreLocale,\n): AvatarConsentCopy | null {\n if (!isAvatarLiveLocaleReviewed(locale)) return null;\n return CONSENT.get(version)?.[locale] ?? null;\n}\n","/**\n * BOFF-9797. Cloudflare Turnstile, for the live avatar's start only.\n *\n * Nothing here runs until the visitor presses Start on the live avatar's consent card: the script is added to the page\n * then, once, and a widget is rendered for that one start (action `avatar_start`). The widget stays invisible unless\n * Cloudflare needs the visitor to interact with it. The token it returns goes to the gateway in a header and is used\n * once.\n *\n * The widget is rendered with `cData`, the binding of this check to the create request it is for (web API contract\n * v1.1: see `avatarBotBinding` in `explore-avatar-api.ts`), so it cannot be rendered before the binding is known.\n */\n\nconst SCRIPT_SRC =\n \"https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit\";\n/** How long the script may take to load before the start is given up. */\nconst SCRIPT_TIMEOUT_MS = 15_000;\n\n/** The part of Turnstile's render options used here. */\ninterface TurnstileRenderOptions {\n sitekey: string;\n action: string;\n /** Customer data Turnstile returns with the verified token: the binding to the create request. */\n cData: string;\n appearance: \"interaction-only\";\n size: \"flexible\";\n \"response-field\": false;\n callback: (token: string) => void;\n \"error-callback\": () => boolean;\n \"expired-callback\": () => void;\n \"timeout-callback\": () => void;\n}\n\n/** The part of `window.turnstile` used here. */\ninterface TurnstileApi {\n render: (\n container: HTMLElement,\n options: TurnstileRenderOptions,\n ) => string | null | undefined;\n remove: (widgetId: string) => void;\n}\n\nfunction readApi(): TurnstileApi | null {\n if (typeof window === \"undefined\") return null;\n const api = (window as unknown as { turnstile?: Partial<TurnstileApi> })\n .turnstile;\n return api &&\n typeof api.render === \"function\" &&\n typeof api.remove === \"function\"\n ? (api as TurnstileApi)\n : null;\n}\n\nlet loading: Promise<TurnstileApi> | null = null;\n\n/** Turnstile's API, adding its script to the page the first time. A failed load can be tried again later. */\nexport function loadTurnstile(): Promise<TurnstileApi> {\n const ready = readApi();\n if (ready) return Promise.resolve(ready);\n if (loading) return loading;\n loading = new Promise<TurnstileApi>((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = SCRIPT_SRC;\n script.async = true;\n script.setAttribute(\"data-boff-explore\", \"avatar-live-turnstile\");\n const fail = () => {\n clearTimeout(timer);\n loading = null;\n script.remove();\n reject(new Error(\"The bot check could not be loaded.\"));\n };\n const timer = setTimeout(fail, SCRIPT_TIMEOUT_MS);\n script.addEventListener(\"load\", () => {\n const api = readApi();\n if (!api) {\n fail();\n return;\n }\n clearTimeout(timer);\n resolve(api);\n });\n script.addEventListener(\"error\", fail);\n document.head.appendChild(script);\n });\n return loading;\n}\n\nexport interface TurnstileRun {\n /** The token, once Cloudflare has one; rejects when the check fails, expires, times out or is cancelled. */\n token: Promise<string>;\n /** Remove the widget, and reject `token` if it is still waiting. Safe to call more than once. */\n cancel: () => void;\n}\n\n/**\n * Run one bot check in `container` with `siteKey`, for `action`, bound to `cData` (or to what it resolves to: the widget\n * is rendered once its script has loaded AND the binding is known, and a binding that cannot be made fails the check).\n */\nexport function runTurnstile(\n container: HTMLElement | null,\n siteKey: string,\n action: string,\n cData: string | Promise<string>,\n): TurnstileRun {\n // A binding that cannot be made fails `token`; it is never an unhandled rejection of its own.\n Promise.resolve(cData).catch(() => undefined);\n let settled = false;\n let cancelled = false;\n let widget: { api: TurnstileApi; id: string } | null = null;\n let rejectToken: (error: Error) => void = () => undefined;\n\n const removeWidget = () => {\n if (!widget) return;\n const { api, id } = widget;\n widget = null;\n try {\n api.remove(id);\n } catch {\n // Already gone with its container.\n }\n };\n\n const token = new Promise<string>((resolve, reject) => {\n rejectToken = (error: Error) => {\n if (settled) return;\n settled = true;\n reject(error);\n };\n if (!container) {\n rejectToken(new Error(\"No place for the bot check.\"));\n return;\n }\n Promise.all([loadTurnstile(), cData]).then(\n ([api, binding]) => {\n if (cancelled || settled) return;\n const failed = () => {\n removeWidget();\n rejectToken(new Error(\"The bot check did not pass.\"));\n };\n const id = api.render(container, {\n sitekey: siteKey,\n action,\n cData: binding,\n appearance: \"interaction-only\",\n size: \"flexible\",\n \"response-field\": false,\n callback: (value: string) => {\n if (settled) return;\n settled = true;\n resolve(value);\n },\n \"error-callback\": () => {\n failed();\n // Handled here: Turnstile need not report it again.\n return true;\n },\n \"expired-callback\": failed,\n \"timeout-callback\": failed,\n });\n if (typeof id === \"string\" && id !== \"\") {\n widget = { api, id };\n if (settled) removeWidget();\n } else if (!settled) {\n rejectToken(new Error(\"The bot check could not start.\"));\n }\n },\n (error: unknown) => {\n rejectToken(\n error instanceof Error\n ? error\n : new Error(\"The bot check could not be loaded.\"),\n );\n },\n );\n });\n\n // A cancelled check nobody waits on any more is not an error worth reporting.\n token.catch(() => undefined);\n\n return {\n token,\n cancel: () => {\n cancelled = true;\n removeWidget();\n rejectToken(new Error(\"The bot check was cancelled.\"));\n },\n };\n}\n","/**\n * AvatarLiveView — the Avatar tab's live avatar (BOFF-9797), opt-in: its view and its state machine.\n *\n * `ExploreAvatarLive` (`explore-avatar-live.tsx`) renders this, and only once the Avatar view has been opened on a panel\n * whose host passes `avatar.live`. This file, and the requests, the words and the bot check it brings with it, is a\n * chunk of its own that a site downloads at that moment and not before; a site that never passes `avatar.live` never\n * does. It reads nothing from the page's React contexts (the package builds each entry on its own, so a context read\n * here would be a second, empty one): everything it needs comes in as props from `ExploreAvatarLive`.\n *\n * The visitor watches and listens; their browser never sends the avatar anything to say. What happens, in order:\n *\n * 1. **The tab opens** (never on page load): one availability request to the gateway's web branch. Nothing else is\n * loaded or asked for until the visitor agrees.\n * 2. **Offered, with the conversation's first answer:** a consent card (its copy is versioned; the panel shows only\n * copy written for the version the server names), Start, Not now and a link to the privacy notice. The avatar reads\n * one answer only: a conversation that is exactly a suggested question and its completed answer, while that answer\n * is fresh (see {@link ANSWER_OFFER_MS}). A failed first answer, a second question or an answer that is too old asks\n * the visitor to start a new chat instead, with a New chat button.\n * 3. **Start:** the live module (`live.load`) and, where the server checks for bots (availability's `botCheck`, contract\n * v1.2), the bot check load, then one create request: the contract's six fields, an `Idempotency-Key` and the bot\n * check's token, without credentials. The bot check is bound to that very request (`cData`, contract v1.1), so the\n * body is made once, before the widget is rendered. Where the server runs no bot check, no Cloudflare script or\n * widget is loaded and the request carries no token.\n * 4. **Created:** the room is joined to watch only. The avatar's video, its captions, a badge saying it is an AI and\n * not a person, a countdown (never announced), Stop and Continue in Chat.\n * 5. **Ending:** Stop, closing the panel, leaving the page (`pagehide`) or the live avatar going off asks the server to\n * end the session with a `keepalive` request. The server ends it on its own deadlines either way. Once the create has\n * been sent, switching to the Chat tab or to another browser tab does not end it: the pane is only hidden, so the\n * room's video and audio stay attached and the avatar speaks to its planned end (see `leave`). Before the create,\n * both still call off what is under way, with nothing created. Where the host sets `live.endUnattended`, a session\n * out of sight also ends once its answer has played out, and soon when the browser holds its sound back (see\n * `attend`): an idle tail after an answer runs only while the Avatar view is in sight.\n *\n * **Asking in the Avatar tab** (contract v1.3): where the server reads the answer to a question the visitor typed too\n * (availability's `questions` is `any`) and this SDK holds consent copy written for that, the tab has a question box of\n * its own, with the suggested questions as chips. A question asked there (`surface: \"AVATAR\"`) is the first of a new\n * chat, and its first answer is the only one offered: the consent card shows while the answer is written, with \"Start\n * when ready\", which waits for the answer, asks availability again and checks the answer as the service will, and only\n * then creates the session. Any other conversation is never read: the tab offers \"New chat for the avatar\", and never\n * resets a conversation by itself. After the day's session (a `limits` refusal, or this browser's own note of one) the\n * box asks ordinary questions, and the answer shows as text. Under `suggested`, or with a server older than v1.3, the\n * tab is as it was.\n *\n * Any refusal is one short sentence and \"Continue in Chat\". A route that is not there, a refused origin or a network\n * failure shows the tab as it was before the live avatar. The conversation token goes into the create request and\n * nowhere else; the session's secret and room token are kept in refs, never in the page.\n */\n\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ClipboardEvent as ReactClipboardEvent,\n type DragEvent as ReactDragEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from \"react\";\n\nimport {\n avatarBotBinding,\n canBindBotCheck,\n isAvatarConversationToken,\n isAvatarMessageId,\n newIdempotencyKey,\n requestAvailability,\n requestCreate,\n sendEnd,\n type AvatarAvailability,\n type AvatarBotCheck,\n type AvatarCreateBody,\n type AvatarCreateResult,\n type AvatarEndReason,\n type AvatarOffer,\n type AvatarQuestions,\n type AvatarRefusal,\n type AvatarSession,\n} from \"./explore-avatar-api\";\nimport {\n avatarConsentCopy,\n avatarLiveStrings,\n type AvatarConsentCopy,\n type AvatarLiveStrings,\n} from \"./explore-avatar-i18n\";\nimport { turnstileSiteKeyOf } from \"./explore-avatar-live-config\";\nimport { runTurnstile, type TurnstileRun } from \"./explore-avatar-turnstile\";\nimport { fill } from \"./explore-fill\";\nimport { cn } from \"../utils/cn\";\n\nimport type {\n AvatarConversation,\n ExplorePanelAvatarLive,\n} from \"./explore-avatar-live-config\";\nimport type { ExploreLocale } from \"./explore-i18n\";\nimport type { ExploreMessage } from \"./explore-types\";\nimport type {\n AvatarLiveModule,\n ReceiveOnlyEvent,\n ReceiveOnlySession,\n} from \"../avatar-live/types\";\n\n/** Where the consent card's privacy link goes: the site's privacy notice, at its live avatar section. */\nconst PRIVACY_HREF = \"/privacy#live-avatar\";\n\n/** How long a joined room waits for the avatar's video before the session is given up. */\nconst SPEAKER_WAIT_MS = 30_000;\n/** Past a session's end, how long before the browser leaves a room that is somehow still open. */\nconst END_GRACE_MS = 10_000;\n/** How far the server's end may sit from this browser's clock before the browser counts down on its own clock. */\nconst CLOCK_TOLERANCE_MS = 5_000;\n/**\n * Under `endUnattended`: out of sight, how long a session whose sound the browser holds back goes on before it is ended\n * (see `attend`). Long enough for a visitor who has just switched to the Chat tab or another browser tab to come back\n * and find \"Tap to turn on sound\"; short enough that a session nobody can hear is not paid for to its end.\n */\nconst UNHEARD_GRACE_MS = 5_000;\n/**\n * Under `endUnattended`: from the end of the speech at its source (`speech-ended`) to the answer's playout as the\n * visitor hears it. The worker's voice lags its source, and the server keeps a session for that lag: its planned end is\n * the speech's first frame + its length + a 3 s tail allowance (global-speech-svc `docs/AVATAR_WEB_API.md`, \"Timing\").\n * This is that allowance plus 2 s, so the last words are never cut, and the server's own end, which counts as a natural\n * finish only when no end request came before it, comes first while the server ends a session after its answer.\n */\nconst PLAYOUT_TAIL_MS = 5_000;\n\n/**\n * The avatar service refuses an answer more than fifteen minutes old (`not_eligible`; `MAX_AGE_MS` in global-speech-svc\n * `src/avatar/web/eligibility.ts`, measured from the answer's `createdAt` on the service's clock). If it changes, this\n * and the \"fifteen minutes\" in the `notEligible` and `startNewChatDetail` strings change with it.\n */\nconst SERVICE_MAX_AGE_MS = 15 * 60_000;\n/**\n * How long after an answer was created the view offers the avatar for it: a minute less than the service allows, so\n * that a visitor who reads the consent card near the edge is not sent through Start and a create request the service\n * will refuse. A visitor on the consent card when the answer crosses this age is moved to the start-over step (one\n * timer, set for that moment). Once Start is pressed, the create is skipped only past the service's own limit.\n */\nconst ANSWER_OFFER_MS = SERVICE_MAX_AGE_MS - 60_000;\n/** The longest delay a browser's `setTimeout` keeps (about 24.8 days): a longer one fires at once. */\nconst MAX_TIMER_MS = 2_147_483_647;\n\n/**\n * The longest question the Avatar tab's own box takes: the avatar service's limit for a question the visitor typed (the\n * chat's own limit is longer).\n */\nconst ASK_MAX_LENGTH = 300;\n/** The most references an answer the avatar service reads may cite (`eligibility.ts`); it needs at least one. */\nconst MAX_REFERENCES = 64;\n/**\n * Where this browser notes the day (UTC) it had a live session, so the box can say the day's session is used and ask in\n * text. A hint only: the limits are the server's.\n */\nconst USED_ON_KEY = \"boff.explore.avatarUsedOn\";\n\n/** The control each step puts focus on when the one the visitor was on has gone. */\nconst PRIMARY =\n '[data-avatar-primary], [data-boff-explore=\"panel-continue-chat\"]';\n\ninterface Offer extends AvatarOffer {\n /** The locale availability was asked for: the consent copy shown and the create request are both in this one. */\n locale: ExploreLocale;\n copy: AvatarConsentCopy;\n}\n\n/** What the page shows of a session: never its secret or its room token. */\ninterface ShownSession {\n /** When this browser counts the session as over, on its own clock. */\n endsAt: number;\n captions: { locale: string; text: string };\n /** Only the first part of the answer is spoken (the 201's `excerpt`): the status line says so while it plays. */\n excerpt: boolean;\n}\n\n/**\n * How a session ended. `finished` means the server closed the room (the worker left, or the room was closed by the\n * server) while the avatar was live, or the session's time ran out with the room still open: the browser cannot tell the\n * avatar reading to the end from a server-side stop or a hand-over, so the words for it say only that the live avatar\n * has ended.\n */\ntype EndedHow = \"finished\" | \"stopped\" | \"failed\" | \"interrupted\";\n\ntype Phase =\n | { name: \"idle\" }\n | { name: \"checking\" }\n | { name: \"inert\" }\n | { name: \"needs-answer\"; offer: Offer }\n | { name: \"consent\"; offer: Offer; messageId: string }\n /** Under `any`: Not now. The card is offered again when the tab next opens, while the answer is fresh. */\n | { name: \"declined\"; offer: Offer }\n /** Under `any`: \"Start when ready\" pressed while the answer is still being written (see {@link WaitRun}). */\n | { name: \"waiting\"; offer: Offer }\n | { name: \"refused\"; reason: AvatarRefusal }\n | { name: \"bot-check\"; offer: Offer; messageId: string }\n | { name: \"creating\" }\n | { name: \"pending\"; session: ShownSession }\n | { name: \"live\"; session: ShownSession }\n | { name: \"ended\"; how: EndedHow };\n\nconst IDLE: Phase = { name: \"idle\" };\nconst INERT: Phase = { name: \"inert\" };\n\n/** One press of Start, until its create request has answered. */\ninterface StartRun {\n /** Set when the visitor (or the page) gave up on it, with the reason to end a session it still creates. */\n cancelled: AvatarEndReason | null;\n turnstile: TurnstileRun | null;\n}\n\n/**\n * One press of \"Start when ready\", until the answer is ready and checked (or the start is called off). The press is the\n * visitor's consent for exactly what it is bound to: this conversation, its first question and the answer on its way,\n * the site, the locale and the page, and the consent version and bot check that availability named. Any of them\n * changing calls it off with nothing created; once the answer is ready, availability is asked again and the answer\n * checked again, and anything that differs shows the card again instead of creating.\n */\ninterface WaitRun {\n bound: {\n token: string;\n questionId: string;\n answerId: string;\n site: string;\n locale: ExploreLocale;\n path: string;\n consentVersion: string;\n botCheck: AvatarBotCheck;\n };\n /** The room module, loading while the answer is written. */\n module: Promise<AvatarLiveModule>;\n /** The availability question asked again once the answer is ready; null until then. */\n check: AbortController | null;\n}\n\n/** A created session, from its 201 until it ends. */\ninterface SessionHandle {\n session: AvatarSession;\n base: string;\n headers: Readonly<Record<string, string>>;\n module: AvatarLiveModule;\n /** The join, once started. */\n room: Promise<ReceiveOnlySession | null> | null;\n /** The joined room, once joined: `enablePlayback` must be called inside the visitor's tap, so not via a promise. */\n joined: ReceiveOnlySession | null;\n /** When this browser counts the session as over, on its own clock (see `begin`). */\n endsAt: number;\n /** The avatar's video has arrived. */\n speakerArrived: boolean;\n /**\n * The avatar's voice (its audio track) has arrived. Until then a held-back sound is the room's guess (it reports a\n * suspended audio context as soon as it connects, and takes it back once the voice actually plays), not a voice\n * speaking to nobody.\n */\n voiceArrived: boolean;\n /** The browser holds the avatar's sound back (`playback-blocked`'s `sound`): nobody hears it until a tap. */\n soundHeld: boolean;\n /** The answer has played out: its speech ended at the source, and {@link PLAYOUT_TAIL_MS} has passed since. */\n playedOut: boolean;\n /** The attention rule's timers (see `attend`): the grace for held-back sound, and the playout tail. */\n unheard: ReturnType<typeof setTimeout> | null;\n tail: ReturnType<typeof setTimeout> | null;\n done: boolean;\n}\n\n/** Clear the attention rule's timers (see `attend`): the session has ended, or the view has gone. */\nfunction stopAttending(handle: SessionHandle): void {\n if (handle.unheard !== null) clearTimeout(handle.unheard);\n if (handle.tail !== null) clearTimeout(handle.tail);\n handle.unheard = null;\n handle.tail = null;\n}\n\nconst REFUSAL_TEXT: Record<AvatarRefusal, keyof AvatarLiveStrings> = {\n busy: \"busy\",\n limits: \"limits\",\n region: \"region\",\n locale: \"locale\",\n paused: \"paused\",\n not_eligible: \"notEligible\",\n answer_claimed: \"answerClaimed\",\n};\n\n/**\n * What the first exchange is. `answer` is the one the avatar may read; the others say why there is none yet, or never in\n * this conversation:\n *\n * - `empty`: nothing asked yet; `asking`: the first question, its answer on its way;\n * - `text-only` (under `any`): a completed first answer that fails a check the service makes and this browser can make\n * too (it cites none of the site's documentation, more references than the service takes, files with the question);\n * - `failed` (under `any`): the first answer failed;\n * - `ask-here` (under `any`): the first answer to a question that was not asked in this tab as the first of a new chat;\n * - `start-over`: anything else (a second question, an answer whose id the service cannot take, one too old).\n */\ntype ExchangeKind =\n | \"empty\"\n | \"asking\"\n | \"answer\"\n | \"text-only\"\n | \"failed\"\n | \"ask-here\"\n | \"start-over\";\n\n/** What the conversation offers the avatar to read. */\ninterface Exchange {\n kind: ExchangeKind;\n /** The answer the avatar may read, or null: set for `answer` only. */\n answerId: string | null;\n /**\n * The conversation can never be read: its first answer failed or is unusable, or it has gone past the first\n * exchange. Only a new chat can be. False while there is simply nothing to read yet.\n */\n startOver: boolean;\n /**\n * With an answer: until when (this browser's clock, in milliseconds) it is offered, {@link ANSWER_OFFER_MS} after its\n * `createdAt`. `NaN` for an answer whose `createdAt` is missing or cannot be read, which is never offered (the\n * service would refuse it). `NaN` without an answer too.\n */\n offerUntil: number;\n /** The first question, while the conversation is its first exchange; null otherwise. */\n question: ExploreMessage | null;\n /** Asking: the id the server gave the answer on its way (the one it keeps once complete), or null before then. */\n pendingAnswerId: string | null;\n /** Under `any`: the first question was asked in this tab, as the first of a new chat, in this page's visit. */\n askedHere: boolean;\n}\n\nconst EMPTY: Exchange = {\n kind: \"empty\",\n answerId: null,\n startOver: false,\n offerUntil: NaN,\n question: null,\n pendingAnswerId: null,\n askedHere: false,\n};\nconst START_OVER: Exchange = { ...EMPTY, kind: \"start-over\", startOver: true };\n\n/**\n * A question this tab asked as the first of a new chat, recorded only once the chat's `send` has actually added it: the\n * id of the USER message it added, and the conversation's token as that send ended (null when the server never named\n * one: a send that failed before the server took it). Not its text: the server stores the question normalized (line\n * endings, control characters, runs of blank lines: `normalizeExploreMessage` in global-support-svc), so the words in\n * the chat can differ from the ones the box sent, and the id alone already names the one message.\n */\ninterface AskedHere {\n messageId: string;\n token: string | null;\n}\n\n/**\n * Which rules the exchange is read by: the server's `questions`, the question this tab asked as the first of a new\n * chat (null when none), the conversation's token now, and whether the chat has a question on its way (`sending` or\n * `streaming`).\n */\ninterface ExchangeRules {\n any: boolean;\n askedHere: AskedHere | null;\n token: string | null;\n inFlight: boolean;\n}\n\nconst SUGGESTED_RULES: ExchangeRules = {\n any: false,\n askedHere: null,\n token: null,\n inFlight: false,\n};\n\n/**\n * Whether `question` is the one this tab asked: the very USER message its send added (its id), in the conversation that\n * send ended in. A question asked in Chat is never it, whatever it says (the same words included), and neither is a\n * conversation opened from History whose first question happens to read the same.\n */\nfunction isAskedHere(question: ExploreMessage, rules: ExchangeRules): boolean {\n const asked = rules.askedHere;\n return (\n rules.any &&\n asked !== null &&\n question.id === asked.messageId &&\n asked.token === rules.token\n );\n}\n\n/** A message's `createdAt` in milliseconds, or `NaN` when it is missing or not a date. */\nfunction createdAtOf(message: ExploreMessage): number {\n const raw: unknown = message.createdAt;\n return typeof raw === \"string\" && raw !== \"\" ? Date.parse(raw) : NaN;\n}\n\n/**\n * The exchange as it stands at `now`: an answer past its {@link Exchange.offerUntil} (or with no readable time) is\n * no longer offered, and only a new chat can be.\n */\nfunction offeredAt(exchange: Exchange, now: number): Exchange {\n // `!(now < …)` and not `now >= …`: with a `NaN` deadline (no readable `createdAt`) it is true, so the answer is not\n // offered.\n return exchange.answerId !== null && !(now < exchange.offerUntil)\n ? START_OVER\n : exchange;\n}\n\n/**\n * The checks on a first answer that the avatar service makes and this browser can make as well (`eligibility.ts` in\n * global-speech-svc): it is an answer (`answered`), it cites between one and {@link MAX_REFERENCES} references, and no\n * files came with the question. The service stays the judge: this only keeps the card from offering what it refuses.\n */\nfunction readable(question: ExploreMessage, answer: ExploreMessage): boolean {\n const references = answer.references?.length ?? 0;\n return (\n answer.answered === true &&\n references >= 1 &&\n references <= MAX_REFERENCES &&\n (question.attachments?.length ?? 0) === 0\n );\n}\n\n/**\n * The one answer the avatar may read, and why there is none. The avatar service accepts a conversation only when it\n * holds EXACTLY two messages: the first USER message and the first ASSISTANT answer, COMPLETED. This is the same rule,\n * so the avatar is never offered, and the visitor never goes through consent and the bot check, for a conversation the\n * service would refuse:\n *\n * - exactly that exchange: its answer;\n * - nothing asked yet, or the question asked and its answer still on its way: nothing yet (the view says to choose a\n * suggested question, or that the answer is coming, and offers the avatar once the answer completes);\n * - anything else (a failed or empty first answer, a second question, whatever came after a failed answer asked\n * again without Retry): never, in this conversation (the view says to start a new chat).\n *\n * The service also refuses an answer more than fifteen minutes old: a conversation restored from this browser's\n * history, say. That depends on the time as well as the messages, so it is applied on top of this (`offeredAt`), with\n * the answer's {@link Exchange.offerUntil}.\n *\n * Under `suggested`, that the question is one of the suggested ones is the service's to judge (`not_eligible`), not the\n * browser's. Under `any` (the Avatar tab's own box), the answer is offered only to a question this tab asked as the\n * first of a new chat, and only when it passes the checks this browser can make too ({@link readable}); a failed\n * first answer is told apart, so the tab can say so.\n */\nfunction firstExchange(\n messages: readonly ExploreMessage[] | undefined,\n rules: ExchangeRules = SUGGESTED_RULES,\n): Exchange {\n if (!messages || messages.length === 0) return EMPTY;\n if (messages.length > 2) return START_OVER;\n const [question, answer] = messages;\n if (question?.role !== \"USER\") return START_OVER;\n const first = { question, askedHere: isAskedHere(question, rules) };\n if (answer === undefined) {\n // The question alone. On its way: the answer is coming. Otherwise none is: the chat drops a failed answer that\n // had no text (and one a reload cut short), so under `any` the tab says the answer failed; under `suggested`, as\n // before, nothing has been answered yet.\n if (rules.inFlight) return { ...EMPTY, ...first, kind: \"asking\" };\n return rules.any ? { ...START_OVER, ...first, kind: \"failed\" } : EMPTY;\n }\n if (answer.role !== \"ASSISTANT\") return START_OVER;\n if (answer.status === \"PENDING\" || answer.status === \"RUNNING\") {\n return {\n ...EMPTY,\n ...first,\n kind: \"asking\",\n pendingAnswerId: isAvatarMessageId(answer.id) ? answer.id : null,\n };\n }\n if (rules.any && answer.status === \"FAILED\") {\n return { ...START_OVER, ...first, kind: \"failed\" };\n }\n if (\n answer.status !== \"COMPLETED\" ||\n answer.content.trim() === \"\" ||\n !isAvatarMessageId(answer.id)\n ) {\n return START_OVER;\n }\n if (rules.any && !first.askedHere) {\n return { ...START_OVER, ...first, kind: \"ask-here\" };\n }\n if (rules.any && !readable(question, answer)) {\n return { ...START_OVER, ...first, kind: \"text-only\" };\n }\n return {\n ...EMPTY,\n ...first,\n kind: \"answer\",\n answerId: answer.id,\n offerUntil: createdAtOf(answer) + ANSWER_OFFER_MS,\n };\n}\n\n/** Whether the chat has a question on its way. */\nfunction inFlight(conversation: AvatarConversation | null): boolean {\n return (\n conversation?.phase === \"sending\" || conversation?.phase === \"streaming\"\n );\n}\n\n/** Today, as UTC: the day the box's note of a used session is for. */\nfunction utcToday(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\n/** Whether this browser noted a live session today. Storage that cannot be read (a private window) is no note. */\nfunction usedTodayHere(): boolean {\n try {\n return window.localStorage.getItem(USED_ON_KEY) === utcToday();\n } catch {\n return false;\n }\n}\n\n/** Note today's live session, where this browser lets the page keep it. */\nfunction noteUsedToday(): void {\n try {\n window.localStorage.setItem(USED_ON_KEY, utcToday());\n } catch {\n // Storage blocked: the box simply does not know, and the server's limits still hold.\n }\n}\n\n/** A tenth of a second of silence, as a WAV data URI, made once, the first time a Start needs it. */\nlet silence: string | null = null;\n\nfunction silentWav(): string {\n if (silence !== null) return silence;\n // 8 kHz, 8-bit mono: 800 samples at the mid level (128) is silence.\n const rate = 8_000;\n const samples = rate / 10;\n const bytes = new Uint8Array(44 + samples);\n const view = new DataView(bytes.buffer);\n const text = (at: number, value: string) => {\n for (let i = 0; i < value.length; i += 1) {\n bytes[at + i] = value.charCodeAt(i);\n }\n };\n text(0, \"RIFF\");\n view.setUint32(4, 36 + samples, true);\n text(8, \"WAVE\");\n text(12, \"fmt \");\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true); // PCM\n view.setUint16(22, 1, true); // mono\n view.setUint32(24, rate, true);\n view.setUint32(28, rate, true); // bytes a second\n view.setUint16(32, 1, true); // bytes a frame\n view.setUint16(34, 8, true); // bits a sample\n text(36, \"data\");\n view.setUint32(40, samples, true);\n bytes.fill(128, 44);\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n silence = `data:audio/wav;base64,${btoa(binary)}`;\n return silence;\n}\n\n/**\n * Let the page play sound later: called straight from the visitor's tap on Start (browsers allow sound only from inside\n * a gesture, and Safari on iOS keeps an element locked until then), it plays a tenth of a second of silence on the\n * element the room's audio will use, and pauses it. \"Tap to turn on sound\" stays for a browser that still holds sound\n * back. An element already playing a room's audio is left alone.\n */\nfunction unlockSound(audio: HTMLAudioElement | null): void {\n if (audio === null || audio.srcObject) return;\n try {\n audio.src = silentWav();\n void Promise.resolve(audio.play()).then(\n () => audio.pause(),\n () => undefined,\n );\n } catch {\n // A browser that cannot play it now: the room's own playback, and the sound button, still work.\n }\n}\n\n/**\n * The step that offers `messageId` to the visitor: the consent card, unless this visit has already used that answer\n * (`claimed` holds every answer a session was created for, or that the server said it already has one for), in which\n * case it says so instead. The ways back to a consent card for an answer that may have been used in the meantime go\n * through here: the availability answer, and returning from a bot check.\n */\nfunction offering(\n offer: Offer,\n messageId: string,\n claimed: ReadonlySet<string>,\n): Phase {\n return claimed.has(messageId)\n ? { name: \"refused\", reason: \"answer_claimed\" }\n : { name: \"consent\", offer, messageId };\n}\n\nasync function loadModule(\n load: () => Promise<AvatarLiveModule>,\n): Promise<AvatarLiveModule> {\n const loaded: unknown = await load();\n const join =\n loaded !== null && typeof loaded === \"object\"\n ? (loaded as Partial<AvatarLiveModule>).joinReceiveOnly\n : undefined;\n if (typeof join !== \"function\") {\n throw new Error(\"The live avatar module could not be loaded.\");\n }\n return loaded as AvatarLiveModule;\n}\n\n/** `m:ss`. */\nfunction clock(seconds: number): string {\n const whole = Math.max(0, Math.ceil(seconds));\n return `${Math.floor(whole / 60)}:${String(whole % 60).padStart(2, \"0\")}`;\n}\n\nexport interface AvatarLiveViewProps {\n live: ExplorePanelAvatarLive;\n /** The Avatar view is showing: the panel is open and its Avatar tab is selected. */\n active: boolean;\n /**\n * The panel is open, whichever tab it shows. With `active` it tells the Chat tab (open, not active: the pane is only\n * hidden, and a session under way keeps playing) from the panel closing (not open: what is under way ends).\n */\n open: boolean;\n locale: ExploreLocale;\n /** The product the panel speaks for, when it is one product's own; null on the portfolio's. */\n productName: string | null;\n /** The approved still picture. */\n still: { src: string; alt: string };\n /** The Avatar tab as it was before the live avatar: shown whenever the live avatar is not offered or not reachable. */\n fallback: ReactNode;\n /**\n * Back to the Chat tab. Like the Chat tab itself, it calls off a start that has not been sent yet, and leaves a\n * session under way speaking.\n */\n onContinueInChat: () => void;\n /**\n * Told whenever the avatar's voice starts or stops being the page's: its status line while a session is being\n * created, joined or played (\"Connecting to the live avatar…\", \"The avatar is speaking.\"), and null otherwise (and\n * when the view goes). The panel holds Chat's own read-aloud and dictation meanwhile, so the page never speaks in two\n * voices and the microphone never takes down the avatar's.\n */\n onVoiceHold?: (line: string | null) => void;\n /** \"Continue in Chat\" in the panel's language: the panel's own word for it, so this chunk carries none of the panel's. */\n continueInChat: string;\n /**\n * \"New chat\" in the panel's language, the panel's own word for it: the button that starts over (the conversation's\n * `reset`, as the chat's own New chat button does, then the Chat tab) where this conversation can never be read.\n */\n newChat: string;\n /** \"Send\" and \"Try asking\" in the panel's language, for the Avatar tab's own question box. */\n send: string;\n tryAsking: string;\n /** The suggested questions the chat view shows: the box's chips. */\n prompts: readonly string[];\n /** No precise pointer: the box is not focused by itself, so the keyboard does not cover the view. */\n touchFirst: boolean;\n /** The host router's path, when it has one: a \"Start when ready\" is called off when it changes. */\n currentPath: string | undefined;\n /**\n * Nothing to ask the server about: an incomplete config, no gateway, no shared conversation to read (no provider, or a\n * read-only shared one), or a locale whose strings have not been reviewed. The tab stays as it was. Decided by\n * `ExploreAvatarLive`, which also decides whether this view is loaded at all; it can change while this view is\n * mounted (the panel's locale switching), and what is under way then ends.\n */\n off: boolean;\n /** {@link avatarApiBase} of the SDK's gateway, null when there is none to use. */\n base: string | null;\n /** Headers every request carries: the alpha gateway's access headers, and nothing on production. */\n headers: Readonly<Record<string, string>>;\n /** The panel's conversation, null when there is no provider. */\n conversation: AvatarConversation | null;\n}\n\nexport function AvatarLiveView({\n live,\n active,\n open,\n locale,\n productName,\n still,\n fallback,\n onContinueInChat,\n onVoiceHold,\n continueInChat,\n newChat,\n send,\n tryAsking,\n prompts,\n touchFirst,\n currentPath,\n off,\n base,\n headers,\n conversation,\n}: AvatarLiveViewProps) {\n const S = avatarLiveStrings(locale);\n const uid = useId();\n const consentTitleId = `${uid}-consent`;\n\n /**\n * Which first questions the server reads the answer to, as its last availability answer said (`suggested` until one\n * says `any`). Kept in a ref as well, for the steps that read it between renders.\n */\n const [questions, setQuestions] = useState<AvatarQuestions>(\"suggested\");\n const questionsRef = useRef<AvatarQuestions>(\"suggested\");\n /**\n * The question this tab asked as the first of a new chat, in this page's visit; null when none. Recorded only once the\n * chat's `send` says which message it added (see `ask`), and set and cleared through {@link setAskedHere} alone.\n */\n const askedHereRef = useRef<AskedHere | null>(null);\n /**\n * Counts every ask from the box and every clearing of {@link askedHereRef}: an ask whose send resolves after a New\n * chat, a reset, another conversation or a later ask records nothing.\n */\n const askSeqRef = useRef(0);\n /** Re-renders the view when {@link askedHereRef} changes: a ref alone would leave the card unshown. */\n const [, setAskedHereTick] = useState(0);\n const setAskedHere = useCallback((next: AskedHere | null) => {\n if (next === null) {\n askSeqRef.current += 1;\n if (askedHereRef.current === null) return;\n }\n askedHereRef.current = next;\n setAskedHereTick((tick) => tick + 1);\n }, []);\n\n // Compared, never shown: see `getConversationToken`.\n const token = conversation?.getConversationToken() ?? null;\n const exchange = firstExchange(conversation?.messages, {\n any: questions === \"any\",\n askedHere: askedHereRef.current,\n token,\n inFlight: inFlight(conversation),\n });\n // Re-rendered by the timer below at the moment the answer stops being offered: the time is read here, on each render.\n const [ageTick, setAgeTick] = useState(0);\n const shown = offeredAt(exchange, Date.now());\n const { answerId, startOver } = shown;\n /** Until when the answer is offered, while one is. */\n const offerUntil = answerId === null ? null : exchange.offerUntil;\n\n const [phase, setPhase] = useState<Phase>(IDLE);\n const [blocked, setBlocked] = useState(false);\n const [now, setNow] = useState(() => Date.now());\n /** The box's text: the view's own, never the chat's draft. */\n const [draft, setDraft] = useState(\"\");\n /**\n * The longest question the box takes: the avatar service's limit, or the chat's own (the live catalog's) where that is\n * shorter, since the chat refuses a longer one without adding it.\n */\n const chatMaxLength = conversation?.catalog.limits.maxMessageLength;\n const askMaxLength =\n chatMaxLength !== undefined &&\n Number.isFinite(chatMaxLength) &&\n chatMaxLength >= 1\n ? Math.min(ASK_MAX_LENGTH, Math.floor(chatMaxLength))\n : ASK_MAX_LENGTH;\n /** A line the view owes the visitor: a new chat was started for the avatar, or a \"Start when ready\" was called off. */\n const [note, setNote] = useState<\"new-chat\" | \"cancelled\" | null>(null);\n /** This browser noted a live session today (read once the view is on the page). */\n const [usedToday, setUsedToday] = useState(false);\n\n /**\n * The live view is on the page: the Avatar tab is selected in an open panel, and the live avatar is on. It is also\n * hidden while `off` puts the fallback in its place (the panel's locale switching to one whose strings have not been\n * reviewed, say), which unmounts the video and audio elements a room is attached to.\n */\n const showing = active && !off;\n /**\n * Hidden only because the open panel shows its Chat tab: the pane is CSS-hidden, its video and audio elements stay\n * mounted and attached, so a session under way can keep playing (see `leave`).\n */\n const behindChat = open && !active && !off;\n\n const phaseRef = useRef<Phase>(IDLE);\n /** This render's view of everything the asynchronous steps read, so they never act on a stale one. */\n const latest = useRef({\n live,\n locale,\n base,\n headers,\n off,\n currentPath,\n showing,\n });\n latest.current = { live, locale, base, headers, off, currentPath, showing };\n const conversationRef = useRef(conversation);\n conversationRef.current = conversation;\n const waitRef = useRef<WaitRun | null>(null);\n /** A question from the box is on its way to the chat: a second press sends nothing. */\n const sendingRef = useRef(false);\n /** The box asks ordinary questions, whose answers stay text (set each render; see `textBox`). */\n const textBoxRef = useRef(false);\n\n const checkRef = useRef<AbortController | null>(null);\n /**\n * The locale the last availability question was asked for (or settled without asking): a later change of locale asks\n * again (see the effect on `locale`), and a view that has just asked for the new locale does not ask twice.\n */\n const askedLocale = useRef(locale);\n const startRef = useRef<StartRun | null>(null);\n const sessionRef = useRef<SessionHandle | null>(null);\n /**\n * Every answer whose session this visit has already created (or found already read): none of them is offered again.\n * A set and not the latest one: a create the visitor gave up on can answer long after they moved to another chat and\n * used its first answer, and what it reports is added to what is known, never put in its place.\n */\n const claimedRef = useRef<Set<string>>(new Set());\n\n const rootRef = useRef<HTMLDivElement>(null);\n const videoRef = useRef<HTMLVideoElement>(null);\n const audioRef = useRef<HTMLAudioElement>(null);\n const botBoxRef = useRef<HTMLDivElement>(null);\n\n const go = useCallback((next: Phase) => {\n phaseRef.current = next;\n setPhase(next);\n }, []);\n\n /**\n * Whether the visitor can see the view: it is showing, and the page is not hidden. Out of sight, a browser may hold a\n * muted video back (Chrome pauses one that is off screen or in a background tab), so its `playing` cannot be waited\n * for there (see `goLive`).\n */\n const inSight = useCallback(\n (): boolean =>\n latest.current.showing &&\n (typeof document === \"undefined\" ||\n document.visibilityState !== \"hidden\"),\n [],\n );\n\n const setMode = useCallback((next: AvatarQuestions) => {\n questionsRef.current = next;\n setQuestions(next);\n }, []);\n\n /**\n * The exchange right now, read when a step needs it rather than from the last render: the answer may have stopped\n * being offered since (it grew too old while nothing re-rendered), and the server's `questions` may have just changed.\n */\n const exchangeNow = useCallback(\n (): Exchange =>\n offeredAt(\n firstExchange(conversationRef.current?.messages, {\n any: questionsRef.current === \"any\",\n askedHere: askedHereRef.current,\n token: conversationRef.current?.getConversationToken() ?? null,\n inFlight: inFlight(conversationRef.current),\n }),\n Date.now(),\n ),\n [],\n );\n\n /** The answer offered right now (see {@link exchangeNow}). */\n const offeredNow = useCallback(\n (): string | null => exchangeNow().answerId,\n [exchangeNow],\n );\n\n /** The page the visitor is on: the host router's path, else the window's. */\n const pathNow = useCallback(\n (): string =>\n latest.current.currentPath ??\n (typeof window === \"undefined\" ? \"\" : window.location.pathname),\n [],\n );\n\n /** Back to what the offer shows for the answer offered now: its consent card, or the step without one. */\n const reoffer = useCallback(\n (offer: Offer): Phase => {\n const messageId = offeredNow();\n return messageId === null\n ? { name: \"needs-answer\", offer }\n : offering(offer, messageId, claimedRef.current);\n },\n [offeredNow],\n );\n\n /** End the session: tell the server (unless it ended it), leave the room, and show how it ended. */\n const finish = useCallback(\n (how: EndedHow, reason: AvatarEndReason | null) => {\n const handle = sessionRef.current;\n if (!handle || handle.done) return;\n handle.done = true;\n stopAttending(handle);\n sessionRef.current = null;\n if (reason !== null) {\n sendEnd({\n base: handle.base,\n headers: handle.headers,\n sessionId: handle.session.sessionId,\n secret: handle.session.endSecret,\n reason,\n });\n }\n const room = handle.joined;\n handle.joined = null;\n if (room) void room.leave().catch(() => undefined);\n setBlocked(false);\n go({ name: \"ended\", how });\n },\n [go],\n );\n\n /**\n * The avatar is on: its video plays (`playing`), or, while the view is out of sight (the Chat tab, a hidden page),\n * its video has arrived. A browser may hold a muted video back out of sight and play it only once it shows again, so\n * waiting for `playing` there would leave a session that is speaking counted as never started, and ended as failed\n * when the server closes it. Under `any`, the box notes the day's session as used (a hint for the visitor: the limits\n * are the server's).\n */\n const goLive = useCallback(() => {\n const current = phaseRef.current;\n const handle = sessionRef.current;\n if (current.name !== \"pending\" || !handle) return;\n handle.speakerArrived = true;\n if (questionsRef.current === \"any\") {\n noteUsedToday();\n setUsedToday(true);\n }\n go({ name: \"live\", session: current.session });\n }, [go]);\n\n /**\n * The attention rule, under `live.endUnattended` (without it, nothing here runs and nothing changes): a paid session\n * never outlives the visitor's attention. Out of sight (behind the Chat tab, on a hidden page) the answer under way\n * still plays to its end; past that, nothing is paid for that nobody can see or hear:\n *\n * - **Played out** (its speech ended at the source, and {@link PLAYOUT_TAIL_MS} has passed): a live session out of\n * sight ends at once, as finished. This is the lifecycle rule every later stage keeps: **an idle tail after an\n * answer runs only while the Avatar view is in sight**, and going out of sight during it ends the session then. (A\n * session still waiting for the avatar's video is the speaker wait's, {@link SPEAKER_WAIT_MS}.)\n * - **Sound held back** (`playback-blocked`'s `sound`: autoplay refused, or the room's audio context suspended), once\n * the avatar's voice has arrived: in sight, \"Tap to turn on sound\" shows and nothing ends. Out of sight nobody can\n * tap it, so after {@link UNHEARD_GRACE_MS} the session ends early: \"The live avatar stopped early.\" and \"The full\n * answer is in Chat.\". Back in sight, or the sound let through, within the grace: nothing ends.\n *\n * Both send the end with reason `user`, and once (`finish`). Run whenever what it reads changes: the view's sight, the\n * page's, the sound and the playout.\n */\n const attend = useCallback(() => {\n const handle = sessionRef.current;\n if (!handle || handle.done || latest.current.live.endUnattended !== true) {\n return;\n }\n const current = phaseRef.current.name;\n if (current !== \"pending\" && current !== \"live\") return;\n const away = !inSight();\n if (away && handle.playedOut && current === \"live\") {\n finish(\"finished\", \"user\");\n return;\n }\n if (!(away && handle.soundHeld && handle.voiceArrived)) {\n if (handle.unheard !== null) {\n clearTimeout(handle.unheard);\n handle.unheard = null;\n }\n return;\n }\n if (handle.unheard !== null) return;\n handle.unheard = setTimeout(() => {\n handle.unheard = null;\n if (\n sessionRef.current === handle &&\n !handle.done &&\n latest.current.live.endUnattended === true &&\n handle.soundHeld &&\n handle.voiceArrived &&\n !inSight()\n ) {\n finish(\"interrupted\", \"user\");\n }\n }, UNHEARD_GRACE_MS);\n }, [finish, inSight]);\n\n /** Give up on a Start still on its way to a session. A session it still creates is ended with `reason`. */\n const cancelStart = useCallback((reason: AvatarEndReason) => {\n const run = startRef.current;\n if (!run) return;\n startRef.current = null;\n run.cancelled = reason;\n run.turnstile?.cancel();\n }, []);\n\n /**\n * Go to the step an availability answer, asked in `locale`, leads to. A `refused` answer still says which questions the\n * server reads, for the box (a `limits` refusal under `any` keeps the box, asking in text).\n */\n const applyAvailability = useCallback(\n (result: AvatarAvailability, locale: ExploreLocale) => {\n const { live } = latest.current;\n if (result.kind === \"inert\") {\n setMode(\"suggested\");\n go(INERT);\n return;\n }\n if (result.kind === \"refused\") {\n setMode(result.questions);\n go({ name: \"refused\", reason: result.reason });\n return;\n }\n // A fresh answer from the server, a fresh look at this browser's note of the day's session.\n setUsedToday(usedTodayHere());\n // The copy for the version the server named, in the locale it was asked about (a later locale change asks\n // again: see the effect on `locale`).\n const copy = avatarConsentCopy(result.offer.consentVersion, locale);\n // A consent version this SDK has no reviewed copy for: no card, rather than words the server does not record. Nor\n // copy that describes another bot check than the one the server runs, or other questions than the ones it reads:\n // the visitor would agree to a notice that is wrong about it.\n if (\n copy === null ||\n copy.botCheck !== result.offer.botCheck ||\n copy.questions !== result.offer.questions\n ) {\n setMode(\"suggested\");\n go(INERT);\n return;\n }\n // A server that checks for bots, and no site key this page may use for its check: no start could pass it.\n if (\n result.offer.botCheck === \"turnstile\" &&\n turnstileSiteKeyOf(live) === null\n ) {\n setMode(\"suggested\");\n go(INERT);\n return;\n }\n setMode(result.offer.questions);\n go(reoffer({ ...result.offer, locale, copy }));\n },\n [go, reoffer, setMode],\n );\n\n const check = useCallback(() => {\n const { live, locale, base, headers, off } = latest.current;\n checkRef.current?.abort();\n checkRef.current = null;\n askedLocale.current = locale;\n if (off || base === null) {\n go(INERT);\n return;\n }\n const controller = new AbortController();\n checkRef.current = controller;\n go({ name: \"checking\" });\n void requestAvailability({\n base,\n headers,\n site: live.site,\n locale,\n signal: controller.signal,\n }).then((result) => {\n if (checkRef.current !== controller) return;\n checkRef.current = null;\n applyAvailability(result, locale);\n });\n }, [applyAvailability, go]);\n\n const begin = useCallback(\n (\n session: AvatarSession,\n module: AvatarLiveModule,\n offer: Offer,\n target: { base: string; headers: Readonly<Record<string, string>> },\n ) => {\n // Count down on the server's end when this browser's clock agrees with it, else on this browser's own clock.\n const received = Date.now();\n const longest = offer.maxSessionSeconds * 1000;\n const ahead = session.endsAt - received;\n const endsAt =\n ahead > 0 && ahead <= longest + CLOCK_TOLERANCE_MS\n ? session.endsAt\n : received + longest;\n sessionRef.current = {\n session,\n base: target.base,\n headers: target.headers,\n module,\n room: null,\n joined: null,\n endsAt,\n speakerArrived: false,\n voiceArrived: false,\n soundHeld: false,\n playedOut: false,\n unheard: null,\n tail: null,\n done: false,\n };\n setBlocked(false);\n setNow(received);\n go({\n name: \"pending\",\n session: {\n endsAt,\n captions: session.captions,\n excerpt: session.excerpt,\n },\n });\n },\n [go],\n );\n\n const settle = useCallback(\n (\n result: AvatarCreateResult,\n run: StartRun,\n context: {\n module: AvatarLiveModule;\n offer: Offer;\n messageId: string;\n base: string;\n headers: Readonly<Record<string, string>>;\n },\n ) => {\n const created =\n result.kind === \"created\"\n ? {\n sessionId: result.session.sessionId,\n secret: result.session.endSecret,\n }\n : result.kind === \"unusable\"\n ? { sessionId: result.sessionId, secret: result.endSecret }\n : null;\n // A session now exists for this answer (this create made it, or the server says an earlier one did): it is used.\n const claimed =\n created !== null ||\n (result.kind === \"refused\" && result.reason === \"answer_claimed\");\n if (claimed) claimedRef.current.add(context.messageId);\n if (run.cancelled !== null) {\n // Given up while the request was on its way: a session it created is ended at once.\n if (created !== null) {\n sendEnd({\n base: context.base,\n headers: context.headers,\n sessionId: created.sessionId,\n secret: created.secret,\n reason: run.cancelled,\n });\n }\n // The visitor may be back on the consent card for this very answer by now (they left during the create and came\n // back before it answered): it has been read, so the card gives way to saying so rather than offering it again.\n const shown = phaseRef.current;\n if (\n claimed &&\n shown.name === \"consent\" &&\n shown.messageId === context.messageId\n ) {\n go({ name: \"refused\", reason: \"answer_claimed\" });\n }\n return;\n }\n switch (result.kind) {\n case \"created\":\n begin(result.session, context.module, context.offer, context);\n return;\n case \"unusable\":\n sendEnd({\n base: context.base,\n headers: context.headers,\n sessionId: result.sessionId,\n secret: result.endSecret,\n reason: \"client_error\",\n });\n go({ name: \"ended\", how: \"failed\" });\n return;\n case \"refused\":\n go({ name: \"refused\", reason: result.reason });\n return;\n case \"consent\":\n // The consent version moved on: ask again, and show the consent that is current now.\n check();\n return;\n case \"inert\":\n go(INERT);\n return;\n case \"failed\":\n go({ name: \"ended\", how: \"failed\" });\n return;\n }\n },\n [begin, check, go],\n );\n\n /**\n * From the visitor's consent to a session for `messageId`: Start on the card, or a \"Start when ready\" whose answer is\n * now ready and checked (with the room module it has been loading meanwhile, `preloaded`). One create request, never\n * sent again by itself: a failed create ends as failed, and only another tap can start again.\n */\n const launch = useCallback(\n (\n offer: Offer,\n messageId: string,\n preloaded: Promise<AvatarLiveModule> | null,\n ) => {\n const { live, base, headers } = latest.current;\n if (base === null) return;\n const exchangeAtStart = exchangeNow();\n // The answer has grown too old for the service since the card was shown (a timer that has not run yet: a throttled\n // background tab, say), or the conversation has moved on: no request the service would refuse.\n if (exchangeAtStart.answerId !== messageId) {\n go(reoffer(offer));\n return;\n }\n // Already read in this visit (a \"Start when ready\" whose answer a session elsewhere in this visit used): say so.\n if (claimedRef.current.has(messageId)) {\n go({ name: \"refused\", reason: \"answer_claimed\" });\n return;\n }\n // When the service will refuse this answer as too old: the module and a bot check can take a while, and a create\n // that starts after this is not sent.\n const refusedFrom =\n exchangeAtStart.offerUntil - ANSWER_OFFER_MS + SERVICE_MAX_AGE_MS;\n // The key for the bot check, where the server runs one; null where it runs none.\n const siteKey =\n offer.botCheck === \"turnstile\" ? turnstileSiteKeyOf(live) : null;\n // A bot check with no key this page may use, or with no WebCrypto (a page that is not a secure context) to bind it\n // to a create request: no live avatar can start here. Nothing is loaded for a start that cannot happen (no module,\n // no bot-check script), and the tab stays as it was.\n if (\n offer.botCheck === \"turnstile\" &&\n (siteKey === null || !canBindBotCheck())\n ) {\n go(INERT);\n return;\n }\n // The create request's values, read once, here. A bot check is bound to exactly these (`avatarBotBinding`, before its\n // widget is rendered), so the request that follows it carries this same body and reads nothing again.\n const conversationToken =\n conversationRef.current?.getConversationToken() ?? null;\n const idempotencyKey = newIdempotencyKey();\n if (\n conversationToken === null ||\n !isAvatarConversationToken(conversationToken) ||\n idempotencyKey === null\n ) {\n // Nothing to create a session for: no module, no bot check.\n go({ name: \"ended\", how: \"failed\" });\n return;\n }\n const body: AvatarCreateBody = {\n site: live.site,\n locale: offer.locale,\n conversationToken,\n messageId,\n consentVersion: offer.consentVersion,\n manifestVersion: live.manifestVersion,\n };\n const run: StartRun = { cancelled: null, turnstile: null };\n startRef.current = run;\n // Only now that the visitor has agreed: the live module (already loading, for a \"Start when ready\"), and the bot\n // check where the server runs one. Where it runs none, there is no Cloudflare script, no widget and no token: the\n // module loads and the request follows.\n const module = preloaded ?? loadModule(live.load);\n let turnstile: TurnstileRun | null = null;\n if (siteKey === null) {\n go({ name: \"creating\" });\n } else {\n go({ name: \"bot-check\", offer, messageId });\n turnstile = runTurnstile(\n botBoxRef.current,\n siteKey,\n \"avatar_start\",\n avatarBotBinding(body),\n );\n run.turnstile = turnstile;\n }\n void (async () => {\n let loaded: AvatarLiveModule;\n let botToken: string | undefined;\n try {\n [loaded, botToken] = await Promise.all([module, turnstile?.token]);\n } catch {\n turnstile?.cancel();\n if (run.cancelled === null) {\n startRef.current = null;\n go(INERT);\n }\n return;\n }\n // The widget has done its work.\n turnstile?.cancel();\n if (run.cancelled !== null) return;\n // The answer grew too old for the service while the module or the bot check took their time: nothing is created,\n // and the view says to start a new chat (it reads the answer as too old now).\n if (!(Date.now() < refusedFrom)) {\n startRef.current = null;\n go({ name: \"needs-answer\", offer });\n return;\n }\n if (turnstile !== null) go({ name: \"creating\" });\n const result = await requestCreate({\n base,\n headers,\n idempotencyKey,\n botToken,\n body,\n });\n if (startRef.current === run) startRef.current = null;\n settle(result, run, {\n module: loaded,\n offer,\n messageId,\n base,\n headers,\n });\n })();\n },\n [exchangeNow, go, reoffer, settle],\n );\n\n /** Start, on the consent card. Under `any`, the tap also lets the page play the avatar's sound later. */\n const start = useCallback(() => {\n const current = phaseRef.current;\n if (current.name !== \"consent\") return;\n if (current.offer.questions === \"any\") unlockSound(audioRef.current);\n launch(current.offer, current.messageId, null);\n }, [launch]);\n\n /**\n * Call off a \"Start when ready\": nothing is created, and the view goes back to the answer being written (or to what\n * the conversation now is). `told`: the visitor did not cancel it themselves, so the view says it did not start.\n */\n const cancelWaiting = useCallback(\n (told: boolean) => {\n const wait = waitRef.current;\n waitRef.current = null;\n wait?.check?.abort();\n const current = phaseRef.current;\n if (current.name !== \"waiting\") return;\n if (told) setNote(\"cancelled\");\n go({ name: \"needs-answer\", offer: current.offer });\n },\n [go],\n );\n\n /** Whether what a \"Start when ready\" was bound to still holds, for the exchange as it is now. */\n const bindingHolds = useCallback(\n (bound: WaitRun[\"bound\"], exchange: Exchange): boolean => {\n const { live, locale } = latest.current;\n return (\n conversationRef.current?.getConversationToken() === bound.token &&\n exchange.question?.id === bound.questionId &&\n live.site === bound.site &&\n locale === bound.locale &&\n pathNow() === bound.path\n );\n },\n [pathNow],\n );\n\n /**\n * \"Start when ready\", on the card shown while the answer is written: the visitor's consent for this conversation's\n * first answer, once it is ready (see {@link WaitRun}). Pressed only for a question this tab asked as the first of a\n * new chat, once the server has taken it.\n */\n const startWhenReady = useCallback(() => {\n const current = phaseRef.current;\n if (current.name !== \"needs-answer\") return;\n const { live, locale } = latest.current;\n const exchange = exchangeNow();\n const token = conversationRef.current?.getConversationToken() ?? null;\n if (\n exchange.kind !== \"asking\" ||\n !exchange.askedHere ||\n exchange.question === null ||\n exchange.pendingAnswerId === null ||\n token === null ||\n !isAvatarConversationToken(token)\n ) {\n return;\n }\n unlockSound(audioRef.current);\n const module = loadModule(live.load);\n // Read when the answer is ready; a failure then is the start's. Until then, nothing is left unhandled.\n module.catch(() => undefined);\n waitRef.current = {\n bound: {\n token,\n questionId: exchange.question.id,\n answerId: exchange.pendingAnswerId,\n site: live.site,\n locale,\n path: pathNow(),\n consentVersion: current.offer.consentVersion,\n botCheck: current.offer.botCheck,\n },\n module,\n check: null,\n };\n setNote(null);\n go({ name: \"waiting\", offer: current.offer });\n }, [exchangeNow, go, pathNow]);\n\n /**\n * The answer a \"Start when ready\" waited for is ready: ask availability again (no cache) and check the answer again,\n * and create only if nothing differs. Anything that does (another consent version or bot check, a refusal, the answer\n * or the conversation) shows what is offered now instead: the card again, or why there is none.\n */\n const confirm = useCallback(\n (offer: Offer, wait: WaitRun) => {\n const { live, locale, base, headers } = latest.current;\n if (base === null) {\n cancelWaiting(true);\n return;\n }\n const controller = new AbortController();\n wait.check = controller;\n void requestAvailability({\n base,\n headers,\n site: live.site,\n locale,\n signal: controller.signal,\n }).then((result) => {\n if (waitRef.current !== wait || phaseRef.current.name !== \"waiting\") {\n return;\n }\n waitRef.current = null;\n // (A change of locale while this was asked has already called the start off, dropping this answer: see the\n // effect on `locale`. So it is the answer for the locale the panel is in.)\n const exchange = exchangeNow();\n const same =\n result.kind === \"available\" &&\n result.offer.consentVersion === wait.bound.consentVersion &&\n result.offer.botCheck === wait.bound.botCheck &&\n result.offer.questions === \"any\" &&\n exchange.kind === \"answer\" &&\n exchange.answerId === wait.bound.answerId &&\n bindingHolds(wait.bound, exchange);\n if (!same || result.kind !== \"available\") {\n applyAvailability(result, locale);\n return;\n }\n // The offer as it is now (the same version, bot check and questions; the session's length may have moved).\n launch({ ...offer, ...result.offer }, wait.bound.answerId, wait.module);\n });\n },\n [applyAvailability, bindingHolds, cancelWaiting, exchangeNow, launch],\n );\n\n /** The visitor's Stop, at any step from Start on (and Cancel, for a \"Start when ready\"). */\n const stop = useCallback(() => {\n const current = phaseRef.current;\n if (current.name === \"waiting\") {\n cancelWaiting(false);\n return;\n }\n if (current.name === \"bot-check\") {\n // Nothing was created: back to the consent card, if its answer is still offered.\n cancelStart(\"user\");\n go(reoffer(current.offer));\n return;\n }\n if (current.name === \"creating\") {\n cancelStart(\"user\");\n go({ name: \"ended\", how: \"stopped\" });\n return;\n }\n if (current.name === \"pending\" || current.name === \"live\") {\n finish(\"stopped\", \"user\");\n }\n }, [cancelStart, cancelWaiting, finish, go, reoffer]);\n\n /**\n * The view going out of the visitor's sight, by what took it away:\n *\n * - `user`: the panel closing, or the live avatar going off (the fallback takes the view's place, unmounting the\n * video and audio a room is attached to, and Stop with them). Everything under way ends, a session with `user`.\n * - `chat`: the open panel showing its Chat tab instead. Before the create is sent nothing paid exists, so it is\n * called off as `user` would (C3): a check is dropped (opening the view asks again), a \"Start when ready\" and a bot\n * check are called off with nothing created. From the create on (`creating`, `pending`, `live`) nothing ends: the\n * pane is only hidden, the room's video and audio stay attached, and the avatar speaks to its planned end.\n * - `hidden`: the page hidden (another browser tab, another app). A \"Start when ready\" is called off and a bot check\n * goes back to the consent card, so the view is as the visitor left it when they come back; a check is kept. From\n * the create on nothing ends, as for `chat`: the server ends the session at its planned end, so a hidden page adds\n * no paid time.\n * - `page_hide`: the page being left (`pagehide`). Everything ends, a session with `page_hide`; a check is kept.\n *\n * Out of sight with a session whose video has already arrived, it is counted as live (see `goLive`). What a session\n * kept out of sight may still end on is the attention rule's (`attend`), under `live.endUnattended`.\n */\n const leave = useCallback(\n (event: \"user\" | \"chat\" | \"hidden\" | \"page_hide\") => {\n const current = phaseRef.current;\n const reason: AvatarEndReason =\n event === \"user\" || event === \"chat\" ? \"user\" : \"page_hide\";\n const how: EndedHow = reason === \"user\" ? \"stopped\" : \"interrupted\";\n /** Once the create has been sent, only the panel closing, the live avatar going off and leaving the page end it. */\n const keepsSession = event === \"chat\" || event === \"hidden\";\n switch (current.name) {\n case \"checking\": {\n if (reason !== \"user\") return;\n const controller = checkRef.current;\n checkRef.current = null;\n controller?.abort();\n go(IDLE);\n return;\n }\n case \"waiting\":\n // A \"Start when ready\" is for this view as the visitor left it: called off, with nothing created.\n cancelWaiting(true);\n return;\n case \"bot-check\":\n cancelStart(reason);\n go(reason === \"user\" ? IDLE : reoffer(current.offer));\n return;\n case \"creating\":\n if (keepsSession) return;\n cancelStart(reason);\n go({ name: \"ended\", how });\n return;\n case \"pending\":\n case \"live\":\n if (keepsSession) {\n if (\n current.name === \"pending\" &&\n sessionRef.current?.speakerArrived\n ) {\n goLive();\n }\n return;\n }\n finish(how, reason);\n return;\n default:\n return;\n }\n },\n [cancelStart, cancelWaiting, finish, go, goLive, reoffer],\n );\n\n // The Avatar view showing, and hiding. Opening it asks again, except where this visit has already used the answer,\n // and except during a session, which shows as it is, counting down to its end.\n //\n // Hidden behind the Chat tab, a session under way keeps playing (`leave(\"chat\")`). Anything else that hides the view\n // (the panel closing, the live avatar going off) ends whatever is under way (`leave(\"user\")`): a bot check is called\n // off, a create in flight is ended once it answers, a session is ended and its room left. Coming back asks again.\n useEffect(() => {\n if (!showing) {\n leave(behindChat ? \"chat\" : \"user\");\n return;\n }\n const current = phaseRef.current;\n if (\n current.name === \"creating\" ||\n current.name === \"pending\" ||\n current.name === \"live\"\n ) {\n // Back during a session, after the Chat tab: nothing is asked again and nothing reset. The countdown is to the\n // session's end as `begin` set it, and is brought up to date at once rather than at its next tick.\n setNow(Date.now());\n return;\n }\n const offered = offeredNow();\n const used = offered !== null && claimedRef.current.has(offered);\n if (current.name === \"ended\" && used) return;\n if (\n current.name === \"refused\" &&\n current.reason === \"answer_claimed\" &&\n used\n ) {\n return;\n }\n if (\n current.name === \"idle\" ||\n current.name === \"inert\" ||\n current.name === \"refused\" ||\n current.name === \"needs-answer\" ||\n current.name === \"consent\" ||\n current.name === \"declined\" ||\n current.name === \"ended\" ||\n // Asking, with nothing actually asking: React's strict mode unmounts and mounts a component again with the state it\n // left, and the unmount in between dropped the question. (This view mounts already showing, the first time the\n // Avatar view opens.)\n (current.name === \"checking\" && checkRef.current === null)\n ) {\n check();\n }\n }, [showing, behindChat, check, leave, offeredNow]);\n\n // The attention rule (`attend`), each time the view comes into sight or goes out of it, once the effect above has\n // dealt with the move (the page's own sight is the visibility handler's, below).\n useEffect(() => {\n attend();\n }, [showing, attend]);\n\n // The panel's locale changing before Start: an availability answer, and the consent copy chosen for it, belong to the\n // locale they were asked about, so the view asks again (or, hidden, starts over when it next opens). A session already\n // under way keeps its own. A \"Start when ready\" is bound to its locale: it is called off, with nothing created (and\n // the availability question it may be asking again for the old locale is dropped with it), and the view asks again\n // for the new one.\n useEffect(() => {\n if (askedLocale.current === locale) return;\n askedLocale.current = locale;\n if (phaseRef.current.name === \"waiting\") cancelWaiting(true);\n const current = phaseRef.current.name;\n if (\n current !== \"checking\" &&\n current !== \"needs-answer\" &&\n current !== \"consent\" &&\n current !== \"declined\" &&\n current !== \"refused\" &&\n current !== \"inert\"\n ) {\n return;\n }\n if (active) {\n check();\n } else {\n checkRef.current?.abort();\n checkRef.current = null;\n go(IDLE);\n }\n }, [active, cancelWaiting, check, go, locale]);\n\n // The first answer arriving (it may complete while the Avatar view shows), or the conversation starting over.\n const kind = shown.kind;\n useEffect(() => {\n const current = phaseRef.current;\n if (current.name === \"needs-answer\" && answerId !== null) {\n go({ name: \"consent\", offer: current.offer, messageId: answerId });\n } else if (current.name === \"consent\" && current.messageId !== answerId) {\n go(\n answerId === null\n ? { name: \"needs-answer\", offer: current.offer }\n : { ...current, messageId: answerId },\n );\n } else if (current.name === \"declined\" && answerId === null) {\n // Not now, and then the conversation moved on (a new chat, say): nothing is declined any more.\n if (kind !== \"asking\") go({ name: \"needs-answer\", offer: current.offer });\n }\n }, [answerId, kind, go]);\n\n // A \"Start when ready\" while its answer is written: on every render, whatever changed (the conversation, its answer,\n // the page, the locale). It holds while the answer it is bound to is on its way; once that answer is ready and passes\n // the checks this browser can make, it is confirmed (`confirm`); anything else calls it off, with nothing created. A\n // failed or unreadable answer then says why itself; anything else says the start was called off.\n useEffect(() => {\n const current = phaseRef.current;\n const wait = waitRef.current;\n if (current.name !== \"waiting\" || wait === null || wait.check !== null) {\n return;\n }\n const now = exchangeNow();\n const holds = bindingHolds(wait.bound, now);\n if (\n holds &&\n now.kind === \"asking\" &&\n now.pendingAnswerId === wait.bound.answerId\n ) {\n return;\n }\n if (\n !holds ||\n now.kind !== \"answer\" ||\n now.answerId !== wait.bound.answerId\n ) {\n cancelWaiting(now.kind !== \"failed\" && now.kind !== \"text-only\");\n return;\n }\n confirm(current.offer, wait);\n });\n\n // A question asked here that Chat's Retry sent again is still the one asked here: the retry's question replaces it\n // (first the one shown while it is on its way, then the server's own, with the token the server may have just\n // minted; each names every id the question had). Declared before the two effects below, which run in the same commit\n // as the change it follows: the record moves to the new question (and its token) before they compare it.\n const resent = conversation?.resent ?? null;\n useEffect(() => {\n const asked = askedHereRef.current;\n if (\n resent === null ||\n asked === null ||\n !resent.replacedMessageIds.includes(asked.messageId)\n ) {\n return;\n }\n setAskedHere({\n messageId: resent.sent.userMessageId,\n token: resent.sent.conversationToken,\n });\n }, [resent, setAskedHere]);\n\n // The question this tab asked is the first of its chat only while that chat lasts: a conversation that empties (New\n // chat, in either tab) has no question asked here.\n const empty = (conversation?.messages.length ?? 0) === 0;\n useEffect(() => {\n if (empty) setAskedHere(null);\n }, [empty, setAskedHere]);\n // And it belongs to the conversation its send ended in, and no other: another token (a conversation opened from\n // History, say, whatever its first question says) ends it.\n useEffect(() => {\n const asked = askedHereRef.current;\n if (asked !== null && asked.token !== token) setAskedHere(null);\n }, [token, setAskedHere]);\n\n // This browser's note of a session today, read each time the view shows (never while rendering on a server), so a\n // page left open past midnight (UTC) has the new day's session.\n useEffect(() => {\n if (showing) setUsedToday(usedTodayHere());\n }, [showing]);\n\n // The answer stops being offered at `offerUntil`: one timer for that moment, set again for a new answer, and cleared\n // when the answer changes or the view goes. It re-renders the view, which then reads the answer as too old (and the\n // effect above moves a consent card to the start-over step). A timer that ran early, or a deadline past the longest\n // delay a timer keeps, is simply set again (`ageTick`).\n useEffect(() => {\n if (offerUntil === null) return;\n const timer = setTimeout(\n () => setAgeTick((tick) => tick + 1),\n Math.min(MAX_TIMER_MS, Math.max(0, offerUntil - Date.now())),\n );\n return () => clearTimeout(timer);\n }, [offerUntil, ageTick]);\n\n /** Start over: the chat's own New chat (the conversation's `reset`), then the Chat tab and its suggested questions. */\n const startNewChat = useCallback(() => {\n conversationRef.current?.reset();\n onContinueInChat();\n }, [onContinueInChat]);\n\n const onRoomEvent = useCallback(\n (handle: SessionHandle, event: ReceiveOnlyEvent) => {\n if (handle.done || sessionRef.current !== handle) return;\n const wasLive = phaseRef.current.name === \"live\";\n switch (event.type) {\n case \"speaker-track\":\n if (event.kind !== \"video\") {\n handle.voiceArrived = true;\n attend();\n return;\n }\n handle.speakerArrived = true;\n // Out of sight, the video's own `playing` may not come until the view shows again.\n if (!inSight()) goLive();\n return;\n case \"playback-blocked\":\n setBlocked(event.blocked);\n handle.soundHeld = event.sound ?? event.blocked;\n attend();\n return;\n case \"speech-ended\":\n // Under `endUnattended` only: the answer counts as played out once the worker's lag has had its time.\n if (\n latest.current.live.endUnattended !== true ||\n handle.tail !== null ||\n handle.playedOut\n ) {\n return;\n }\n handle.tail = setTimeout(() => {\n handle.tail = null;\n if (sessionRef.current !== handle || handle.done) return;\n handle.playedOut = true;\n attend();\n }, PLAYOUT_TAIL_MS);\n return;\n case \"speaker-left\":\n finish(\n wasLive ? \"finished\" : \"failed\",\n wasLive ? null : \"client_error\",\n );\n return;\n case \"disconnected\":\n if (event.byServer) finish(wasLive ? \"finished\" : \"failed\", null);\n else finish(wasLive ? \"interrupted\" : \"failed\", \"client_error\");\n return;\n }\n },\n [attend, finish, goLive, inSight],\n );\n\n // A created session: join its room once the video and audio elements are on the page.\n useEffect(() => {\n if (phase.name !== \"pending\") return;\n const handle = sessionRef.current;\n if (!handle || handle.room !== null || handle.done) return;\n const video = videoRef.current;\n const audio = audioRef.current;\n if (!video || !audio) {\n finish(\"failed\", \"client_error\");\n return;\n }\n let joining: Promise<ReceiveOnlySession>;\n try {\n joining = handle.module.joinReceiveOnly({\n url: handle.session.join.livekitUrl,\n token: handle.session.join.participantToken,\n workerIdentity: handle.session.join.workerIdentity,\n video,\n audio,\n onEvent: (event) => onRoomEvent(handle, event),\n });\n } catch (error) {\n joining = Promise.reject(error);\n }\n handle.room = joining.then(\n (room) => {\n if (handle.done) {\n void room.leave().catch(() => undefined);\n return null;\n }\n handle.joined = room;\n return room;\n },\n () => {\n if (!handle.done) finish(\"failed\", \"client_error\");\n return null;\n },\n );\n }, [phase.name, finish, onRoomEvent]);\n\n // While a session lasts: give up on a speaker who never comes, and leave a room still open after the session's end.\n useEffect(() => {\n if (phase.name !== \"pending\" && phase.name !== \"live\") return;\n const handle = sessionRef.current;\n if (!handle) return;\n const timers: Array<ReturnType<typeof setTimeout>> = [];\n if (phase.name === \"pending\") {\n timers.push(\n setTimeout(() => {\n if (sessionRef.current === handle && !handle.speakerArrived) {\n finish(\"failed\", \"client_error\");\n }\n }, SPEAKER_WAIT_MS),\n );\n }\n timers.push(\n setTimeout(\n () => {\n if (sessionRef.current !== handle) return;\n finish(\n phaseRef.current.name === \"live\" ? \"finished\" : \"failed\",\n \"client_error\",\n );\n },\n Math.max(0, handle.endsAt + END_GRACE_MS - Date.now()),\n ),\n );\n return () => timers.forEach((timer) => clearTimeout(timer));\n }, [phase.name, finish]);\n\n // The countdown: once a second while a session lasts.\n const ticking = phase.name === \"pending\" || phase.name === \"live\";\n useEffect(() => {\n if (!ticking) return;\n const timer = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(timer);\n }, [ticking]);\n\n // The avatar's voice is the page's from the create until the session ends: the panel is told its status line then,\n // and null otherwise (and when the view goes), and holds Chat's own read-aloud and dictation meanwhile.\n const voiceLine =\n phase.name === \"live\"\n ? S.speaking\n : phase.name === \"creating\" || phase.name === \"pending\"\n ? S.connecting\n : null;\n const onVoiceHoldRef = useRef(onVoiceHold);\n onVoiceHoldRef.current = onVoiceHold;\n useEffect(() => {\n onVoiceHoldRef.current?.(voiceLine);\n }, [voiceLine]);\n useEffect(() => () => onVoiceHoldRef.current?.(null), []);\n\n // Leaving the page ends a session. Hiding it (another browser tab, another app) calls off only what has not been sent\n // yet: a session keeps playing to its planned end, which the server keeps either way (see `leave`), unless the\n // attention rule ends it sooner (`attend`). The page showing again brings the countdown up to date at once: a hidden\n // page's timers may have been held back.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onPageHide = () => leave(\"page_hide\");\n const onVisibility = () => {\n if (document.visibilityState === \"hidden\") {\n leave(\"hidden\");\n attend();\n return;\n }\n const current = phaseRef.current.name;\n if (current === \"pending\" || current === \"live\") setNow(Date.now());\n attend();\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onVisibility);\n return () => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n };\n }, [attend, leave]);\n\n // Unmounted with something under way: end it, as closing the panel would.\n useEffect(\n () => () => {\n const controller = checkRef.current;\n checkRef.current = null;\n controller?.abort();\n const run = startRef.current;\n startRef.current = null;\n if (run) {\n run.cancelled = \"user\";\n run.turnstile?.cancel();\n }\n const wait = waitRef.current;\n waitRef.current = null;\n wait?.check?.abort();\n const handle = sessionRef.current;\n sessionRef.current = null;\n if (handle && !handle.done) {\n handle.done = true;\n stopAttending(handle);\n sendEnd({\n base: handle.base,\n headers: handle.headers,\n sessionId: handle.session.sessionId,\n secret: handle.session.endSecret,\n reason: \"user\",\n });\n if (handle.joined) void handle.joined.leave().catch(() => undefined);\n }\n },\n [],\n );\n\n const any = questions === \"any\";\n /**\n * Under `any`, the tab asks in text: the day's session is used (this browser's note of it, which a session that\n * played and has now ended leaves too), or the server says its limit is reached. The box then sends ordinary\n * questions, without `surface`, and their answers show here as text (after a session, under how it ended).\n */\n const textMode =\n any &&\n ((usedToday &&\n (phase.name === \"needs-answer\" ||\n phase.name === \"consent\" ||\n phase.name === \"declined\" ||\n phase.name === \"ended\")) ||\n (phase.name === \"refused\" && phase.reason === \"limits\"));\n // The box asks in text exactly where the tab shows the answers as text (see `ask`).\n textBoxRef.current = textMode;\n /** Under `any`: which of the Avatar tab's states shows, on the view's root (for tests and a site's own checks). */\n const askState = !any\n ? undefined\n : textMode\n ? \"text\"\n : phase.name === \"needs-answer\"\n ? kind === \"empty\"\n ? \"ready\"\n : kind\n : phase.name;\n\n /**\n * Not now. Under `any` the visitor stays on the tab, told the answer is in Chat (the card is offered again when the tab\n * next opens, while the answer is fresh); otherwise, as before, back to the Chat tab.\n */\n const notNow = useCallback(() => {\n const current = phaseRef.current;\n if (\n (current.name === \"consent\" || current.name === \"needs-answer\") &&\n current.offer.questions === \"any\"\n ) {\n go({ name: \"declined\", offer: current.offer });\n return;\n }\n onContinueInChat();\n }, [go, onContinueInChat]);\n\n /**\n * Ask `text` from the box (or a chip). For the avatar, it is the first question of a new chat, sent with `surface:\n * \"AVATAR\"`, so its answer is the one the card offers. It is remembered as asked here only once the chat's `send` says\n * it added it, bound to the USER message it added and the conversation it ended in; a send that added nothing (too\n * long a question, another question already on its way, a disabled chat) leaves nothing remembered, so the same words\n * asked later in Chat never get the card, and puts the question back in the box. In text (see `textMode`), an ordinary question, without `surface`, into the\n * chat as it is. Never resets the conversation: a chat that is not new is started over only by the visitor's own \"New\n * chat for the avatar\". One question at a time: a second press while the first is on its way sends nothing.\n */\n const ask = useCallback(\n (text: string) => {\n const conversation = conversationRef.current;\n const question = text.trim();\n if (conversation === null || question === \"\" || sendingRef.current) {\n return;\n }\n const spoken = !textBoxRef.current;\n if (spoken && conversation.messages.length > 0) return;\n sendingRef.current = true;\n // Whatever was remembered goes: only this ask's own send can put a question back.\n setAskedHere(null);\n const seq = askSeqRef.current;\n setNote(null);\n setDraft(\"\");\n void conversation\n .send(question, [], spoken ? { surface: \"AVATAR\" } : {})\n .then((added) => {\n // The chat added nothing (over its own length or turn limit, another question on its way, a disabled chat):\n // the question goes back into the box, unless the visitor has typed something else since, so it is never\n // silently lost.\n if (added === null) {\n setDraft((current) => (current === \"\" ? question : current));\n }\n if (\n !spoken ||\n added === null ||\n askSeqRef.current !== seq ||\n added.conversationToken !==\n (conversationRef.current?.getConversationToken() ?? null)\n ) {\n return;\n }\n setAskedHere({\n messageId: added.userMessageId,\n token: added.conversationToken,\n });\n })\n .finally(() => {\n sendingRef.current = false;\n });\n },\n [setAskedHere],\n );\n\n /**\n * \"New chat for the avatar\": the visitor's own start over, where this conversation can no longer be read. The chat's\n * New chat (the conversation's `reset`, so the chat being left stays in History), staying on the Avatar tab, whose\n * box then asks for the avatar. A failed question goes back into the box, if the box is empty.\n */\n const newChatForAvatar = useCallback(() => {\n const conversation = conversationRef.current;\n if (conversation === null) return;\n const now = exchangeNow();\n const failedQuestion =\n now.kind === \"failed\" ? (now.question?.content ?? null) : null;\n conversation.reset();\n setAskedHere(null);\n setNote(\"new-chat\");\n if (failedQuestion !== null) {\n setDraft((current) => (current === \"\" ? failedQuestion : current));\n }\n const current = phaseRef.current;\n if (\n current.name === \"needs-answer\" ||\n current.name === \"consent\" ||\n current.name === \"declined\"\n ) {\n go({ name: \"needs-answer\", offer: current.offer });\n } else {\n // From a refusal or a session's end: ask again whether the avatar is offered, for the new chat.\n check();\n }\n }, [check, exchangeNow, go, setAskedHere]);\n\n // Each step's own control takes focus when the one the visitor was on has gone (Start, once pressed, say): focus\n // left on the page's body would also take Escape out of the panel. \"Tap to turn on sound\" is one of those controls:\n // it goes the moment playback resumes (`blocked` clears), so focus moves on to Stop rather than falling to the body.\n useEffect(() => {\n if (!active) return;\n const focused = document.activeElement;\n if (focused && focused !== document.body && focused.isConnected) return;\n rootRef.current?.querySelector<HTMLElement>(PRIMARY)?.focus();\n // (The card's arrival while the answer is written is a step of its own here: its Start when ready takes focus from\n // the box the question was asked from, which has gone.)\n }, [active, phase.name, askState, shown.pendingAnswerId, blocked]);\n\n // The avatar's video plays: the session is live (`goLive`).\n const onPlaying = goLive;\n\n const enablePlayback = useCallback(() => {\n // Called straight from the tap: browsers allow sound only from inside the visitor's gesture.\n void sessionRef.current?.joined?.enablePlayback().catch(() => undefined);\n }, []);\n\n if (off || phase.name === \"inert\") {\n return (\n // `display: contents`: the earlier Avatar view's picture, line and button lay out in the pane exactly as before.\n <div\n ref={rootRef}\n style={{ display: \"contents\" }}\n data-boff-explore=\"avatar-live\"\n data-phase={off ? \"off\" : \"inert\"}\n >\n {fallback}\n </div>\n );\n }\n\n const primaryButton =\n \"inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background motion-reduce:transition-none\";\n const secondaryButton =\n \"inline-flex items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background motion-reduce:transition-none\";\n const stillPicture = (small: boolean) => (\n <img\n src={still.src}\n alt={still.alt}\n decoding=\"async\"\n width={small ? 64 : 128}\n height={small ? 64 : 128}\n className={cn(\n \"shrink-0 rounded-full border border-border object-cover shadow-sm\",\n small\n ? \"h-16 w-16\"\n : any\n ? \"h-[min(12rem,32dvh)] w-[min(12rem,32dvh)]\"\n : \"h-32 w-32\",\n )}\n />\n );\n const continueButton = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-continue\"\n className={primaryButton}\n onClick={onContinueInChat}\n >\n {continueInChat}\n </button>\n );\n /** Where this conversation can never be read: New chat first, and Continue in Chat beside it. */\n const startOverActions = (\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-new-chat\"\n className={primaryButton}\n onClick={startNewChat}\n >\n {newChat}\n </button>\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-continue\"\n className={secondaryButton}\n onClick={onContinueInChat}\n >\n {continueInChat}\n </button>\n </div>\n );\n const stopButton = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-stop\"\n className={secondaryButton}\n onClick={stop}\n >\n {S.stop}\n </button>\n );\n /** Under `any`: to the Chat tab, where the answer and its sources are. */\n const readInChatButton = (primary: boolean) => (\n <button\n type=\"button\"\n data-avatar-primary={primary ? \"\" : undefined}\n data-boff-explore=\"avatar-live-read-in-chat\"\n className={primary ? primaryButton : secondaryButton}\n onClick={onContinueInChat}\n >\n {S.readInChat}\n </button>\n );\n /** The consent card: exactly its four lines and the privacy link (the notice's digest is taken over them). */\n const consentCard = (copy: AvatarConsentCopy) => (\n <section\n aria-labelledby={consentTitleId}\n data-boff-explore=\"avatar-live-consent\"\n className=\"w-full max-w-sm rounded-lg border border-border p-4 text-start\"\n >\n <h2 id={consentTitleId} className=\"text-base font-semibold\">\n {copy.title}\n </h2>\n <p className=\"mt-2 text-sm\">\n {productName === null || copy.introProduct === null\n ? copy.intro\n : fill(copy.introProduct, { product: productName })}\n </p>\n <p className=\"mt-2 text-sm text-muted-foreground\">{copy.processing}</p>\n <p className=\"mt-2 text-sm text-muted-foreground\">{copy.storage}</p>\n <a\n href={PRIVACY_HREF}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-boff-explore=\"avatar-live-privacy\"\n className=\"mt-2 inline-block text-sm font-medium text-primary underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {copy.privacyLink}\n <span className=\"sr-only\"> {S.opensInNewTab}</span>\n </a>\n </section>\n );\n /** The card's buttons: Start (or, while the answer is written, Start when ready) and Not now. */\n const consentActions = (whenReady: boolean) => (\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore={\n whenReady ? \"avatar-live-start-when-ready\" : \"avatar-live-start\"\n }\n className={primaryButton}\n onClick={whenReady ? startWhenReady : start}\n >\n {whenReady ? S.startWhenReady : S.start}\n </button>\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-not-now\"\n className={secondaryButton}\n onClick={notNow}\n >\n {S.notNow}\n </button>\n </div>\n );\n const liveMedia = (playing: boolean) => (\n <div\n className={cn(\n \"relative shrink-0 overflow-hidden rounded-xl border border-border bg-muted\",\n any ? \"h-[min(12rem,32dvh)] w-[min(12rem,32dvh)]\" : \"h-48 w-48\",\n )}\n >\n <video\n ref={videoRef}\n aria-label={S.video}\n data-boff-explore=\"avatar-live-video\"\n playsInline\n autoPlay\n muted\n onPlaying={onPlaying}\n className={cn(\"h-full w-full object-cover\", !playing && \"opacity-0\")}\n />\n {playing ? null : (\n <img\n src={still.src}\n alt=\"\"\n decoding=\"async\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n )}\n {/* Under `any`, the audio element is the view's own, so that Start's tap can let it play (see `unlockSound`). */}\n {any ? null : (\n <audio ref={audioRef} data-boff-explore=\"avatar-live-audio\" />\n )}\n </div>\n );\n /**\n * The status line while the avatar speaks. Where the server speaks only the first part of the answer (Stage B), the\n * line says so, and that the full answer is in Chat, in place of \"The avatar is speaking.\": the same slot, so the\n * layout is the same whether or not a cap applies.\n */\n const speakingLine = (session: ShownSession) =>\n session.excerpt ? S.excerpt : S.speaking;\n const liveBody = (session: ShownSession) => (\n <>\n <section\n aria-label={S.captions}\n data-boff-explore=\"avatar-live-captions\"\n lang={session.captions.locale || undefined}\n dir=\"auto\"\n tabIndex={0}\n className=\"max-h-32 w-full max-w-sm overflow-y-auto rounded-lg bg-muted p-3 text-start text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {session.captions.text}\n </section>\n <p className=\"text-xs text-muted-foreground\">{S.answerInChat}</p>\n <p className=\"text-sm tabular-nums text-muted-foreground\">\n {S.timeLeft}{\" \"}\n <span role=\"timer\" data-boff-explore=\"avatar-live-countdown\">\n {clock(Math.max(0, (session.endsAt - now) / 1000))}\n </span>\n </p>\n </>\n );\n /** A session's buttons: the sound, where the browser holds it back, Stop, and the way back to the chat. */\n const liveActions = (back: ReactNode) => (\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n {blocked ? (\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-sound\"\n className={primaryButton}\n onClick={enablePlayback}\n >\n {S.tapForSound}\n </button>\n ) : null}\n {stopButton}\n {back}\n </div>\n );\n const badge = (\n <p\n data-boff-explore=\"avatar-live-badge\"\n className=\"rounded-full bg-muted px-3 py-1 text-xs font-medium text-foreground\"\n >\n {S.badge}\n </p>\n );\n\n if (any) {\n // The Avatar tab with its own question box: a stage that scrolls (the picture or the video, the status, the card or\n // the captions, the question) over a foot that stays (the chips, the box and the line under it).\n let status = \"\";\n let outcome = false;\n let lead: ReactNode = null;\n let top: ReactNode = null;\n let media: ReactNode = stillPicture(false);\n let body: ReactNode = null;\n let actions: ReactNode = null;\n let newChatOffer = false;\n let box: \"spoken\" | \"text\" | null = null;\n const first = exchange.question;\n const questionLine =\n first === null ? null : (\n <p\n data-boff-explore=\"avatar-live-question\"\n dir=\"auto\"\n className=\"line-clamp-2 w-full max-w-sm break-words text-sm font-medium\"\n >\n {first.content}\n </p>\n );\n const activity = conversation?.activity ?? null;\n const activityLine =\n activity === null ? null : (\n <p\n data-boff-explore=\"avatar-live-activity\"\n className=\"text-xs text-muted-foreground\"\n >\n {activity}\n </p>\n );\n\n if (textMode) {\n // The day's session is used (or the server says its limit is reached): the box asks ordinary questions, and the\n // answer shows here as text.\n const messages = conversation?.messages ?? [];\n let questionAt = messages.length - 1;\n while (questionAt >= 0 && messages[questionAt]?.role !== \"USER\") {\n questionAt -= 1;\n }\n const lastQuestion = questionAt === -1 ? undefined : messages[questionAt];\n // Only that question's own answer, the message right after it: the chat adds the question at once and its answer\n // only once the server takes it (and none when the send fails), so an earlier answer is never shown under it.\n const after = questionAt === -1 ? undefined : messages[questionAt + 1];\n const lastAnswer = after?.role === \"ASSISTANT\" ? after : undefined;\n const chatPhase = conversation?.phase;\n /** The question has no answer yet: on its way, failed (the chat's error is the send's), or neither. */\n const unanswered =\n lastQuestion === undefined || lastAnswer !== undefined\n ? null\n : chatPhase === \"sending\" || chatPhase === \"streaming\"\n ? \"waiting\"\n : chatPhase === \"error\" || chatPhase === \"limited\"\n ? \"failed\"\n : null;\n if (phase.name === \"refused\") {\n status = S[REFUSAL_TEXT[phase.reason]];\n outcome = true;\n } else if (phase.name === \"ended\") {\n // After the day's session: how it ended stays said, over the last question and its answer.\n status = S[phase.how];\n outcome = true;\n }\n body = (\n <>\n {lastQuestion === undefined ? null : (\n <p\n data-boff-explore=\"avatar-live-question\"\n dir=\"auto\"\n className=\"line-clamp-2 w-full max-w-sm break-words text-sm font-medium\"\n >\n {lastQuestion.content}\n </p>\n )}\n {lastAnswer === undefined ? (\n unanswered === \"waiting\" ? (\n <p className=\"text-xs text-muted-foreground\">\n {activity ?? S.gettingAnswer}\n </p>\n ) : unanswered === \"failed\" ? (\n <p className=\"text-sm text-muted-foreground\">{S.answerFailed}</p>\n ) : null\n ) : lastAnswer.status === \"PENDING\" ||\n lastAnswer.status === \"RUNNING\" ? (\n <p className=\"text-xs text-muted-foreground\">\n {activity ?? S.gettingAnswer}\n </p>\n ) : lastAnswer.status === \"FAILED\" ? (\n <p className=\"text-sm text-muted-foreground\">{S.answerFailed}</p>\n ) : (\n <p\n data-boff-explore=\"avatar-live-text-answer\"\n dir=\"auto\"\n className=\"line-clamp-6 w-full max-w-sm whitespace-pre-wrap break-words text-start text-sm\"\n >\n {lastAnswer.content}\n </p>\n )}\n </>\n );\n // After a session, \"Read the answer and sources in Chat\" stays the step's own control, as it was before the box\n // asked anything (focus moves there from Stop).\n const ended = phase.name === \"ended\";\n // A send that failed before any answer came is retried in Chat, so the way there is offered for it too.\n actions =\n lastAnswer === undefined && unanswered !== \"failed\" && !ended\n ? null\n : readInChatButton(ended);\n box = \"text\";\n } else {\n switch (phase.name) {\n case \"checking\":\n status = S.checking;\n break;\n case \"needs-answer\":\n switch (shown.kind) {\n case \"empty\":\n status = note === \"new-chat\" ? S.newChatStarted : \"\";\n lead = <p className=\"text-base font-semibold\">{S.askHeadline}</p>;\n box = \"spoken\";\n break;\n case \"asking\":\n case \"answer\": {\n // The card shows while the answer is written, for a question asked here as the first of a new chat, once\n // the server has taken it.\n const card = shown.askedHere && shown.pendingAnswerId !== null;\n status =\n note === \"cancelled\" ? S.armedCancelled : S.gettingAnswer;\n if (card) media = stillPicture(true);\n body = (\n <>\n {questionLine}\n {activityLine}\n {card ? consentCard(phase.offer.copy) : null}\n </>\n );\n actions = card ? consentActions(true) : null;\n break;\n }\n case \"text-only\":\n status = S.notSpoken;\n outcome = true;\n body = questionLine;\n actions = readInChatButton(false);\n newChatOffer = true;\n break;\n case \"failed\":\n status = S.answerFailed;\n outcome = true;\n body = questionLine;\n newChatOffer = true;\n break;\n case \"ask-here\":\n status = S.askHere;\n outcome = true;\n actions = readInChatButton(false);\n newChatOffer = true;\n break;\n default:\n status = S.startNewChat;\n outcome = true;\n body = (\n <p className=\"text-sm text-muted-foreground\">\n {S.startNewChatDetailAny}\n </p>\n );\n actions = readInChatButton(false);\n newChatOffer = true;\n break;\n }\n break;\n case \"consent\":\n media = stillPicture(true);\n body = (\n <>\n {questionLine}\n {consentCard(phase.offer.copy)}\n </>\n );\n actions = consentActions(false);\n break;\n case \"declined\":\n status = S.declined;\n actions = readInChatButton(true);\n break;\n case \"waiting\":\n status = S.armed;\n body = questionLine;\n actions = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-cancel\"\n className={secondaryButton}\n onClick={stop}\n >\n {S.cancel}\n </button>\n );\n break;\n case \"refused\":\n outcome = true;\n if (\n phase.reason === \"not_eligible\" ||\n phase.reason === \"answer_claimed\"\n ) {\n // This chat's answer will not be read: a new chat for the avatar can be.\n status =\n phase.reason === \"not_eligible\"\n ? S.notEligibleAny\n : S.answerClaimed;\n actions = readInChatButton(false);\n newChatOffer = true;\n } else {\n status = S[REFUSAL_TEXT[phase.reason]];\n actions = continueButton;\n }\n break;\n case \"bot-check\":\n status = S.botCheck;\n actions = stopButton;\n break;\n case \"creating\":\n status = S.connecting;\n actions = stopButton;\n break;\n case \"pending\":\n case \"live\":\n status =\n phase.name === \"live\" ? speakingLine(phase.session) : S.connecting;\n top = badge;\n media = liveMedia(phase.name === \"live\");\n body = liveBody(phase.session);\n actions = liveActions(readInChatButton(false));\n break;\n case \"ended\":\n status = S[phase.how];\n outcome = true;\n actions = readInChatButton(true);\n // A session that never played leaves no note of the day's: a new chat for the avatar can still be. (One that\n // played is in text mode, above.)\n newChatOffer = true;\n break;\n default:\n break;\n }\n }\n\n const reason = inFlight(conversation)\n ? S.askBusy\n : conversation?.canSend\n ? null\n : S.askUnavailable;\n const chips =\n box !== null && shown.kind === \"empty\" && prompts.length > 0 ? (\n <div className=\"flex flex-col gap-1\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n {tryAsking}\n </p>\n <div className=\"flex max-h-28 flex-wrap gap-2 overflow-y-auto\">\n {prompts.map((prompt) => (\n <button\n key={prompt}\n type=\"button\"\n data-boff-explore=\"avatar-live-chip\"\n aria-disabled={reason !== null ? \"true\" : undefined}\n className=\"min-h-11 rounded-full border border-border bg-background px-3 py-2 text-start text-sm text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:transition-none\"\n onClick={() => {\n if (reason === null) ask(prompt);\n }}\n >\n {prompt}\n </button>\n ))}\n </div>\n </div>\n ) : null;\n const foot =\n box === null && !newChatOffer ? null : (\n <div\n data-boff-explore=\"avatar-live-foot\"\n className=\"flex shrink-0 flex-col gap-2 border-t border-border bg-background p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]\"\n >\n {newChatOffer ? (\n <div className=\"flex flex-col items-center gap-1 text-center\">\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-new-chat-avatar\"\n className={cn(primaryButton, \"min-h-11\")}\n onClick={newChatForAvatar}\n >\n {S.newChatForAvatar}\n </button>\n <p className=\"text-xs text-muted-foreground\">{S.newChatNote}</p>\n </div>\n ) : null}\n {chips}\n {box !== null && usedToday ? (\n <p\n data-boff-explore=\"avatar-live-used-today\"\n className=\"text-xs text-muted-foreground\"\n >\n {S.usedToday}\n </p>\n ) : null}\n {box === null ? null : (\n <AskBox\n value={draft}\n maxLength={askMaxLength}\n onChange={setDraft}\n onAsk={ask}\n reason={reason}\n label={S.askLabel}\n placeholder={S.askPlaceholder}\n send={send}\n footer={S.askFooter}\n noFiles={S.askNoFiles}\n hint={box === \"spoken\" ? S.needsAnswerAny : null}\n touchFirst={touchFirst}\n />\n )}\n </div>\n );\n\n return (\n <div\n ref={rootRef}\n data-boff-explore=\"avatar-live\"\n data-phase={phase.name}\n data-ask={askState}\n className=\"absolute inset-0 flex flex-col bg-background\"\n >\n <div className=\"flex min-h-0 flex-1 flex-col items-center gap-4 overflow-y-auto p-6 text-center\">\n {top}\n {media}\n {lead}\n <p\n role=\"status\"\n data-boff-explore=\"avatar-live-status\"\n className={\n outcome\n ? \"text-base font-semibold\"\n : \"text-sm text-muted-foreground\"\n }\n >\n {status}\n </p>\n {body}\n <div ref={botBoxRef} data-boff-explore=\"avatar-live-bot-check\" />\n {actions}\n </div>\n {foot}\n <audio ref={audioRef} data-boff-explore=\"avatar-live-audio\" />\n </div>\n );\n }\n\n // The headline of each step, in the one polite status region: announced as it changes, the countdown never.\n const headline: Record<Phase[\"name\"], string> = {\n idle: \"\",\n checking: S.checking,\n inert: \"\",\n // A question asked and its answer on its way: the answer is coming (the avatar is offered once it completes).\n \"needs-answer\": startOver\n ? S.startNewChat\n : shown.kind === \"asking\"\n ? S.gettingAnswer\n : S.needsAnswer,\n consent: \"\",\n declined: S.declined,\n waiting: S.armed,\n refused: phase.name === \"refused\" ? S[REFUSAL_TEXT[phase.reason]] : \"\",\n \"bot-check\": S.botCheck,\n creating: S.connecting,\n pending: S.connecting,\n live: phase.name === \"live\" ? speakingLine(phase.session) : \"\",\n ended: phase.name === \"ended\" ? S[phase.how] : \"\",\n };\n const outcome =\n phase.name === \"needs-answer\" ||\n phase.name === \"refused\" ||\n phase.name === \"ended\";\n\n let top: ReactNode = null;\n let media: ReactNode = stillPicture(false);\n let body: ReactNode = null;\n let actions: ReactNode = null;\n\n switch (phase.name) {\n case \"needs-answer\":\n // Nothing to read yet (choose a suggested question), or never in this conversation (start a new chat).\n body = (\n <p className=\"text-sm text-muted-foreground\">\n {startOver ? S.startNewChatDetail : S.needsAnswerDetail}\n </p>\n );\n actions = startOver ? startOverActions : continueButton;\n break;\n case \"consent\":\n media = stillPicture(true);\n body = consentCard(phase.offer.copy);\n actions = consentActions(false);\n break;\n case \"refused\":\n // An answer the service will not read (not one of the suggested questions, or too old by its clock): only a new\n // chat can be.\n actions =\n phase.reason === \"not_eligible\" ? startOverActions : continueButton;\n break;\n case \"bot-check\":\n case \"creating\":\n actions = stopButton;\n break;\n case \"pending\":\n case \"live\":\n top = badge;\n media = liveMedia(phase.name === \"live\");\n body = liveBody(phase.session);\n actions = liveActions(\n <button\n type=\"button\"\n data-boff-explore=\"avatar-live-continue\"\n className={secondaryButton}\n onClick={onContinueInChat}\n >\n {continueInChat}\n </button>,\n );\n break;\n case \"ended\":\n body = <p className=\"text-sm text-muted-foreground\">{S.answerInChat}</p>;\n actions = (\n <button\n type=\"button\"\n data-avatar-primary=\"\"\n data-boff-explore=\"avatar-live-back\"\n className={primaryButton}\n onClick={onContinueInChat}\n >\n {S.backToChat}\n </button>\n );\n break;\n default:\n break;\n }\n\n // The same slots in every step, so the status region and the bot check's box stay the same elements throughout.\n return (\n <div\n ref={rootRef}\n data-boff-explore=\"avatar-live\"\n data-phase={phase.name}\n className=\"flex max-h-full w-full flex-col items-center gap-4 overflow-y-auto\"\n >\n {top}\n {media}\n <p\n role=\"status\"\n data-boff-explore=\"avatar-live-status\"\n className={\n outcome ? \"text-base font-semibold\" : \"text-sm text-muted-foreground\"\n }\n >\n {headline[phase.name]}\n </p>\n {body}\n <div ref={botBoxRef} data-boff-explore=\"avatar-live-bot-check\" />\n {actions}\n </div>\n );\n}\n\ninterface AskBoxProps {\n value: string;\n /** The longest question the box takes: {@link ASK_MAX_LENGTH}, or the chat's own limit where that is shorter. */\n maxLength: number;\n onChange: (value: string) => void;\n /** Ask `question`. Called only with text, and only while {@link AskBoxProps.reason} is null. */\n onAsk: (question: string) => void;\n /** Why Send cannot be pressed now (an answer on its way, a chat that cannot ask), or null when it can. */\n reason: string | null;\n label: string;\n placeholder: string;\n send: string;\n /** The line under the box, always shown with it. */\n footer: string;\n /** Said when a file is pasted or dropped on the box. */\n noFiles: string;\n /** What the box is for, read with it by a screen reader; null for nothing more than its name. */\n hint: string | null;\n touchFirst: boolean;\n}\n\n/**\n * The Avatar tab's own question box. Its text is the view's (never the chat's draft); it takes text only, up to\n * {@link AskBoxProps.maxLength} characters. Send is never `disabled` (a disabled control cannot be focused or explained): it is\n * `aria-disabled`, described by why. Enter asks and Shift+Enter breaks the line; while an input method is composing,\n * Enter is the input method's, and so is Escape, which then does not reach the panel. 44 px controls.\n */\nfunction AskBox({\n value,\n maxLength,\n onChange,\n onAsk,\n reason,\n label,\n placeholder,\n send,\n footer,\n noFiles,\n hint,\n touchFirst,\n}: AskBoxProps) {\n const uid = useId();\n const reasonId = `${uid}-reason`;\n const hintId = `${uid}-hint`;\n const footerId = `${uid}-footer`;\n const [refusedFiles, setRefusedFiles] = useState(false);\n const empty = value.trim() === \"\";\n\n const submit = () => {\n if (reason !== null || empty) return;\n onAsk(value);\n };\n const onKeyDown = (event: ReactKeyboardEvent<HTMLTextAreaElement>) => {\n if (event.nativeEvent.isComposing || event.keyCode === 229) {\n if (event.key === \"Escape\") event.stopPropagation();\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n }\n };\n // Files are the chat's: one pasted or dropped here is refused, with a word on where to attach it.\n const onPaste = (event: ReactClipboardEvent<HTMLTextAreaElement>) => {\n if (event.clipboardData.files.length === 0) return;\n event.preventDefault();\n setRefusedFiles(true);\n };\n const onDrop = (event: ReactDragEvent<HTMLTextAreaElement>) => {\n if (!Array.from(event.dataTransfer.types).includes(\"Files\")) return;\n event.preventDefault();\n setRefusedFiles(true);\n };\n\n return (\n <form\n data-boff-explore=\"avatar-live-ask\"\n className=\"flex w-full flex-col gap-1\"\n onSubmit={(event) => {\n event.preventDefault();\n submit();\n }}\n >\n <div className=\"flex items-end gap-2\">\n <textarea\n value={value}\n rows={1}\n maxLength={maxLength}\n aria-label={label}\n aria-describedby={hint === null ? footerId : `${hintId} ${footerId}`}\n placeholder={placeholder}\n dir=\"auto\"\n data-avatar-primary={touchFirst ? undefined : \"\"}\n data-boff-explore=\"avatar-live-ask-input\"\n className=\"max-h-32 min-h-11 flex-1 resize-none rounded-md border border-border bg-background px-3 py-2.5 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring sm:text-sm\"\n onChange={(event) => {\n setRefusedFiles(false);\n onChange(event.target.value);\n }}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n onDrop={onDrop}\n />\n <button\n type=\"submit\"\n aria-disabled={reason !== null || empty ? \"true\" : undefined}\n aria-describedby={reason !== null ? reasonId : undefined}\n data-avatar-primary={touchFirst ? \"\" : undefined}\n data-boff-explore=\"avatar-live-ask-send\"\n className=\"inline-flex h-11 min-w-11 shrink-0 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background aria-disabled:cursor-not-allowed aria-disabled:opacity-50 motion-reduce:transition-none\"\n >\n {send}\n </button>\n </div>\n {reason === null ? null : (\n <p\n id={reasonId}\n data-boff-explore=\"avatar-live-ask-reason\"\n className=\"text-xs text-muted-foreground\"\n >\n {reason}\n </p>\n )}\n {refusedFiles ? (\n <p\n data-boff-explore=\"avatar-live-ask-files\"\n className=\"text-xs text-muted-foreground\"\n >\n {noFiles}\n </p>\n ) : null}\n {hint === null ? null : (\n <p id={hintId} className=\"sr-only\">\n {hint}\n </p>\n )}\n <p id={footerId} className=\"text-xs text-muted-foreground\">\n {footer}\n </p>\n </form>\n );\n}\n"]}