@sapia-ai/chatbot-v3 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EmbeddedVideoPlayer-SaMMfDIW.js → EmbeddedVideoPlayer-CNcds-dW.js} +283 -282
- package/dist/Preview-Dmns6UWL.js +84 -0
- package/dist/api.js +1 -1
- package/dist/{dist-DGBYKC8c.js → dist-B9SbMqZU.js} +2693 -2693
- package/dist/embed/createChatbot.d.ts +2 -0
- package/dist/{fix-webm-duration-BW9Fbdzt.js → fix-webm-duration-BWL-ZRDX.js} +2 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +15479 -2067
- package/dist/jsx-runtime-8QqjHL5t.js +24 -0
- package/dist/messages-Czlp86gl.js +1963 -0
- package/dist/react-B0K-sClg.js +295 -0
- package/dist/{react-Bujo1aK5.js → react-ChCcxVnw.js} +90 -89
- package/dist/{react-GXf8sbzf.js → react-DJysvNxz.js} +72 -71
- package/dist/{react-BVzcquey.js → react-Dbs-sPBo.js} +93 -92
- package/dist/{react-lp7yfM94.js → react-NauLB_WU.js} +91 -90
- package/dist/{react-BGJ7Szvq.js → react-QrtEtv1G.js} +76 -74
- package/dist/{react-BrCGR7Ca.js → react-be7q6yw_.js} +312 -310
- package/dist/{react-CRTg4gz8.js → react-czRIxT0g.js} +85 -84
- package/dist/{react-BMxM8TWJ.js → react-dE7BdGuR.js} +49 -48
- package/dist-umd/sapia-chatbot.umd.js +1 -1
- package/package.json +14 -25
- package/dist/EmbeddedVideoPlayer-SaMMfDIW.js.map +0 -1
- package/dist/Preview-Db-hgkTh.js +0 -83
- package/dist/Preview-Db-hgkTh.js.map +0 -1
- package/dist/dash.all.min-DZ1yEcJk.js.map +0 -1
- package/dist/dist-BSi28_cP.js.map +0 -1
- package/dist/dist-DGBYKC8c.js.map +0 -1
- package/dist/dist-FvHBWiRa.js.map +0 -1
- package/dist/fix-webm-duration-BW9Fbdzt.js.map +0 -1
- package/dist/hls-mBncGwsE.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/max-Btet1snX.js.map +0 -1
- package/dist/messages-C4jqrtSG.js +0 -187
- package/dist/messages-C4jqrtSG.js.map +0 -1
- package/dist/react-BGJ7Szvq.js.map +0 -1
- package/dist/react-BMxM8TWJ.js.map +0 -1
- package/dist/react-BVzcquey.js.map +0 -1
- package/dist/react-BrCGR7Ca.js.map +0 -1
- package/dist/react-Bujo1aK5.js.map +0 -1
- package/dist/react-CRTg4gz8.js.map +0 -1
- package/dist/react-GXf8sbzf.js.map +0 -1
- package/dist/react-lp7yfM94.js.map +0 -1
- package/dist/sapia-chatbot.css +0 -3
- package/dist-umd/sapia-chatbot.umd.js.map +0 -1
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["setRef","React","React","React","React","count","useId","React","useLayoutEffect","React","getElementRef","React","useCallbackRef","React","useCallbackRef","React","useCallbackRef","React","useCallbackRef","PORTAL_NAME","Portal","React","React","React2","React","React","React","React","React","React","SideCar","Dialog","React","useId","PortalPrimitive","RemoveScroll","createContext"],"sources":["../src/core/events.ts","../src/core/validation/pii.ts","../src/core/constants.ts","../src/core/bubbles/types.ts","../src/core/bubbles/convert.ts","../src/core/i18n/languages.ts","../src/core/persistence.ts","../src/core/interview.ts","../src/core/store.ts","../src/core/i18n/fallback.ts","../src/core/i18n/translator.ts","../src/core/theme/branding.ts","../src/core/theme/cssVariables.ts","../src/ui/richText.ts","../src/ui/inputs/OptionList/OptionList.tsx","../src/ui/inputs/DropdownInput/DropdownInput.tsx","../src/ui/primitives/Button/Button.tsx","../src/ui/inputs/SliderInput/SliderInput.tsx","../src/ui/media/EmbeddedVideo/EmbeddedVideo.tsx","../src/ui/media/UploadProgress/UploadProgress.tsx","../src/ui/media/VideoPlayer/VideoPlayer.tsx","../src/ui/chat/ChatBubble/ChatBubble.tsx","../src/ui/chat/TypingIndicator/TypingIndicator.tsx","../src/ui/chat/ChatLog/ChatLog.tsx","../../../node_modules/.pnpm/@radix-ui+primitive@1.1.4/node_modules/@radix-ui/primitive/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.3_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-context@1.1.4_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-context/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-use-layout-effect@1.1.2_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-id@1.1.2_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-id/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-use-controllable-state@1.2.3_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-slot@1.2.5_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-slot/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-primitive@2.1.5_@types+react-dom@19.2.3_@types+react@19.2.17__@types+re_5ec1197f1b7e91be68436f374cb27c36/node_modules/@radix-ui/react-primitive/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-use-callback-ref@1.1.2_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-use-callback-ref/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-use-escape-keydown@1.1.2_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-use-escape-keydown/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-dismissable-layer@1.1.12_@types+react-dom@19.2.3_@types+react@19.2.17___73c7bc8f5cad65bae593ba1fe3bba9e4/node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-focus-scope@1.1.9_@types+react-dom@19.2.3_@types+react@19.2.17__@types+_1208a7d081be7db086412200d014e5ff/node_modules/@radix-ui/react-focus-scope/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-portal@1.1.11_@types+react-dom@19.2.3_@types+react@19.2.17__@types+reac_a201d07b874b71bd93a8c3bc6f0982e5/node_modules/@radix-ui/react-portal/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-presence@1.1.6_@types+react-dom@19.2.3_@types+react@19.2.17__@types+rea_dcd2172d161be68b0f7e3bfe31aff518/node_modules/@radix-ui/react-presence/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-focus-guards@1.1.4_@types+react@19.2.17_react@19.2.7/node_modules/@radix-ui/react-focus-guards/dist/index.mjs","../../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.es6.mjs","../../../node_modules/.pnpm/react-remove-scroll-bar@2.3.8_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll-bar/dist/es2015/constants.js","../../../node_modules/.pnpm/use-callback-ref@1.3.3_@types+react@19.2.17_react@19.2.7/node_modules/use-callback-ref/dist/es2015/assignRef.js","../../../node_modules/.pnpm/use-callback-ref@1.3.3_@types+react@19.2.17_react@19.2.7/node_modules/use-callback-ref/dist/es2015/useRef.js","../../../node_modules/.pnpm/use-callback-ref@1.3.3_@types+react@19.2.17_react@19.2.7/node_modules/use-callback-ref/dist/es2015/useMergeRef.js","../../../node_modules/.pnpm/use-sidecar@1.1.3_@types+react@19.2.17_react@19.2.7/node_modules/use-sidecar/dist/es2015/medium.js","../../../node_modules/.pnpm/use-sidecar@1.1.3_@types+react@19.2.17_react@19.2.7/node_modules/use-sidecar/dist/es2015/exports.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/medium.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/UI.js","../../../node_modules/.pnpm/get-nonce@1.0.1/node_modules/get-nonce/dist/es2015/index.js","../../../node_modules/.pnpm/react-style-singleton@2.2.3_@types+react@19.2.17_react@19.2.7/node_modules/react-style-singleton/dist/es2015/singleton.js","../../../node_modules/.pnpm/react-style-singleton@2.2.3_@types+react@19.2.17_react@19.2.7/node_modules/react-style-singleton/dist/es2015/hook.js","../../../node_modules/.pnpm/react-style-singleton@2.2.3_@types+react@19.2.17_react@19.2.7/node_modules/react-style-singleton/dist/es2015/component.js","../../../node_modules/.pnpm/react-remove-scroll-bar@2.3.8_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll-bar/dist/es2015/utils.js","../../../node_modules/.pnpm/react-remove-scroll-bar@2.3.8_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll-bar/dist/es2015/component.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/aggresiveCapture.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/handleScroll.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/SideEffect.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/sidecar.js","../../../node_modules/.pnpm/react-remove-scroll@2.7.2_@types+react@19.2.17_react@19.2.7/node_modules/react-remove-scroll/dist/es2015/Combination.js","../../../node_modules/.pnpm/aria-hidden@1.2.6/node_modules/aria-hidden/dist/es2015/index.js","../../../node_modules/.pnpm/@radix-ui+react-dialog@1.1.16_@types+react-dom@19.2.3_@types+react@19.2.17__@types+reac_1fa14c606ddb9f3fb8787d3248e07810/node_modules/@radix-ui/react-dialog/dist/index.mjs","../src/ui/primitives/Dialog/Dialog.tsx","../src/ui/shell/AccessVerificationForm/AccessVerificationForm.tsx","../src/ui/shell/DoneScreen/DoneScreen.tsx","../src/ui/shell/Header/Header.tsx","../src/ui/shell/PreparingScreen/PreparingScreen.tsx","../src/ui/shell/ProgressBar/ProgressBar.tsx","../src/ui/shell/CopyLinkButton/CopyLinkButton.tsx","../src/ui/shell/WelcomeScreen/WelcomeScreen.tsx","../src/ui/constants.ts","../src/ui/shell/WidgetRoot/WidgetRoot.tsx","../src/core/validation/phoneCountries.ts","../src/ui/inputs/PhoneAnswerInput/PhoneAnswerInput.tsx","../src/ui/inputs/TextAnswerInput/TextAnswerInput.tsx","../src/ui/inputs/VideoRecorder/VideoRecorder.tsx","../src/core/media/mimeTypes.ts","../src/core/media/recorder.ts","../src/react/useVideoRecorder.ts","../src/react/AnswerInput.tsx","../src/react/bubbleViewModel.ts","../src/react/strings.ts","../src/react/useBeforeUnload.ts","../src/react/SapiaChatbot.tsx","../src/embed/constants.ts","../src/embed/createChatbot.tsx","../src/embed/compat.ts"],"sourcesContent":["// Layer B — typed event emitter wiring widget lifecycle to host callbacks.\n// Replaces the legacy PHChatBotCallback plumbing.\n\nexport const CHATBOT_EVENTS = {\n ASSESSMENT_STARTED: 'assessment:started',\n ASSESSMENT_ENDED: 'assessment:ended',\n ASSESSMENT_DUPLICATED: 'assessment:duplicated',\n ANSWER_SAVED: 'answer:saved',\n ANSWER_EDITED: 'answer:edited',\n ERROR: 'error',\n LOG: 'log',\n} as const\n\nexport type ChatbotEventName = (typeof CHATBOT_EVENTS)[keyof typeof CHATBOT_EVENTS]\n\nexport type ChatbotEventMap = {\n [CHATBOT_EVENTS.ASSESSMENT_STARTED]: { assessmentId: string }\n [CHATBOT_EVENTS.ASSESSMENT_ENDED]: { assessmentId: string }\n [CHATBOT_EVENTS.ASSESSMENT_DUPLICATED]: { assessmentId: string; duplicatedWithAssessmentLink?: string }\n [CHATBOT_EVENTS.ANSWER_SAVED]: { questionId: string }\n [CHATBOT_EVENTS.ANSWER_EDITED]: { questionId: string }\n [CHATBOT_EVENTS.ERROR]: { type: string; message: string }\n [CHATBOT_EVENTS.LOG]: { type: string; message: string }\n}\n\ntype Handler<E extends ChatbotEventName> = (payload: ChatbotEventMap[E]) => void\n\nexport class ChatbotEventEmitter {\n private handlers = new Map<ChatbotEventName, Set<Handler<ChatbotEventName>>>()\n\n on<E extends ChatbotEventName>(event: E, handler: Handler<E>): () => void {\n const set = this.handlers.get(event) ?? new Set()\n set.add(handler as Handler<ChatbotEventName>)\n this.handlers.set(event, set)\n return () => this.off(event, handler)\n }\n\n off<E extends ChatbotEventName>(event: E, handler: Handler<E>): void {\n this.handlers.get(event)?.delete(handler as Handler<ChatbotEventName>)\n }\n\n emit<E extends ChatbotEventName>(event: E, payload: ChatbotEventMap[E]): void {\n this.handlers.get(event)?.forEach((handler) => handler(payload))\n }\n}\n","// Layer B — PII answer validation/normalization, ported from legacy\n// FTQResponse handleSendClick + NameEditor/useHumanNameExtraction. Pure\n// functions; the phone module loads libphonenumber-js on demand so only\n// interviews with a phone question pay its bundle cost.\n\nimport { PiiQuestionType } from '../../api/types/messages'\nimport type { ExtractHumanNameType } from '../../api/types/responses'\n\nexport const PII_ERROR_KEYS = {\n email: 'fi_error_piiEmail',\n fullName: 'fi_error_piiFullName',\n firstName: 'fi_error_piiFirstName',\n lastName: 'fi_error_piiLastName',\n phoneNumber: 'fi_error_piiPhoneNumber',\n} as const\n\nexport type PiiErrorKey = (typeof PII_ERROR_KEYS)[keyof typeof PII_ERROR_KEYS]\n\nexport type PiiValidationResult =\n | { ok: true; text: string }\n | { ok: false; errorKey: PiiErrorKey; possiblePhoneNumber?: boolean }\n\n/** Word-count bounds per name subtype (legacy FTQResponse). */\nconst NAME_WORD_LIMITS: Partial<Record<PiiQuestionType, number>> = {\n [PiiQuestionType.FULL_NAME]: 100,\n [PiiQuestionType.FIRST_NAME]: 50,\n [PiiQuestionType.LAST_NAME]: 50,\n}\n\n/** Above this word count the answer goes through extract-human-name (legacy thresholds). */\nconst NAME_EXTRACTION_THRESHOLDS: Partial<Record<PiiQuestionType, number>> = {\n [PiiQuestionType.FULL_NAME]: 3,\n [PiiQuestionType.FIRST_NAME]: 2,\n [PiiQuestionType.LAST_NAME]: 2,\n}\n\nconst NAME_ERROR_KEYS: Partial<Record<PiiQuestionType, PiiErrorKey>> = {\n [PiiQuestionType.FULL_NAME]: PII_ERROR_KEYS.fullName,\n [PiiQuestionType.FIRST_NAME]: PII_ERROR_KEYS.firstName,\n [PiiQuestionType.LAST_NAME]: PII_ERROR_KEYS.lastName,\n}\n\nexport const EXTRACT_TYPE_BY_PII: Partial<Record<PiiQuestionType, ExtractHumanNameType>> = {\n [PiiQuestionType.FULL_NAME]: 'fullName',\n [PiiQuestionType.FIRST_NAME]: 'firstName',\n [PiiQuestionType.LAST_NAME]: 'lastName',\n}\n\nconst wordCount = (text: string): number => text.trim().split(/\\s+/).filter(Boolean).length\n\n/** Same shape validator.isEmail covers for the legacy flow; BE re-validates. */\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/\n\nexport const validateEmail = (text: string): PiiValidationResult => {\n const trimmed = text.trim()\n return EMAIL_PATTERN.test(trimmed)\n ? { ok: true, text: trimmed }\n : { ok: false, errorKey: PII_ERROR_KEYS.email }\n}\n\nexport const validateName = (piiType: PiiQuestionType, text: string): PiiValidationResult => {\n const trimmed = text.trim()\n const limit = NAME_WORD_LIMITS[piiType]\n const errorKey = NAME_ERROR_KEYS[piiType]\n if (limit === undefined || errorKey === undefined) return { ok: true, text: trimmed }\n const words = wordCount(trimmed)\n return words >= 1 && words <= limit ? { ok: true, text: trimmed } : { ok: false, errorKey }\n}\n\n/** True when the answer likely contains more than the asked-for name part. */\nexport const needsNameExtraction = (piiType: PiiQuestionType, text: string): boolean => {\n const threshold = NAME_EXTRACTION_THRESHOLDS[piiType]\n return threshold !== undefined && wordCount(text) > threshold\n}\n\n/**\n * Validates a national phone number against the selected country and\n * normalizes to E.164 (legacy submits phoneNumber.number). `possiblePhoneNumber`\n * mirrors the legacy INVALID_PHONE_NUMBER log trigger (possible but invalid).\n */\nexport const validatePhone = async (\n text: string,\n countryCode: string,\n): Promise<PiiValidationResult> => {\n const { parsePhoneNumberFromString } = await import('libphonenumber-js/max')\n const phoneNumber = parsePhoneNumberFromString(\n text.trim(),\n countryCode as import('libphonenumber-js').CountryCode,\n )\n if (phoneNumber?.isValid()) {\n return { ok: true, text: phoneNumber.number }\n }\n return {\n ok: false,\n errorKey: PII_ERROR_KEYS.phoneNumber,\n possiblePhoneNumber: phoneNumber?.isPossible() ?? false,\n }\n}\n\nexport const isNamePiiType = (piiType?: PiiQuestionType): boolean =>\n piiType !== undefined && piiType in NAME_WORD_LIMITS\n","// Layer B — core constants (ported from legacy src/constants/common.ts).\n\n/** Streaming reveal cadence: ms per char-step (React passes 0 under prefers-reduced-motion). */\nexport const STREAM_REVEAL_MS = 12\n/** Chars revealed per reveal tick — bounds store writes to ~60/s at the default cadence. */\nexport const STREAM_CHARS_PER_TICK = 2\n/** Id prefix for the transient live agent bubble shown while a message streams in. */\nexport const STREAM_BUBBLE_ID_PREFIX = 'stream-live'\n\nexport const QUESTION_TAG_PII_TYPE = 'PII_TYPE'\nexport const QUESTION_TAG_VIDEO_TYPE = 'VIDEO_TYPE'\n\n/** Experience-rating slider range and starting position (legacy defaultSliderValue). */\nexport const SLIDER_MIN = 1\nexport const SLIDER_MAX = 10\nexport const SLIDER_DEFAULT_VALUE = 8\n\n/** Default video answer length when the question carries no max-seconds rule. */\nexport const MAX_VIDEO_SECONDS_DEFAULT = 60\n","// Layer B — UI-facing message bubble domain types (converted from wire chatLogs).\n// Ported from legacy src/types/Next.ts (MessageBubble family).\n\nimport type {\n AnswerContent,\n ContentType,\n MessageIdentifier,\n MessageSender,\n PHService,\n PiiQuestionType,\n QuestionRule,\n QuestionType,\n Style,\n Tag,\n Trigger,\n VideoQuestionType,\n} from '../../api/types/messages'\n\nexport enum BubbleStatus {\n ANSWERED = 'ANSWERED',\n ANSWERING = 'ANSWERING',\n EDITING = 'EDITING',\n PENDING = 'PENDING',\n FAILED = 'FAILED',\n}\n\n/** A bubble content entry; for MCQ/DROPDOWN options and BGQ buttons it carries\n * the selectable option (BGQ adds triggers/style, echoed back in the answer). */\nexport type OptionContent = {\n id: string\n text: string\n value: string\n triggers?: Trigger[]\n style?: Style\n}\n\n/** BE A2UI-style content render component (STATE_SNAPSHOT / loaded chatLogs contents[].component). */\nexport type ContentComponent = 'Text' | 'VoicePlayer' | 'VideoPlayer' | 'Slider'\n/** BE message kind (STATE_SNAPSHOT / loaded chatLogs question.kind). */\nexport type MessageKind = 'Hint' | 'Question'\n\nexport type MessageItem = {\n id: string\n types: ContentType[]\n contents: OptionContent[]\n /** BE-provided render component for this content; falls back to `types` when absent. */\n component?: ContentComponent\n}\n\nexport type MessageBubbleData = {\n messageItems: MessageItem[]\n answer?: AnswerContent | null\n rules?: QuestionRule[]\n tags?: Tag[]\n}\n\nexport type MessageBubble = {\n status: BubbleStatus\n sender: MessageSender\n messageIdentifier?: MessageIdentifier\n id: string\n types: QuestionType[]\n usageWhitelist?: PHService[]\n questionId: string\n data: MessageBubbleData\n masterId?: string\n /** BE-provided message kind; falls back to `types` when absent. */\n messageKind?: MessageKind\n piiQuestionType?: PiiQuestionType\n videoQuestionType?: VideoQuestionType\n /** Video answer in flight: upload progress 0–1 (PENDING video bubbles). */\n uploadProgress?: number\n /** Locally-recorded blob for immediate playback before/without a signed URL. */\n videoBlob?: Blob\n /** Recorded file extension (webm/mp4), needed to fetch the playback access URL. */\n videoExtension?: string\n}\n","// Layer B — pure conversion of wire chatLogs to renderable MessageBubbles.\n// Ported from legacy src/contexts/ChatbotStateContext/bubble-util.ts; the legacy\n// __tests__/bubble-util fixtures are the parity spec (see convert.test.ts).\n\nimport {\n ContentType,\n MessageSender,\n PiiQuestionType,\n QuestionType,\n VideoQuestionType,\n type AgentResponse,\n type AnswerContent,\n type CandidateResponse,\n type Tag,\n} from '../../api/types/messages'\nimport { QUESTION_TAG_PII_TYPE, QUESTION_TAG_VIDEO_TYPE } from '../constants'\nimport { BubbleStatus, type MessageBubble, type MessageItem } from './types'\n\n/** Question types whose candidate answer is rendered from {text, value} (not free text). */\nconst VALUE_ANSWER_QUESTION_TYPES = [\n QuestionType.SLIDER,\n QuestionType.MCQ,\n QuestionType.VIDEO,\n QuestionType.DROPDOWN,\n QuestionType.BGQ,\n]\n\n/** Question types whose options must be kept in the bubble so edit mode can re-show them. */\nconst OPTION_QUESTION_TYPES = [QuestionType.MCQ, QuestionType.DROPDOWN, QuestionType.BGQ]\n\n/** Question types answered inline by the candidate bubble rendered under the question. */\nconst MANUAL_CANDIDATE_BUBBLE_TYPES = [\n QuestionType.SLIDER,\n QuestionType.MCQ,\n QuestionType.DROPDOWN,\n QuestionType.BGQ,\n]\n\nexport const piiQuestionTypeFromQuestionTags = (tags?: Tag[]): PiiQuestionType | undefined => {\n if (!tags || !Array.isArray(tags) || tags.length === 0) return undefined\n let piiQuestionType: PiiQuestionType | undefined\n tags.forEach((tag) => {\n if (tag.name === QUESTION_TAG_PII_TYPE) {\n piiQuestionType = tag.value as PiiQuestionType\n }\n })\n return piiQuestionType\n}\n\nexport const videoQuestionTypeFromQuestionTags = (tags?: Tag[]): VideoQuestionType | undefined => {\n if (!tags || !Array.isArray(tags) || tags.length === 0) return undefined\n let videoQuestionType: VideoQuestionType | undefined\n tags.forEach((tag) => {\n if (tag.name === QUESTION_TAG_VIDEO_TYPE) {\n videoQuestionType = tag.value as VideoQuestionType\n }\n })\n return videoQuestionType\n}\n\nexport const convertRawCandidateResponseToMessageBubble = (\n response: CandidateResponse,\n): MessageBubble => {\n const chatLogData = response?.data\n const questionTypes = chatLogData?.question?.types ?? []\n\n let messageItems: MessageItem[]\n let answer: AnswerContent | undefined\n if (questionTypes.some((type) => VALUE_ANSWER_QUESTION_TYPES.includes(type))) {\n answer = {\n text: chatLogData?.text,\n value: chatLogData?.value,\n }\n if (questionTypes.some((type) => OPTION_QUESTION_TYPES.includes(type))) {\n messageItems = [\n {\n id: chatLogData?._id,\n types: [ContentType.TEXT],\n contents: chatLogData?.question?.options ?? [],\n },\n ]\n } else {\n messageItems = [\n {\n id: chatLogData?._id,\n types: [ContentType.TEXT],\n contents: [\n {\n id: chatLogData?._id,\n text: chatLogData?.question?.contents?.[0]?.value,\n value: chatLogData?.question?.contents?.[0]?.value,\n },\n ],\n },\n ]\n }\n } else {\n messageItems = [\n {\n id: chatLogData?._id,\n types: [ContentType.TEXT],\n contents: [\n {\n id: chatLogData?._id,\n text: chatLogData?.text,\n value: chatLogData?.value,\n },\n ],\n },\n ]\n }\n\n const messageBubble: MessageBubble = {\n id: response?.id,\n questionId: chatLogData?.question?._id,\n sender: response?.sender,\n messageIdentifier: response?.messageIdentifier,\n status: BubbleStatus.ANSWERED,\n types: questionTypes,\n usageWhitelist: chatLogData?.question?.usageWhitelist,\n masterId: chatLogData?.question?.masterId,\n data: {\n messageItems,\n tags: chatLogData?.question?.tags,\n },\n }\n if (answer) {\n messageBubble.data.answer = answer\n }\n return messageBubble\n}\n\nexport const convertRawAgentResponseToMessageBubble = (\n response: AgentResponse,\n hasNext?: boolean,\n): MessageBubble => {\n const chatLogData = response?.data\n return {\n id: response?.id,\n questionId: chatLogData?._id,\n sender: response?.sender,\n messageIdentifier: response?.messageIdentifier,\n status:\n hasNext || chatLogData?.types?.includes(QuestionType.HINT)\n ? BubbleStatus.ANSWERED\n : BubbleStatus.ANSWERING,\n types: chatLogData?.types,\n usageWhitelist: chatLogData?.usageWhitelist,\n // BE history indicators (injectRenderMetadataToChatLogs); undefined ⇒ view-model falls back to type.\n messageKind: chatLogData?.kind,\n data: {\n rules: chatLogData?.rules,\n tags: chatLogData?.tags,\n messageItems: (chatLogData?.contents ?? []).map((content) => ({\n id: content?.value,\n types: content?.types,\n component: content?.component,\n contents: [\n {\n value: content?.value,\n text: content?.value,\n id: content?.value,\n },\n ],\n })),\n },\n masterId: chatLogData?.masterId,\n piiQuestionType: piiQuestionTypeFromQuestionTags(chatLogData?.tags),\n videoQuestionType: videoQuestionTypeFromQuestionTags(chatLogData?.tags),\n }\n}\n\nexport const convertRawResponseToMessageBubble = (\n response: CandidateResponse | AgentResponse,\n hasNext?: boolean,\n): MessageBubble | undefined => {\n if (response?.sender === MessageSender.CANDIDATE) {\n return convertRawCandidateResponseToMessageBubble(response as CandidateResponse)\n }\n if (response?.sender === MessageSender.AGENT) {\n return convertRawAgentResponseToMessageBubble(response as AgentResponse, hasNext)\n }\n return undefined\n}\n\n/**\n * For option/slider questions the candidate \"answers inline\", so a synthetic\n * candidate bubble is appended right after the agent question bubble.\n */\nexport const addCandidateResponseMessageBubble = (\n response: AgentResponse,\n): MessageBubble | undefined => {\n const chatLogData = response?.data\n if (chatLogData?.types?.some((type) => OPTION_QUESTION_TYPES.includes(type))) {\n return {\n // Suffix avoids id duplication with the agent bubble built from the same response.\n id: `${response.id}-candidate`,\n questionId: chatLogData?._id,\n sender: MessageSender.CANDIDATE,\n messageIdentifier: response.messageIdentifier,\n status: BubbleStatus.ANSWERING,\n types: chatLogData?.types,\n usageWhitelist: chatLogData?.usageWhitelist,\n masterId: chatLogData?.masterId,\n data: {\n messageItems: [\n {\n id: chatLogData?.contents?.[0]?.value,\n types: [ContentType.TEXT],\n contents: chatLogData?.options ?? [],\n },\n ],\n tags: chatLogData?.tags,\n answer: null,\n },\n }\n }\n if (chatLogData?.types?.includes(QuestionType.SLIDER)) {\n return {\n id: `${response.id}-candidate`,\n questionId: chatLogData?._id,\n masterId: chatLogData?.masterId,\n sender: MessageSender.CANDIDATE,\n messageIdentifier: response.messageIdentifier,\n status: BubbleStatus.ANSWERING,\n types: chatLogData?.types,\n usageWhitelist: chatLogData?.usageWhitelist,\n data: {\n messageItems: (chatLogData?.contents ?? []).map((content) => ({\n id: content.value,\n types: content?.types,\n contents: [\n {\n value: content?.value,\n text: content?.value,\n id: content.value,\n },\n ],\n })),\n },\n }\n }\n return undefined\n}\n\nexport const convertMessageBubbles = (\n chatLogs: (CandidateResponse | AgentResponse)[],\n): MessageBubble[] => {\n const messageBubbleList: MessageBubble[] = []\n chatLogs.forEach((chatLog, index) => {\n const messageBubble = convertRawResponseToMessageBubble(chatLog, index < chatLogs.length - 1)\n if (messageBubble) {\n messageBubbleList.push(messageBubble)\n }\n if (index === chatLogs.length - 1 && chatLog?.sender === MessageSender.AGENT) {\n const chatLogData = (chatLog as AgentResponse)?.data\n if (chatLogData?.types?.some((type) => MANUAL_CANDIDATE_BUBBLE_TYPES.includes(type))) {\n const candidateBubble = addCandidateResponseMessageBubble(chatLog as AgentResponse)\n if (candidateBubble) {\n messageBubbleList.push(candidateBubble)\n }\n }\n }\n })\n return messageBubbleList\n}\n\n/** Only load the next message when the answered question is the last agent bubble. */\nexport const checkShouldLoadNext = ({\n messageBubbleList,\n questionId,\n}: {\n messageBubbleList: MessageBubble[]\n questionId: string\n}): boolean => {\n const agentBubbles = messageBubbleList.filter((bubble) => bubble.sender === MessageSender.AGENT)\n const lastAgentBubble = agentBubbles[agentBubbles.length - 1]\n return lastAgentBubble?.questionId === questionId\n}\n","// Layer B — supported languages + browser-language resolution. Ported from\n// legacy utils/translation/constants.ts + utils/defaultLanguage.ts.\n\nexport const SUPPORTED_LANGUAGES = [\n 'en-GB',\n 'en-US',\n 'fr',\n 'es',\n 'de',\n 'fi',\n 'da',\n 'nl',\n 'it',\n 'sv',\n 'nb',\n 'pl',\n 'ar',\n] as const\n\nexport type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number]\n\nexport const FALLBACK_LANGUAGE: SupportedLanguage = 'en-US'\n\n/** Right-to-left languages (base code). */\nexport const RTL_LANGUAGES = ['ar'] as const\n\nconst isSupported = (language: string): language is SupportedLanguage =>\n (SUPPORTED_LANGUAGES as readonly string[]).includes(language)\n\n/** Map a browser language tag to a supported language (any en-* → en-US). */\nexport const normalizeLanguage = (browserLanguage?: string): SupportedLanguage => {\n if (!browserLanguage) return FALLBACK_LANGUAGE\n if (browserLanguage.startsWith('en') && !isSupported(browserLanguage)) return 'en-US'\n return isSupported(browserLanguage) ? browserLanguage : FALLBACK_LANGUAGE\n}\n\n/** Resolve the interview language: explicit override, else the browser default. */\nexport const resolveLanguage = (\n override?: string,\n browserLanguage?: string,\n): SupportedLanguage => {\n if (override && isSupported(override)) return override\n return normalizeLanguage(browserLanguage)\n}\n\nexport const isRtlLanguage = (language: string): boolean =>\n (RTL_LANGUAGES as readonly string[]).includes(language.split('-')[0])\n\nexport const directionForLanguage = (language: string): 'rtl' | 'ltr' =>\n isRtlLanguage(language) ? 'rtl' : 'ltr'\n","// Layer B — versioned, minimal localStorage access (replaces legacy's scattered\n// raw localStorage usage). All widget storage lives under one namespaced,\n// versioned key so the schema can evolve without colliding with host apps.\n\nconst STORAGE_KEY = 'sapia-chatbot:v1'\nconst ACCESS_TTL_MS = 30 * 60 * 1000\n\ntype AccessVerification = { candidateEmail: string; expireAt: number }\n\ntype PersistedState = {\n /** Verified access per assessment id (legacy ACCESS_VERIFICATION_INFO). */\n access?: Record<string, AccessVerification>\n}\n\nconst safeStorage = (): Storage | undefined => {\n try {\n return typeof window !== 'undefined' ? window.localStorage : undefined\n } catch {\n // Access to localStorage can throw (privacy mode); treat as unavailable.\n return undefined\n }\n}\n\nconst read = (): PersistedState => {\n const storage = safeStorage()\n if (!storage) return {}\n try {\n const raw = storage.getItem(STORAGE_KEY)\n return raw ? (JSON.parse(raw) as PersistedState) : {}\n } catch {\n return {}\n }\n}\n\nconst write = (state: PersistedState): void => {\n const storage = safeStorage()\n if (!storage) return\n try {\n storage.setItem(STORAGE_KEY, JSON.stringify(state))\n } catch {\n // Quota / disabled storage — non-fatal.\n }\n}\n\n/** Returns a still-valid verified email for the assessment, or undefined. */\nexport const getVerifiedEmail = (assessmentId: string, now = Date.now()): string | undefined => {\n const entry = read().access?.[assessmentId]\n if (entry && entry.expireAt > now) return entry.candidateEmail\n return undefined\n}\n\n/** Persist a verified email for the assessment with the 30-minute legacy TTL. */\nexport const saveVerifiedEmail = (\n assessmentId: string,\n candidateEmail: string,\n now = Date.now(),\n): void => {\n const state = read()\n write({\n ...state,\n access: { ...state.access, [assessmentId]: { candidateEmail, expireAt: now + ACCESS_TTL_MS } },\n })\n}\n","// Layer B — InterviewEngine: orchestrates the interview flow (start → answer → next → complete).\n// Replaces the legacy ChatbotStateContext reducer action triples + useLoadNext/helper.ts logic.\n// No React imports — fully testable in Node with a mocked client.\n\nimport type { ChatbotApiClient } from '../api/client'\nimport {\n AssessmentStatus,\n ContentType,\n MessageSender,\n PiiQuestionType,\n QuestionType,\n type AgentResponse,\n type AnswerContent,\n type CandidateResponseInput,\n type Question,\n} from '../api/types/messages'\nimport {\n EXTRACT_TYPE_BY_PII,\n PII_ERROR_KEYS,\n needsNameExtraction,\n validateEmail,\n validateName,\n validatePhone,\n type PiiErrorKey,\n} from './validation/pii'\nimport type { NextResponse } from '../api/types/responses'\nimport {\n addCandidateResponseMessageBubble,\n convertMessageBubbles,\n convertRawAgentResponseToMessageBubble,\n convertRawCandidateResponseToMessageBubble,\n piiQuestionTypeFromQuestionTags,\n videoQuestionTypeFromQuestionTags,\n} from './bubbles/convert'\nimport { BubbleStatus, type MessageBubble, type OptionContent } from './bubbles/types'\nimport { STREAM_BUBBLE_ID_PREFIX, STREAM_CHARS_PER_TICK, STREAM_REVEAL_MS } from './constants'\nimport { CHATBOT_EVENTS, ChatbotEventEmitter } from './events'\nimport { FALLBACK_LANGUAGE } from './i18n/languages'\nimport { getVerifiedEmail, saveVerifiedEmail } from './persistence'\nimport type { InterviewStore } from './store'\n\nexport const ERROR_TYPE_START_FAILED = 'FI_START_ASSESSMENT_FAILED'\nexport const ERROR_TYPE_LOAD_NEXT_FAILED = 'FI_LOAD_NEXT_FAILED'\nexport const ERROR_TYPE_EXTRACT_NAME_FAILED = 'FI_EXTRACT_HUMAN_NAME_FAILED'\nexport const ERROR_TYPE_EDIT_ANSWER_FAILED = 'FI_EDIT_ANSWER_FAILED'\nexport const ERROR_TYPE_UPLOAD_VIDEO_FAILED = 'FI_SUBMIT_VIDEO_ANSWER_FAILED'\nexport const ERROR_TYPE_TRANSLATION_FAILED = 'FI_GET_TRANSLATION_FAILED'\nexport const ERROR_TYPE_VERIFY_ACCESS_FAILED = 'FI_VERIFY_ACCESS_FAILED'\nexport const ERROR_TYPE_DETECT_AGC_FAILED = 'FI_DETECT_AGC_FAILED'\nexport const LOG_TYPE_INVALID_PHONE_NUMBER = 'INVALID_PHONE_NUMBER'\nexport const LOG_TYPE_INVALID_PASTE_ANSWER_ACTION = 'INVALID_PASTE_ANSWER_ACTION'\n\n/** messageIdentifier of the final submit button (legacy MessageIdentifier). */\nconst SUBMIT_QUESTION_MESSAGE_ID = 'SUBMIT_QUESTION_MESSAGE'\n\n/** Id prefix for the video upload-status candidate bubble. */\nconst VIDEO_BUBBLE_ID_PREFIX = 'video-answer'\n\n/** Result of a validated PII submission (drives the UI error/confirm modals). */\nexport type PiiSubmitOutcome =\n | { status: 'submitted' }\n | { status: 'invalid'; errorKey: PiiErrorKey }\n | { status: 'confirm-name'; suggested: string; original: string }\n\n/** Id prefix for the optimistic candidate bubble shown while an answer is in flight. */\nconst OPTIMISTIC_BUBBLE_ID_PREFIX = 'optimistic-answer'\n\nexport type InterviewEngineDeps = {\n client: ChatbotApiClient\n store: InterviewStore\n emitter: ChatbotEventEmitter\n assessmentId: string\n /** Resolved interview language; translations are fetched for it on start. */\n language?: string\n /** Injectable for tests; defaults to the browser UA. */\n userAgent?: string\n /** Show the pre-interview welcome gate on a fresh start (off by default). */\n welcomeGate?: boolean\n /** Per-char reveal cadence (ms) while streaming; 0 reveals each chunk wholesale (reduced-motion). */\n streamRevealMs?: number\n}\n\nconst defaultUserAgent = (): string =>\n typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown'\n\nconst delay = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms))\n\nconst isEnded = (status: AssessmentStatus): boolean =>\n status === AssessmentStatus.FI_ASSESSMENT_ENDED\n\nexport class InterviewEngine {\n private readonly client: ChatbotApiClient\n private readonly store: InterviewStore\n private readonly emitter: ChatbotEventEmitter\n private readonly assessmentId: string\n private readonly userAgent: string\n private readonly language: string\n private readonly welcomeGate: boolean\n private readonly streamRevealMs: number\n /** Aborts the in-flight stream when a new load starts. */\n private streamAbort?: AbortController\n /** Monotonic counter for unique live-bubble ids (avoids Date.now in core). */\n private streamSeq = 0\n private lastFailedInput?: CandidateResponseInput\n /** Bubble whose answer submission is in flight (optimistic FTQ or inline option bubble). */\n private pendingBubbleId?: string\n /** Retained recorded video for retry after an upload failure. */\n private lastVideoAnswer?: { questionId: string; blob: Blob; extension: string }\n /** Option id held back pending the AGC warning resolution. */\n private pendingAgcOptionId?: string\n\n constructor(deps: InterviewEngineDeps) {\n this.client = deps.client\n this.store = deps.store\n this.emitter = deps.emitter\n this.assessmentId = deps.assessmentId\n this.userAgent = deps.userAgent ?? defaultUserAgent()\n this.language = deps.language ?? FALLBACK_LANGUAGE\n this.welcomeGate = deps.welcomeGate ?? false\n this.streamRevealMs = deps.streamRevealMs ?? STREAM_REVEAL_MS\n this.store.setState({ language: this.language })\n }\n\n /** Fetch the translation file; on failure the bundled fallback is used. */\n private async loadTranslations(): Promise<void> {\n try {\n const translations = await this.client.getTranslation(this.language)\n this.store.setState({ translations })\n } catch (error) {\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_TRANSLATION_FAILED,\n message: errorMessage(error),\n })\n }\n }\n\n /**\n * Entry point: gate the interview on email access verification when the\n * assessment requires it (legacy AccessVerification), else start directly.\n * A still-valid cached email is re-verified silently.\n */\n async begin(): Promise<void> {\n this.store.setState({ phase: 'verifying' })\n let access\n try {\n access = await this.client.getAccessManagement(this.assessmentId)\n } catch {\n // Access-management unavailable — don't block; proceed to start.\n await this.start()\n return\n }\n if (!access.shouldAuthenticate) {\n await this.start()\n return\n }\n const cachedEmail = getVerifiedEmail(this.assessmentId)\n if (cachedEmail) {\n try {\n const res = await this.client.verifyAccess(this.assessmentId, cachedEmail)\n if (res.allowToAccess) {\n await this.start()\n return\n }\n } catch {\n // fall through to the form\n }\n }\n this.store.setState({ phase: 'access-required', emailHint: access.emailHint })\n }\n\n /** Verify a candidate email against the gate; on success cache it and start. */\n async verifyAccessEmail(email: string): Promise<void> {\n const trimmed = email.trim()\n const valid = validateEmail(trimmed)\n if (!valid.ok) {\n this.store.setState({ accessEmailMismatch: true })\n return\n }\n this.store.setState({ verifyingAccess: true, accessEmailMismatch: false })\n try {\n const res = await this.client.verifyAccess(this.assessmentId, trimmed)\n if (res.allowToAccess) {\n saveVerifiedEmail(this.assessmentId, trimmed)\n this.store.setState({ verifyingAccess: false })\n await this.start()\n } else {\n this.store.setState({ verifyingAccess: false, accessEmailMismatch: true })\n }\n } catch (error) {\n this.store.setState({ verifyingAccess: false })\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_VERIFY_ACCESS_FAILED,\n message: errorMessage(error),\n })\n }\n }\n\n async start(): Promise<void> {\n this.store.setState({ phase: 'starting' })\n // Fetch translations in parallel with start (legacy did these serially).\n void this.loadTranslations()\n try {\n const res = await this.client.startAts(this.assessmentId)\n const chatLogs = res.chatLogs ?? []\n const bubbles = convertMessageBubbles(chatLogs)\n const ended = isEnded(res.assessmentStatus)\n // Fresh assessment (no candidate answers yet) → gate on the welcome screen;\n // resumed assessments drop straight into the chat.\n const isFresh =\n this.welcomeGate &&\n !ended &&\n !chatLogs.some((log) => log.sender === MessageSender.CANDIDATE)\n this.store.setState({\n phase: ended ? 'ended' : 'active',\n assessmentStatus: res.assessmentStatus,\n bubbles,\n branding: res.branding,\n candidateName: res.candidateName,\n roleTitle: res.roleTitle,\n numOfNormalQuestion: res.numOfNormalQuestion,\n numOfNormalAnswer: res.numOfNormalAnswer,\n candidateCountryCode: res.candidateCountryCode,\n agcAttempt: res.agcDetectionAttempt,\n allowNextAgcDetection: res.allowNextAgcDetection,\n })\n this.emitter.emit(CHATBOT_EVENTS.ASSESSMENT_STARTED, { assessmentId: this.assessmentId })\n if (ended) {\n this.emitter.emit(CHATBOT_EVENTS.ASSESSMENT_ENDED, { assessmentId: this.assessmentId })\n return\n }\n // Archived-cohort / reused-assessment terminal messages end the interview.\n if (this.handleTerminalSignals(res)) return\n if (isFresh) {\n // Hold at the welcome gate; firstLoad runs on confirmWelcome().\n this.welcomeChatLogs = chatLogs\n this.store.setState({ phase: 'welcome' })\n return\n }\n await this.firstLoad(chatLogs)\n } catch (error) {\n this.store.setState({\n phase: 'failed',\n lastError: { type: ERROR_TYPE_START_FAILED, message: errorMessage(error) },\n })\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_START_FAILED,\n message: errorMessage(error),\n })\n }\n }\n\n /** Raw chatLogs captured at start, replayed by firstLoad once the welcome gate clears. */\n private welcomeChatLogs: { sender: MessageSender; data: unknown }[] = []\n\n /**\n * Candidate clicked \"Next\" on the welcome screen — reveal the chat and play\n * the agent's opening message(s). No-op unless we're holding at the gate.\n */\n async confirmWelcome(): Promise<void> {\n if (this.store.getState().phase !== 'welcome') return\n this.store.setState({ phase: 'active' })\n await this.firstLoad(this.welcomeChatLogs)\n }\n\n /**\n * Ported from legacy firstLoadMessageBasedOnChatLogs: empty history → fetch the\n * first message; history ending in a HINT (either the agent's question or the\n * candidate's ack of it) → acknowledge it to fetch the next one. On a finished\n * assessment the re-ack returns no nextResponse, which ends the interview.\n */\n private async firstLoad(chatLogs: { sender: MessageSender; data: unknown }[]): Promise<void> {\n if (chatLogs.length === 0) {\n await this.loadNext()\n return\n }\n const bubbles = this.store.getState().bubbles\n const lastBubble = bubbles[bubbles.length - 1]\n if (lastBubble?.types?.includes(QuestionType.HINT)) {\n await this.loadNext({ userAgent: this.userAgent, questionId: lastBubble.questionId })\n }\n }\n\n /**\n * Submit a free-text answer to the current (last agent) question. `html` is\n * the optional sanitized rich-text rendering; `text` remains the plain-text\n * source the backend scores against.\n */\n async submitTextAnswer(text: string, html?: string): Promise<void> {\n await this.submitFreeText(text, html)\n }\n\n /** Validate then submit an email PII answer (legacy FTQResponse email branch). */\n async submitEmailAnswer(text: string): Promise<PiiSubmitOutcome> {\n const result = validateEmail(text)\n if (!result.ok) return { status: 'invalid', errorKey: result.errorKey }\n await this.submitFreeText(result.text)\n return { status: 'submitted' }\n }\n\n /**\n * Validate + normalize a phone PII answer to E.164 then submit. On a\n * possible-but-invalid number, emits the legacy INVALID_PHONE_NUMBER log event.\n */\n async submitPhoneAnswer(text: string, countryCode: string): Promise<PiiSubmitOutcome> {\n const result = await validatePhone(text, countryCode)\n if (!result.ok) {\n if (result.possiblePhoneNumber) {\n this.emitter.emit(CHATBOT_EVENTS.LOG, {\n type: LOG_TYPE_INVALID_PHONE_NUMBER,\n message: `Invalid phone number for ${countryCode}: ${text}`,\n })\n }\n return { status: 'invalid', errorKey: result.errorKey }\n }\n await this.submitFreeText(result.text)\n return { status: 'submitted' }\n }\n\n /**\n * Validate a name PII answer. If it likely contains more than the asked-for\n * name part, call extract-human-name; when the extracted value differs, return\n * a confirm outcome for the UI (legacy NameExtractionConfirmModal). Otherwise\n * submit directly. Confirm via submitNameConfirmed.\n */\n async submitNameAnswer(text: string): Promise<PiiSubmitOutcome> {\n const piiType = this.currentPiiType()\n if (!piiType) return { status: 'invalid', errorKey: PII_ERROR_KEYS.fullName }\n\n const result = validateName(piiType, text)\n if (!result.ok) return { status: 'invalid', errorKey: result.errorKey }\n\n if (needsNameExtraction(piiType, result.text)) {\n const extractType = EXTRACT_TYPE_BY_PII[piiType]\n if (extractType) {\n try {\n const extracted = await this.client.extractHumanName(this.assessmentId, {\n userText: result.text,\n extractType,\n })\n const suggested = extracted[extractType]\n if (suggested && suggested !== result.text) {\n return { status: 'confirm-name', suggested, original: result.text }\n }\n } catch (error) {\n // Extraction is best-effort; fall through to submit the raw input.\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_EXTRACT_NAME_FAILED,\n message: errorMessage(error),\n })\n }\n }\n }\n await this.submitFreeText(result.text)\n return { status: 'submitted' }\n }\n\n /** Submit the name value the candidate confirmed in the extraction modal. */\n async submitNameConfirmed(text: string): Promise<void> {\n await this.submitFreeText(text)\n }\n\n /** Submit a location PII answer (address text + serialized place; legacy handleSelectLocation). */\n async submitLocationAnswer(location: { address: string; [key: string]: unknown }): Promise<void> {\n const questionId = this.currentQuestionId()\n if (!questionId || this.store.getState().sendingAnswer) return\n await this.dispatchFreshOrEdit(questionId, {\n text: location.address,\n value: JSON.stringify(location),\n })\n }\n\n /**\n * Re-edit a previously answered question (legacy EDIT_MODE_ENTER): mark its\n * candidate bubble EDITING so the input/options re-appear; the next submit\n * routes to edit-answer instead of next.\n */\n enterEditMode(questionId: string): void {\n if (this.store.getState().sendingAnswer) return\n this.store.setState((state) => ({\n editingQuestionId: questionId,\n bubbles: state.bubbles.map((bubble) =>\n bubble.sender === MessageSender.CANDIDATE && bubble.questionId === questionId\n ? { ...bubble, status: BubbleStatus.EDITING }\n : bubble,\n ),\n }))\n }\n\n /** Cancel an in-progress edit, restoring the answered bubble (legacy EDIT_MODE_EXIT). */\n cancelEditMode(): void {\n this.store.setState((state) => ({\n editingQuestionId: undefined,\n bubbles: state.bubbles.map((bubble) =>\n bubble.status === BubbleStatus.EDITING\n ? { ...bubble, status: BubbleStatus.ANSWERED }\n : bubble,\n ),\n }))\n }\n\n /**\n * Upload a recorded video answer then submit its server filename (legacy\n * useUploadVideo + ChatbotStateContext video answer): append a PENDING video\n * bubble showing upload progress, get the S3 signed URL, PUT the blob, then\n * POST the returned videoFileName to /next. On failure the bubble goes FAILED\n * and the blob is retained for retry.\n */\n async submitVideoAnswer(blob: Blob, extension: string): Promise<void> {\n const questionId = this.currentEditableQuestionId()\n if (!questionId || this.store.getState().sendingAnswer) return\n\n const bubbleId = `${VIDEO_BUBBLE_ID_PREFIX}-${questionId}`\n this.lastVideoAnswer = { questionId, blob, extension }\n this.upsertVideoBubble(bubbleId, questionId, {\n status: BubbleStatus.PENDING,\n uploadProgress: 0,\n videoBlob: blob,\n videoExtension: extension,\n })\n this.store.setState({ sendingAnswer: true })\n\n try {\n const { url, videoFileName } = await this.client.getVideoUploadUrl(\n this.assessmentId,\n questionId,\n extension,\n )\n await this.client.uploadVideo(url, blob, extension, (fraction) => {\n this.upsertVideoBubble(bubbleId, questionId, {\n status: BubbleStatus.PENDING,\n uploadProgress: fraction,\n videoBlob: blob,\n videoExtension: extension,\n })\n })\n const answer: AnswerContent = { text: videoFileName, value: videoFileName }\n if (this.store.getState().editingQuestionId === questionId) {\n this.removeBubble(bubbleId)\n await this.editExistingAnswer(questionId, answer)\n } else {\n // Upload finished: clear the progress bar so the bubble shows the recorded\n // video player BEFORE the next question streams in. Otherwise the bar stays\n // visible — and when the next response bundles a trailing hint, settle takes\n // the non-replace ANSWERED path and leaves it frozen mid-upload forever.\n this.upsertVideoBubble(bubbleId, questionId, {\n status: BubbleStatus.PENDING,\n uploadProgress: undefined,\n videoBlob: blob,\n videoExtension: extension,\n })\n this.pendingBubbleId = bubbleId\n await this.loadNext({ userAgent: this.userAgent, questionId, answer })\n }\n this.lastVideoAnswer = undefined\n } catch (error) {\n this.upsertVideoBubble(bubbleId, questionId, {\n status: BubbleStatus.FAILED,\n videoBlob: blob,\n videoExtension: extension,\n })\n this.store.setState({ sendingAnswer: false })\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_UPLOAD_VIDEO_FAILED,\n message: errorMessage(error),\n })\n }\n }\n\n /** Retry a failed video upload with the retained blob. */\n async retryVideoAnswer(): Promise<void> {\n if (!this.lastVideoAnswer) return\n const { blob, extension } = this.lastVideoAnswer\n await this.submitVideoAnswer(blob, extension)\n }\n\n /** Fetch a signed playback URL for a recorded video answer (legacy getVideoAccessUrl). */\n async getVideoPlaybackUrl(questionId: string, extension: string): Promise<string> {\n const res = await this.client.getVideoAccessUrl(this.assessmentId, questionId, extension)\n return res.url\n }\n\n private upsertVideoBubble(\n bubbleId: string,\n questionId: string,\n fields: Partial<MessageBubble>,\n ): void {\n this.store.setState((state) => {\n const existing = state.bubbles.find((bubble) => bubble.id === bubbleId)\n const bubble: MessageBubble = {\n id: bubbleId,\n questionId,\n sender: MessageSender.CANDIDATE,\n status: BubbleStatus.PENDING,\n types: [QuestionType.VIDEO],\n data: { messageItems: [] },\n ...existing,\n ...fields,\n }\n return {\n bubbles: existing\n ? state.bubbles.map((b) => (b.id === bubbleId ? bubble : b))\n : [...state.bubbles, bubble],\n }\n })\n }\n\n private removeBubble(bubbleId: string): void {\n this.store.setState((state) => ({\n bubbles: state.bubbles.filter((bubble) => bubble.id !== bubbleId),\n }))\n }\n\n private async submitFreeText(text: string, html?: string): Promise<void> {\n const questionId = this.currentEditableQuestionId()\n if (!questionId || this.store.getState().sendingAnswer) return\n await this.dispatchFreshOrEdit(questionId, { text, value: text, ...(html ? { html } : {}) })\n }\n\n /** Routes an answer to edit-answer when re-editing, else to the next-question flow. */\n private async dispatchFreshOrEdit(questionId: string, answer: AnswerContent): Promise<void> {\n if (this.store.getState().editingQuestionId === questionId) {\n await this.editExistingAnswer(questionId, answer)\n return\n }\n const input: CandidateResponseInput = { userAgent: this.userAgent, questionId, answer }\n this.appendOptimisticCandidateBubble(input)\n await this.loadNext(input)\n }\n\n /** Submit an edited answer (legacy useSubmitEditedAnswer + EDIT_ANSWER_REQUEST_COMPLETED). */\n private async editExistingAnswer(questionId: string, answer: AnswerContent): Promise<void> {\n this.store.setState((state) => ({\n sendingAnswer: true,\n bubbles: state.bubbles.map((bubble) =>\n bubble.sender === MessageSender.CANDIDATE && bubble.questionId === questionId\n ? { ...bubble, status: BubbleStatus.PENDING, data: { ...bubble.data, answer } }\n : bubble,\n ),\n }))\n try {\n const res = await this.client.editAnswer(this.assessmentId, { questionId, answer })\n const updated = convertRawCandidateResponseToMessageBubble(res.updatedCandidateResponse)\n this.store.setState((state) => ({\n sendingAnswer: false,\n editingQuestionId: undefined,\n bubbles: state.bubbles.map((bubble) =>\n bubble.sender === MessageSender.CANDIDATE && bubble.questionId === questionId\n ? updated\n : bubble,\n ),\n }))\n this.emitter.emit(CHATBOT_EVENTS.ANSWER_EDITED, { questionId })\n } catch (error) {\n // Restore the answered bubble; stay in edit mode so the candidate can retry.\n this.store.setState((state) => ({\n sendingAnswer: false,\n bubbles: state.bubbles.map((bubble) =>\n bubble.sender === MessageSender.CANDIDATE && bubble.questionId === questionId\n ? { ...bubble, status: BubbleStatus.EDITING }\n : bubble,\n ),\n }))\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_EDIT_ANSWER_FAILED,\n message: errorMessage(error),\n })\n }\n }\n\n /** Question being answered: the one under edit if editing, else the last agent bubble. */\n private currentEditableQuestionId(): string | undefined {\n return this.store.getState().editingQuestionId ?? this.currentQuestionId()\n }\n\n private currentPiiType(): PiiQuestionType | undefined {\n const bubbles = this.store.getState().bubbles\n const agentBubbles = bubbles.filter((bubble) => bubble.sender === MessageSender.AGENT)\n return agentBubbles[agentBubbles.length - 1]?.piiQuestionType\n }\n\n /**\n * Submit the selected option (MCQ/DROPDOWN/BGQ, incl. the terms-accept MCQ) of the\n * current question. The option lives in the inline candidate bubble appended by\n * bubble conversion; BGQ buttons echo their triggers/style back in the answer\n * (ported from legacy handleSelectOption / handleSelectBGQButton).\n */\n async submitOptionAnswer(optionId: string, skipAgcDetection = false): Promise<void> {\n const questionId = this.currentEditableQuestionId()\n if (!questionId || this.store.getState().sendingAnswer) return\n\n const bubble = this.inlineCandidateBubble(questionId)\n const option = bubble?.data.messageItems?.[0]?.contents?.find(\n (content) => content.id === optionId,\n )\n if (!bubble || !option) return\n\n // AGC: on the final SUBMIT button, check for automated content first\n // (legacy handleSelectBGQButton). If detected, show the warning and hold.\n if (!skipAgcDetection && (await this.detectedAgc(bubble))) {\n this.pendingAgcOptionId = optionId\n return\n }\n\n await this.submitInlineAnswer(bubble, questionId, optionToAnswer(option))\n }\n\n /**\n * Calls detect-agc when submitting the SUBMIT_QUESTION_MESSAGE and a check is\n * allowed; returns true (→ show warning) when automated content is suspected.\n */\n private async detectedAgc(bubble: MessageBubble): Promise<boolean> {\n const isSubmitButton = bubble.messageIdentifier === SUBMIT_QUESTION_MESSAGE_ID\n if (!isSubmitButton || !this.store.getState().allowNextAgcDetection) return false\n try {\n const res = await this.client.detectAgc(this.assessmentId)\n this.store.setState({\n agcAttempt: res.attempt,\n allowNextAgcDetection: res.allowNextAgcDetection,\n })\n if (res.isAgc) {\n this.store.setState({ showAgcWarning: true })\n return true\n }\n } catch (error) {\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_DETECT_AGC_FAILED,\n message: errorMessage(error),\n })\n }\n return false\n }\n\n /** Continue submitting after the AGC warning (legacy \"Continue\" — skips re-detection). */\n async continueAfterAgcWarning(): Promise<void> {\n const optionId = this.pendingAgcOptionId\n this.pendingAgcOptionId = undefined\n this.store.setState({ showAgcWarning: false })\n if (optionId) await this.submitOptionAnswer(optionId, true)\n }\n\n /** Dismiss the AGC warning to edit the answer (legacy \"Edit\"). */\n dismissAgcWarning(): void {\n this.pendingAgcOptionId = undefined\n this.store.setState({ showAgcWarning: false })\n }\n\n /** Emits the legacy INVALID_PASTE_ANSWER_ACTION log when paste is disallowed. */\n reportPaste(): void {\n this.emitter.emit(CHATBOT_EVENTS.LOG, {\n type: LOG_TYPE_INVALID_PASTE_ANSWER_ACTION,\n message: 'Candidate pasted an answer',\n })\n }\n\n /** Submit the experience-rating slider score (legacy handleSubmitRating). */\n async submitSliderAnswer(score: number): Promise<void> {\n const questionId = this.currentEditableQuestionId()\n if (!questionId || this.store.getState().sendingAnswer) return\n const bubble = this.inlineCandidateBubble(questionId)\n if (!bubble) return\n await this.submitInlineAnswer(bubble, questionId, {\n text: String(score),\n value: String(score),\n })\n }\n\n /** Stamp the inline candidate bubble with the chosen answer and send it (or edit it). */\n private async submitInlineAnswer(\n bubble: MessageBubble,\n questionId: string,\n answer: AnswerContent,\n ): Promise<void> {\n if (this.store.getState().editingQuestionId === questionId) {\n await this.editExistingAnswer(questionId, answer)\n return\n }\n this.pendingBubbleId = bubble.id\n this.store.setState((state) => ({\n bubbles: state.bubbles.map((candidate) =>\n candidate.id === bubble.id\n ? { ...candidate, status: BubbleStatus.PENDING, data: { ...candidate.data, answer } }\n : candidate,\n ),\n }))\n await this.loadNext({ userAgent: this.userAgent, questionId, answer })\n }\n\n /** Re-submit the answer whose bubble is in FAILED state. */\n async retryLastAnswer(): Promise<void> {\n if (!this.lastFailedInput) return\n const input = this.lastFailedInput\n this.lastFailedInput = undefined\n this.setPendingBubbleStatus(BubbleStatus.PENDING)\n await this.loadNext(input)\n }\n\n private currentQuestionId(): string | undefined {\n const bubbles = this.store.getState().bubbles\n const agentBubbles = bubbles.filter((bubble) => bubble.sender === MessageSender.AGENT)\n return agentBubbles[agentBubbles.length - 1]?.questionId\n }\n\n /** The synthetic candidate bubble holding the question's selectable options. */\n private inlineCandidateBubble(questionId: string): MessageBubble | undefined {\n return this.store\n .getState()\n .bubbles.find(\n (bubble) =>\n bubble.sender === MessageSender.CANDIDATE &&\n bubble.questionId === questionId &&\n (bubble.status === BubbleStatus.ANSWERING ||\n bubble.status === BubbleStatus.FAILED ||\n bubble.status === BubbleStatus.EDITING),\n )\n }\n\n private appendOptimisticCandidateBubble(input: CandidateResponseInput): void {\n const bubble: MessageBubble = {\n id: `${OPTIMISTIC_BUBBLE_ID_PREFIX}-${input.questionId}`,\n questionId: input.questionId,\n sender: MessageSender.CANDIDATE,\n status: BubbleStatus.PENDING,\n types: [QuestionType.FTQ],\n data: {\n messageItems: [\n {\n id: input.questionId,\n types: [],\n contents: [\n {\n id: input.questionId,\n text: input.answer?.text ?? '',\n value: input.answer?.value ?? '',\n },\n ],\n },\n ],\n // Carry the answer so rich-text HTML renders optimistically (and matches\n // the server-confirmed bubble shape).\n ...(input.answer ? { answer: input.answer } : {}),\n },\n }\n this.pendingBubbleId = bubble.id\n this.store.setState((state) => ({ bubbles: [...state.bubbles, bubble] }))\n }\n\n private setPendingBubbleStatus(status: BubbleStatus): void {\n const pendingId = this.pendingBubbleId\n if (!pendingId) return\n this.store.setState((state) => ({\n bubbles: state.bubbles.map((bubble) =>\n bubble.id === pendingId ? { ...bubble, status } : bubble,\n ),\n }))\n }\n\n /** Swap the in-flight bubble for the server-confirmed candidate response. */\n private replacePendingBubble(confirmed: MessageBubble): void {\n const pendingId = this.pendingBubbleId\n this.store.setState((state) => ({\n bubbles: pendingId\n ? state.bubbles.map((bubble) => (bubble.id === pendingId ? confirmed : bubble))\n : [...state.bubbles, confirmed],\n }))\n }\n\n /**\n * Loads the next message via /next/stream (the sole load path): consumes the\n * AG-UI stream, revealing agent text char-by-char into a transient live bubble,\n * then swaps it for the authoritative bubble from the terminal RUN_FINISHED\n * frame. Shares the candidate-settle and agent-append tails with the answer flow.\n */\n private async loadNext(input?: CandidateResponseInput): Promise<void> {\n this.streamAbort?.abort()\n const abort = new AbortController()\n this.streamAbort = abort\n this.store.setState({ sendingAnswer: Boolean(input?.answer), typing: true })\n\n // `liveId` is reallocated per bundled message; `metaById` keeps each message's\n // STATE_SNAPSHOT so a committed hint can carry its render indicators.\n let liveId = `${STREAM_BUBBLE_ID_PREFIX}-${this.streamSeq++}`\n let received = ''\n let revealed = 0\n let meta: Question | undefined\n let currentBaseId: string | undefined\n const metaById = new Map<string, Question>()\n let networkDone = false\n let placed = false\n\n const writeLive = () => {\n const bubble = this.buildLiveBubble(liveId, received.slice(0, revealed), meta)\n this.store.setState((state) => ({\n typing: false,\n streamingBubbleId: liveId,\n bubbles: placed\n ? state.bubbles.map((b) => (b.id === liveId ? bubble : b))\n : [...state.bubbles, bubble],\n }))\n placed = true\n }\n\n /**\n * Freeze the active streamed message as a permanent hint bubble and reset the\n * reveal state for the next bundled message. Bundled non-final messages are\n * hints by construction (only the final one is echoed in RUN_FINISHED).\n */\n const commitHint = (baseId: string) => {\n revealed = received.length\n const bubble = this.buildLiveBubble(baseId, received, metaById.get(baseId), true)\n bubble.status = BubbleStatus.ANSWERED\n if (!bubble.types?.length) bubble.types = [QuestionType.HINT]\n // Replace the live bubble if the reveal loop already placed it; otherwise\n // append (deltas can outrun the reveal tick, so no live bubble exists yet).\n this.store.setState((state) => ({\n streamingBubbleId: undefined,\n bubbles: placed\n ? state.bubbles.map((b) => (b.id === liveId ? bubble : b))\n : [...state.bubbles, bubble],\n }))\n liveId = `${STREAM_BUBBLE_ID_PREFIX}-${this.streamSeq++}`\n received = ''\n revealed = 0\n placed = false\n meta = undefined\n }\n\n // Reveal loop runs concurrently with the network read; delays yield control\n // back so reader chunks keep arriving between char-steps.\n const drain = (async () => {\n while (revealed < received.length || !networkDone) {\n if (revealed >= received.length) {\n await delay(8)\n continue\n }\n revealed =\n this.streamRevealMs === 0\n ? received.length\n : Math.min(received.length, revealed + STREAM_CHARS_PER_TICK)\n writeLive()\n if (this.streamRevealMs > 0) await delay(this.streamRevealMs)\n }\n })()\n\n const dropLiveBubble = () =>\n this.store.setState((state) => ({\n streamingBubbleId: undefined,\n bubbles: state.bubbles.filter((b) => b.id !== liveId),\n }))\n\n try {\n const final = await this.client.nextStream(this.assessmentId, input, {\n signal: abort.signal,\n onMeta: (question) => {\n // STATE_SNAPSHOT.question._id is the message baseId; store for commitHint.\n metaById.set(question._id, question)\n if (currentBaseId === undefined || currentBaseId === question._id) {\n meta = question\n if (placed) writeLive()\n }\n },\n onDelta: (text, messageId) => {\n const baseId = messageId.split(':')[0]\n // A new baseId means the previous bundled message is complete: commit it.\n if (currentBaseId !== undefined && baseId !== currentBaseId) {\n commitHint(currentBaseId)\n }\n currentBaseId = baseId\n meta = metaById.get(baseId) ?? meta\n received += text\n },\n })\n networkDone = true\n await drain\n if (final.nextResponse?.data) {\n // The final streamed message is echoed authoritatively in RUN_FINISHED:\n // drop its live bubble and let the shared tail append the settled one.\n dropLiveBubble()\n } else if (currentBaseId) {\n // Run ended on a hint with no next message: keep the last streamed message.\n commitHint(currentBaseId)\n }\n if (this.settleAnswerAndStatus(final, input)) return\n await this.appendAgentAndContinue(final, meta)\n } catch (error) {\n networkDone = true\n await drain.catch(() => {})\n // A superseding load aborted this stream — leave state to the new load.\n if ((error as { name?: string }).name === 'AbortError') return\n dropLiveBubble()\n this.lastFailedInput = input\n this.setPendingBubbleStatus(BubbleStatus.FAILED)\n this.store.setState({ typing: false, sendingAnswer: false })\n this.emitter.emit(CHATBOT_EVENTS.ERROR, {\n type: ERROR_TYPE_LOAD_NEXT_FAILED,\n message: errorMessage(error),\n })\n }\n }\n\n /** Minimal agent bubble for the streaming text (mirrors convertRawAgentResponseToMessageBubble\n * for a single TEXT content); meta, when present, seeds types/rules/tags so the live bubble\n * can render as the question card from the first character. While revealing, the content is\n * typed out as plain TEXT; once `committed`, the snapshot content's BE render indicators\n * (types/component) are applied so a bundled video hint settles to the embedded player\n * instead of leaking its URL as text. */\n private buildLiveBubble(\n id: string,\n text: string,\n meta?: Question,\n committed = false,\n ): MessageBubble {\n const content = committed ? meta?.contents?.[0] : undefined\n return {\n id,\n questionId: meta?._id ?? id,\n sender: MessageSender.AGENT,\n status: BubbleStatus.ANSWERING,\n types: meta?.types ?? [],\n usageWhitelist: meta?.usageWhitelist,\n masterId: meta?.masterId,\n messageKind: meta?.kind,\n piiQuestionType: piiQuestionTypeFromQuestionTags(meta?.tags),\n videoQuestionType: videoQuestionTypeFromQuestionTags(meta?.tags),\n data: {\n rules: meta?.rules,\n tags: meta?.tags,\n messageItems: [\n {\n id,\n types: content?.types ?? [ContentType.TEXT],\n component: content?.component ?? meta?.contents?.[0]?.component,\n contents: [{ id, value: text, text }],\n },\n ],\n },\n }\n }\n\n /**\n * Handle terminal/duplicate signals on a response (legacy\n * chatbotStateReducer): emit assessment:duplicated and render a terminal\n * agent message (archived cohort / reused assessment), ending the interview.\n * Returns true when the interview has been terminated.\n */\n private handleTerminalSignals(res: {\n duplicatedWithAssessmentLink?: string\n cohortIsArchivedMessage?: AgentResponse\n assessmentIsReusedMessage?: AgentResponse\n }): boolean {\n if (res.duplicatedWithAssessmentLink) {\n this.emitter.emit(CHATBOT_EVENTS.ASSESSMENT_DUPLICATED, {\n assessmentId: this.assessmentId,\n duplicatedWithAssessmentLink: res.duplicatedWithAssessmentLink,\n })\n }\n const terminalMessage = res.cohortIsArchivedMessage ?? res.assessmentIsReusedMessage\n if (terminalMessage?.data) {\n const bubble = convertRawAgentResponseToMessageBubble(terminalMessage)\n this.store.setState((state) => ({\n phase: 'ended',\n typing: false,\n bubbles: [...state.bubbles, bubble],\n }))\n this.emitter.emit(CHATBOT_EVENTS.ASSESSMENT_ENDED, { assessmentId: this.assessmentId })\n return true\n }\n return false\n }\n\n /**\n * Settle the in-flight candidate bubble with the server-confirmed response and\n * update the meta fields, then handle terminal/duplicate signals.\n * Returns true when the interview has been terminated (caller stops).\n */\n private settleAnswerAndStatus(res: NextResponse, input?: CandidateResponseInput): boolean {\n if (input?.answer) {\n // When the response bundles a trailing hint, the backend echoes the HINT's\n // ack (empty text, the hint's questionId) as candidateResponse — NOT the\n // answered question. Only swap the optimistic bubble when the echo actually\n // matches the answered question; otherwise keep the candidate's typed answer.\n const echo = res.candidateResponse\n if (echo && echo.data?.question?._id === input.questionId) {\n this.replacePendingBubble(convertRawCandidateResponseToMessageBubble(echo))\n } else {\n this.setPendingBubbleStatus(BubbleStatus.ANSWERED)\n }\n this.pendingBubbleId = undefined\n this.emitter.emit(CHATBOT_EVENTS.ANSWER_SAVED, { questionId: input.questionId })\n }\n\n this.store.setState({\n sendingAnswer: false,\n assessmentStatus: res.assessmentStatus,\n numOfNormalAnswer: res.numOfNormalAnswer ?? this.store.getState().numOfNormalAnswer,\n })\n\n // Terminal/duplicate signals end the interview before any next question.\n return this.handleTerminalSignals(res)\n }\n\n /**\n * Append the authoritative next agent bubble (plus any inline option/slider\n * candidate bubble), recurse on HINTs, and end the interview when there is no\n * next question. Assumes the answer is already settled and the live bubble removed.\n */\n private async appendAgentAndContinue(res: NextResponse, meta?: Question): Promise<void> {\n const nextAgentResponse = res.nextResponse\n if (nextAgentResponse?.data) {\n const agentBubble = applyRenderIndicators(\n convertRawAgentResponseToMessageBubble(nextAgentResponse),\n meta,\n )\n // Option/slider questions are answered inline: append the synthetic candidate\n // bubble holding the selectable options (mirrors convertMessageBubbles on load).\n const inlineBubble = addCandidateResponseMessageBubble(nextAgentResponse)\n this.store.setState((state) => ({\n typing: false,\n bubbles: inlineBubble\n ? [...state.bubbles, agentBubble, inlineBubble]\n : [...state.bubbles, agentBubble],\n }))\n\n // HINTs need no answer: acknowledge and keep loading the next message.\n if (nextAgentResponse.data.types?.includes(QuestionType.HINT)) {\n await this.loadNext({ userAgent: this.userAgent, questionId: nextAgentResponse.data._id })\n return\n }\n } else {\n this.store.setState({ typing: false })\n }\n\n // Legacy semantics (chatbotStateReducer/action.ts): no nextResponse means the\n // assessment is over — the terminal status may be COMPLETED rather than ENDED.\n if (!nextAgentResponse?.data || isEnded(res.assessmentStatus)) {\n this.store.setState({ phase: 'ended' })\n this.emitter.emit(CHATBOT_EVENTS.ASSESSMENT_ENDED, { assessmentId: this.assessmentId })\n }\n }\n}\n\nconst errorMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n\n/**\n * Overlay the streaming snapshot's BE render indicators (kind + per-content\n * component) onto a bubble built from the raw RUN_FINISHED result, so the\n * settled streaming bubble matches the live one. No-op when meta is absent\n * (buffered/history bubbles carry their own indicators via convert.ts).\n */\nconst applyRenderIndicators = (bubble: MessageBubble, meta?: Question): MessageBubble => {\n if (!meta) return bubble\n bubble.messageKind = meta.kind\n bubble.data.messageItems.forEach((item, index) => {\n item.component = meta.contents?.[index]?.component\n })\n return bubble\n}\n\n/** MCQ answers send {text, value}; BGQ buttons additionally echo triggers/style. */\nconst optionToAnswer = (option: OptionContent): AnswerContent => ({\n text: option.text,\n value: option.value,\n ...(option.triggers ? { triggers: option.triggers } : {}),\n ...(option.style ? { style: option.style } : {}),\n})\n","// Layer B — per-widget-instance state container (zustand vanilla: no React, no global).\n\nimport { createStore, type StoreApi } from 'zustand/vanilla'\nimport type { AssessmentStatus } from '../api/types/messages'\nimport type { Branding } from '../api/types/branding'\nimport type { MessageBubble } from './bubbles/types'\n\nexport type InterviewPhase =\n | 'idle'\n | 'verifying'\n | 'access-required'\n | 'starting'\n // Data loaded for a fresh assessment; awaiting the candidate's \"Next\" on the welcome screen.\n | 'welcome'\n | 'active'\n | 'ended'\n | 'failed'\n\nexport type InterviewState = {\n phase: InterviewPhase\n assessmentStatus?: AssessmentStatus\n bubbles: MessageBubble[]\n /** Agent typing animation visible. */\n typing: boolean\n /** Id of the agent bubble currently streaming in (drives the live caret); undefined when idle. */\n streamingBubbleId?: string\n /** An answer submission is in flight. */\n sendingAnswer: boolean\n numOfNormalQuestion: number\n numOfNormalAnswer: number\n branding?: Branding\n /** Candidate display name for the welcome/done screens (optional; from /start/ats). */\n candidateName?: string\n /** Role/position title for the welcome + header (optional; falls back to branding.title). */\n roleTitle?: string\n /** Candidate's detected ISO country code; seeds the phone PII default. */\n candidateCountryCode?: string\n /** Question whose previously-submitted answer is being re-edited (null = not editing). */\n editingQuestionId?: string\n /** Masked email shown on the access-verification gate. */\n emailHint?: string\n /** Whether to show \"email does not match\" on the access gate. */\n accessEmailMismatch?: boolean\n /** Access verification request in flight. */\n verifyingAccess?: boolean\n /** AGC (automated-content) detection attempt count + whether another check is allowed. */\n agcAttempt?: number\n allowNextAgcDetection?: boolean\n /** Show the AGC warning modal (automated content suspected on submit). */\n showAgcWarning?: boolean\n /** Interview language (resolved); drives translations + text direction. */\n language?: string\n /** Fetched translation file (flat key/value); undefined → bundled fallback only. */\n translations?: Record<string, string>\n lastError?: { type: string; message: string }\n}\n\nexport type InterviewStore = StoreApi<InterviewState>\n\nexport const INITIAL_INTERVIEW_STATE: InterviewState = {\n phase: 'idle',\n bubbles: [],\n typing: false,\n sendingAnswer: false,\n numOfNormalQuestion: 0,\n numOfNormalAnswer: 0,\n}\n\nexport const createInterviewStore = (): InterviewStore =>\n createStore<InterviewState>(() => ({ ...INITIAL_INTERVIEW_STATE }))\n","// Layer B — bundled fallback translations (en-US), used when the API fetch\n// fails or a key is missing. Legacy fi_* keys are ported verbatim from\n// utils/translation/fallBackTranslation.ts; sc_* keys cover widget chrome\n// that the legacy widget rendered without a text key (icons etc.).\n\nimport type { TranslationFile } from './translator'\n\nexport const FALLBACK_TRANSLATIONS: TranslationFile = {\n // Legacy keys (match the backend translation file so other languages resolve)\n fi_label_typing: 'Typing',\n fi_button_edit: 'Edit',\n fi_button_continue: 'Continue',\n fi_button_retry: 'Retry',\n fi_button_record: 'Record',\n fi_button_stop: 'Stop',\n fi_button_tryAgain: 'Try Again',\n fi_button_submitRating: 'Submit rating',\n fi_label_editing: 'Editing',\n fi_label_ratingMessage: 'Rate your experience!',\n fi_label_enterResponse: 'Enter your response…',\n fi_label_uploading: 'Uploading your video',\n fi_label_uploadFailed: 'Your video failed to upload.',\n fi_label_cancelEditDesktop: 'Cancel edit',\n fi_placeholder_dropdown: 'Type to search…',\n fi_placeholder_demoEmailInput: 'Enter your email',\n fi_error_piiEmail: 'Please enter a valid email address.',\n fi_error_piiFullName: 'Please enter a valid full name.',\n fi_error_piiFirstName: 'Please enter a valid first name.',\n fi_error_piiLastName: 'Please enter a valid last name.',\n fi_error_piiPhoneNumber: 'Please enter a valid phone number.',\n fi_error_sendAnswerFailed: 'We could not send your answer. Please try again.',\n fi_error_submitVideo: 'We could not submit your video. Please try again.',\n\n // New widget chrome (no legacy text key)\n sc_header_title: 'Interview',\n sc_header_subtitle: 'Sapia chat interview',\n sc_speaker_interviewer: 'Interviewer',\n sc_single_choice_label: 'Single choice question',\n sc_video_badge: 'Video',\n sc_typing: 'Interviewer is typing',\n sc_typing_reading: 'Reading your response',\n sc_typing_thinking: 'Thinking about it',\n sc_progress_label: 'Interview progress',\n sc_question_counter: 'Question {{current}} of {{total}}',\n sc_getting_started: 'Getting started',\n sc_pause_hint: 'Pause anytime — come back with this link',\n sc_copy_link: 'Copy link',\n sc_copied: 'Copied ✓',\n sc_role_with_company: '{{role}} role with {{company}}',\n sc_welcome_greeting: 'Hi {{name}}.',\n sc_welcome_greeting_generic: 'Hi there.',\n sc_welcome_title: 'Welcome to your Chat Interview',\n sc_welcome_eyebrow: 'Chat interview',\n sc_welcome_copy_resume: 'Copy link · resume later',\n sc_welcome_intro:\n 'A conversation for the {{role}} role with {{company}} — answered in your own words, read blind to your name, age and background.',\n sc_welcome_intro_generic:\n 'A conversation answered in your own words, read blind to your name, age and background.',\n sc_welcome_pause: 'You can pause and come back later with this link',\n sc_welcome_next: 'Next',\n sc_welcome_reassurance: 'No right or wrong answers. Take your time.',\n sc_answer_looks_good: 'Looking good',\n sc_composer_footer: 'Your answers are confidential',\n sc_rich_toolbar: 'Text formatting',\n sc_rich_bold: 'Bold',\n sc_rich_italic: 'Italic',\n sc_rich_underline: 'Underline',\n sc_rich_bullet_list: 'Bulleted list',\n sc_rich_number_list: 'Numbered list',\n sc_button_send: 'Send',\n sc_input_label: 'Your answer',\n sc_options_group: 'Answer options',\n sc_dropdown_search_label: 'Search options',\n sc_min_length_hint: 'Please write at least {{min}} characters',\n sc_loading: 'Loading your interview…',\n sc_preparing: 'Preparing your interview…',\n sc_done_title: \"That's everything.\",\n sc_done_title_named: \"That's everything, {{name}}.\",\n sc_done_subtitle:\n 'Thanks for being generous with your answers — the {{company}} team takes it from here.',\n sc_done_subtitle_generic:\n 'Thanks for being generous with your answers — the team takes it from here.',\n sc_done_next_label: 'What happens next',\n sc_done_step1:\n 'Your answers are assessed on what you said — blind to name, age and background.',\n sc_done_step2:\n \"You'll get personalised feedback whatever the outcome — usually within a few days.\",\n sc_done_step3: \"If it's a match, the team will reach out about next steps.\",\n sc_done_rating_prompt: 'How did this interview feel?',\n sc_start_failed: 'We could not load your interview. Please refresh the page to try again.',\n sc_phone_country_label: 'Country code',\n sc_phone_input_label: 'Phone number',\n sc_phone_placeholder: 'Enter your phone number',\n sc_name_confirm_title: 'Is this correct?',\n sc_name_confirm_body: 'We read your name as \"{{suggested}}\". Use this?',\n sc_name_use_suggested: 'Use \"{{suggested}}\"',\n sc_name_use_original: 'Keep what I typed',\n sc_video_open_camera: 'Turn on camera',\n sc_video_re_record: 'Re-record',\n sc_video_submit: 'Use this answer',\n sc_video_camera: 'Camera',\n sc_video_microphone: 'Microphone',\n sc_video_on: 'On',\n sc_video_off: 'Off',\n sc_video_finish_hint: 'Tap to finish',\n sc_video_camera_off: 'Camera is off',\n sc_video_attempts: '{{current}}/{{max}} attempts',\n sc_video_camera_error:\n 'We could not access your camera. Please check permissions and try again.',\n sc_video_preview: 'Camera preview',\n sc_video_retry_upload: 'Retry upload',\n sc_video_play: 'Play video',\n sc_video_answer: 'Your video answer',\n sc_video_embed_label: 'Embedded video',\n sc_access_title: 'Verify your identity',\n sc_access_description: 'Please enter the email address you applied with to continue.',\n sc_access_input_label: 'Email address',\n sc_access_placeholder: 'you@example.com',\n sc_access_submit: 'Continue',\n fi_error_emailDoesNotMatch: 'That email does not match our records. Please try again.',\n fi_error_agcTitle: 'Please answer in your own words',\n fi_error_agcFirstMessage:\n 'Your answer looks like it may be AI-generated. Please edit it to be your own words.',\n fi_error_agcSecondMessage:\n 'This is your final reminder — please make sure your answer is your own work.',\n}\n","// Layer B — flat-key translator with {{param}} interpolation and _one/_other\n// pluralization. Replaces i18next (legacy only used flat keys + params).\n\nexport type TranslationFile = Record<string, string>\n\n/** Replaces {{name}} placeholders with params; missing params become ''. */\nexport const interpolate = (template: string, params?: Record<string, string | number>): string =>\n template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (_, key: string) =>\n params?.[key] !== undefined ? String(params[key]) : '',\n )\n\n/** Plural key suffix per i18next convention (count===1 → _one, else _other). */\nconst pluralKey = (key: string, count?: number): string => {\n if (count === undefined) return key\n return count === 1 ? `${key}_one` : `${key}_other`\n}\n\nexport type TranslateOptions = { count?: number } & Record<string, string | number>\n\nexport type Translator = (key: string, options?: TranslateOptions) => string\n\n/**\n * Builds a translator that looks up the fetched file, then the bundled\n * fallback, then returns the key itself (so missing keys are visible, never\n * throw — unlike the legacy translator which threw on missing keys).\n */\nexport const createTranslator = (\n file: TranslationFile | undefined,\n fallback: TranslationFile,\n): Translator => {\n return (key, options) => {\n const lookupKey = pluralKey(key, options?.count)\n const template =\n file?.[lookupKey] ?? fallback[lookupKey] ?? file?.[key] ?? fallback[key] ?? key\n return interpolate(template, options)\n }\n}\n","// Layer B — converts the API branding payload into a Theme and merges it with\n// a host-supplied theme (host setTheme wins). Ported from legacy\n// utils/convertTheme.ts (convertRawBrandingTheme) + theme precedence.\n\nimport type { Branding } from '../../api/types/branding'\nimport type { Theme, ThemeSection } from './types'\n\n/** Branding theme-property names this widget maps to Theme sections. */\nconst SECTION_NAMES = ['header', 'question', 'response', 'button'] as const\n\n/** Converts the branding payload (theme array + font) into a Theme object. */\nexport const brandingToTheme = (branding?: Branding): Theme => {\n if (!branding) return {}\n const theme: Theme = {}\n branding.theme?.forEach((property) => {\n if ((SECTION_NAMES as readonly string[]).includes(property.name)) {\n theme[property.name as (typeof SECTION_NAMES)[number]] = {\n backgroundColor: property.value?.backgroundColor,\n fontColor: property.value?.fontColor,\n }\n }\n })\n if (branding.font) theme.fontFamily = branding.font\n return theme\n}\n\nconst mergeSection = (base?: ThemeSection, override?: ThemeSection): ThemeSection | undefined => {\n if (!base && !override) return undefined\n return {\n backgroundColor: override?.backgroundColor ?? base?.backgroundColor,\n fontColor: override?.fontColor ?? base?.fontColor,\n }\n}\n\n/** Merge two themes; `override` (host setTheme) wins per field over `base` (branding). */\nexport const mergeThemes = (base: Theme | undefined, override: Theme | undefined): Theme => {\n const b = base ?? {}\n const o = override ?? {}\n return {\n header: mergeSection(b.header, o.header),\n question: mergeSection(b.question, o.question),\n response: mergeSection(b.response, o.response),\n button: mergeSection(b.button, o.button),\n fontFamily: o.fontFamily ?? b.fontFamily,\n }\n}\n","// Layer B — single source of truth for the widget's CSS variable names.\n// These map 1:1 to Tailwind tokens declared in src/styles/index.css.\n\nimport type { Theme } from './types'\n\nexport const CSS_VAR_HEADER_BG = '--sc-header-bg'\nexport const CSS_VAR_HEADER_FG = '--sc-header-fg'\nexport const CSS_VAR_QUESTION_BG = '--sc-question-bg'\nexport const CSS_VAR_QUESTION_FG = '--sc-question-fg'\nexport const CSS_VAR_RESPONSE_BG = '--sc-response-bg'\nexport const CSS_VAR_RESPONSE_FG = '--sc-response-fg'\nexport const CSS_VAR_BUTTON_BG = '--sc-button-bg'\nexport const CSS_VAR_BUTTON_FG = '--sc-button-fg'\nexport const CSS_VAR_FONT_FAMILY = '--sc-font-family'\n\nexport type CssVariableMap = Record<string, string>\n\n/**\n * Converts a host/branding Theme into CSS custom properties applied on the\n * widget root. Pure function — testable without DOM.\n */\nexport const themeToCssVariables = (theme: Theme | undefined): CssVariableMap => {\n if (!theme) return {}\n const vars: CssVariableMap = {}\n const assign = (name: string, value: string | undefined) => {\n if (value) vars[name] = value\n }\n assign(CSS_VAR_HEADER_BG, theme.header?.backgroundColor)\n assign(CSS_VAR_HEADER_FG, theme.header?.fontColor)\n assign(CSS_VAR_QUESTION_BG, theme.question?.backgroundColor)\n assign(CSS_VAR_QUESTION_FG, theme.question?.fontColor)\n assign(CSS_VAR_RESPONSE_BG, theme.response?.backgroundColor)\n assign(CSS_VAR_RESPONSE_FG, theme.response?.fontColor)\n assign(CSS_VAR_BUTTON_BG, theme.button?.backgroundColor)\n assign(CSS_VAR_BUTTON_FG, theme.button?.fontColor)\n assign(CSS_VAR_FONT_FAMILY, theme.fontFamily)\n return vars\n}\n","// Layer C util — allow-list sanitizer for candidate rich-text answers. Ported\n// from the Chat-3000 prototype. Used at both trust boundaries: on submit (before\n// the HTML leaves the composer) and on render (before dangerouslySetInnerHTML),\n// so server-returned HTML is re-cleaned too.\n\nconst ALLOWED_TAGS = new Set([\n 'B',\n 'I',\n 'U',\n 'STRONG',\n 'EM',\n 'UL',\n 'OL',\n 'LI',\n 'BR',\n 'DIV',\n 'P',\n 'SPAN',\n])\n\n/**\n * Strips everything except a small inline/list formatting allow-list and removes\n * all attributes (class/style/href/on*), re-adding only controlled list/block\n * spacing. Returns \"\" when no DOM is available (SSR).\n */\nexport const sanitizeRichText = (html: string): string => {\n if (typeof DOMParser === 'undefined') return ''\n const doc = new DOMParser().parseFromString(html, 'text/html')\n const clean = (node: Element) => {\n Array.from(node.children).forEach((child) => {\n clean(child)\n Array.from(child.attributes).forEach((attr) => child.removeAttribute(attr.name))\n const tag = child.tagName\n if (!ALLOWED_TAGS.has(tag)) {\n child.replaceWith(...Array.from(child.childNodes))\n } else if (tag === 'UL' || tag === 'OL') {\n const el = child as HTMLElement\n el.style.margin = '4px 0'\n el.style.paddingLeft = '22px'\n } else if (tag === 'P' || tag === 'DIV') {\n ;(child as HTMLElement).style.margin = '0'\n }\n })\n }\n clean(doc.body)\n return doc.body.innerHTML\n}\n","import type { ChatOptionItem } from '../../chat/types'\n\nexport type OptionListProps = {\n options: ChatOptionItem[]\n /** The chosen option (highlighted; stays highlighted after answering). */\n selectedOptionId?: string\n /** Options accept clicks; false once answered or while submitting. */\n enabled?: boolean\n /** Submission in flight for the selected option. */\n pending?: boolean\n groupLabel: string\n onSelect?: (optionId: string) => void\n}\n\n/**\n * Selectable answer options for MCQ/terms-accept/button-group questions.\n * Pure presentational: single select, real buttons, keyboard accessible.\n * Replaces legacy components/OptionList (AntD-free).\n */\nexport const OptionList = ({\n options,\n selectedOptionId,\n enabled = false,\n pending = false,\n groupLabel,\n onSelect,\n}: OptionListProps) => (\n <div\n role=\"group\"\n aria-label={groupLabel}\n className=\"sc:overflow-hidden sc:rounded-2xl sc:border sc:border-line sc:bg-question\"\n >\n {options.map((option, index) => {\n const isSelected = option.id === selectedOptionId\n return (\n <button\n key={option.id}\n type=\"button\"\n disabled={!enabled}\n aria-pressed={isSelected}\n aria-busy={pending && isSelected ? true : undefined}\n onClick={() => onSelect?.(option.id)}\n className={`sc:flex sc:w-full sc:items-center sc:gap-3.5 sc:px-[18px] sc:py-[15px] sc:text-start sc:text-base sc:not-last:border-b sc:border-line sc:transition-colors ${\n isSelected ? 'sc:bg-button sc:text-button-fg' : 'sc:text-question-fg'\n } ${\n enabled\n ? 'sc:cursor-pointer sc:hover:bg-pink-tint sc:focus-visible:outline-2 sc:focus-visible:-outline-offset-2'\n : 'sc:cursor-default'\n } ${pending && isSelected ? 'sc:opacity-60' : ''}`}\n >\n <span\n aria-hidden=\"true\"\n className={`sc:flex sc:size-7 sc:flex-shrink-0 sc:items-center sc:justify-center sc:rounded-lg sc:text-[13px] sc:font-bold sc:tabular-nums ${\n isSelected ? 'sc:bg-white/15 sc:text-button-fg' : 'sc:bg-[#f1f0f3] sc:text-muted'\n }`}\n >\n {index + 1}\n </span>\n <span>\n {option.text}\n {pending && isSelected ? <span aria-hidden=\"true\"> …</span> : null}\n </span>\n </button>\n )\n })}\n </div>\n)\n","import { useState } from 'react'\nimport { OptionList } from '../OptionList/OptionList'\nimport type { ChatOptionItem } from '../../chat/types'\n\nexport type DropdownInputProps = {\n options: ChatOptionItem[]\n selectedOptionId?: string\n /** Accepts input; false once answered or while submitting. */\n enabled?: boolean\n pending?: boolean\n searchPlaceholder: string\n searchLabel: string\n groupLabel: string\n onSelect?: (optionId: string) => void\n}\n\n/**\n * Searchable option picker for DROPDOWN questions (ported from legacy\n * components/Dropdown): a filter input over a visible option list — clicking\n * an option submits it. AntD/ahooks-free.\n */\nexport const DropdownInput = ({\n options,\n selectedOptionId,\n enabled = false,\n pending = false,\n searchPlaceholder,\n searchLabel,\n groupLabel,\n onSelect,\n}: DropdownInputProps) => {\n const [searchText, setSearchText] = useState('')\n\n const normalizedSearch = searchText.trim().toLowerCase()\n const visibleOptions = normalizedSearch\n ? options.filter((option) => option.text.toLowerCase().includes(normalizedSearch))\n : options\n\n return (\n <div className=\"sc:flex sc:flex-col sc:gap-2 sc:min-w-60\">\n <input\n type=\"text\"\n value={searchText}\n disabled={!enabled}\n placeholder={searchPlaceholder}\n aria-label={searchLabel}\n onChange={(event) => setSearchText(event.target.value)}\n className=\"sc:rounded-md sc:border sc:border-black/20 sc:px-3 sc:py-2 sc:text-sm sc:focus-visible:outline-2 sc:focus-visible:outline-offset-1 sc:disabled:opacity-50\"\n />\n <div className=\"sc:max-h-64 sc:overflow-y-auto\">\n <OptionList\n options={visibleOptions}\n selectedOptionId={selectedOptionId}\n enabled={enabled}\n pending={pending}\n groupLabel={groupLabel}\n onSelect={onSelect}\n />\n </div>\n </div>\n )\n}\n","import type { ButtonHTMLAttributes, ReactNode } from 'react'\n\nexport type ButtonProps = {\n children: ReactNode\n variant?: 'primary' | 'ghost'\n} & ButtonHTMLAttributes<HTMLButtonElement>\n\nconst VARIANT_CLASSES: Record<NonNullable<ButtonProps['variant']>, string> = {\n primary:\n 'sc:bg-button sc:text-button-fg sc:hover:bg-ink-strong sc:disabled:opacity-50 sc:disabled:cursor-not-allowed',\n ghost:\n 'sc:bg-transparent sc:border sc:border-button sc:text-button sc:hover:bg-pink-tint sc:disabled:opacity-50',\n}\n\nexport const Button = ({\n children,\n variant = 'primary',\n type = 'button',\n className = '',\n ...rest\n}: ButtonProps) => (\n <button\n type={type}\n className={`sc:inline-flex sc:items-center sc:justify-center sc:gap-2 sc:rounded-full sc:px-5 sc:py-2.5 sc:text-sm sc:font-semibold sc:transition-colors sc:focus-visible:outline-2 sc:focus-visible:outline-offset-2 ${VARIANT_CLASSES[variant]} ${className}`}\n {...rest}\n >\n {children}\n </button>\n)\n","import { useState } from 'react'\nimport { Button } from '../../primitives/Button/Button'\n\nexport type SliderInputProps = {\n min: number\n max: number\n defaultValue: number\n /** The submitted score once answered (renders read-only at this value). */\n submittedValue?: number\n /** Slider accepts input; false once answered or while submitting. */\n enabled?: boolean\n pending?: boolean\n label: string\n hint: string\n submitLabel: string\n onSubmit?: (score: number) => void\n}\n\n/**\n * Experience-rating slider (legacy renderSlider, AntD-free). Native range\n * input: keyboard accessible (arrow keys) out of the box.\n */\nexport const SliderInput = ({\n min,\n max,\n defaultValue,\n submittedValue,\n enabled = false,\n pending = false,\n label,\n hint,\n submitLabel,\n onSubmit,\n}: SliderInputProps) => {\n const [score, setScore] = useState(defaultValue)\n const value = submittedValue ?? score\n\n return (\n <div className=\"sc:flex sc:flex-col sc:gap-2 sc:items-stretch sc:min-w-60\">\n <div className=\"sc:flex sc:items-center sc:gap-2\">\n <span aria-hidden=\"true\" className=\"sc:text-xs sc:text-black/60\">\n {min}\n </span>\n <input\n type=\"range\"\n min={min}\n max={max}\n step={1}\n value={value}\n disabled={!enabled}\n aria-label={label}\n aria-valuetext={String(value)}\n onChange={(event) => setScore(Number(event.target.value))}\n className=\"sc:flex-1 sc:accent-button sc:disabled:opacity-50\"\n />\n <span aria-hidden=\"true\" className=\"sc:text-xs sc:text-black/60\">\n {max}\n </span>\n </div>\n <p className=\"sc:text-sm sc:font-bold sc:text-question-fg\">{hint}</p>\n {enabled ? (\n <Button onClick={() => onSubmit?.(score)} disabled={pending} aria-busy={pending || undefined}>\n {submitLabel}\n </Button>\n ) : null}\n </div>\n )\n}\n","import { lazy, Suspense } from 'react'\n\n// Lazy so react-player + @vimeo/player form a separate async chunk and stay out\n// of the dist/index.js ESM entry the size-limit gate measures (ADR-024/ADR-025).\nconst EmbeddedVideoPlayer = lazy(() =>\n import('./EmbeddedVideoPlayer').then((module) => ({ default: module.EmbeddedVideoPlayer })),\n)\n\nexport type EmbeddedVideoProps = {\n /** Raw agent-delivered video URL (YouTube/Vimeo/generic). */\n url: string\n /** Accessible title/label for the embed. */\n label: string\n}\n\n/**\n * Backend-delivered video embedded inside an agent bubble (intro/explainer).\n * Thin wrapper that lazy-loads the heavy player stack on demand.\n */\nexport const EmbeddedVideo = ({ url, label }: EmbeddedVideoProps) => (\n <Suspense\n fallback={<div aria-hidden=\"true\" className=\"sc:w-full sc:aspect-video\" />}\n >\n <EmbeddedVideoPlayer url={url} label={label} />\n </Suspense>\n)\n","export type UploadProgressProps = {\n /** 0–1. */\n value: number\n label: string\n}\n\n/** Accessible determinate progress bar for a video upload. */\nexport const UploadProgress = ({ value, label }: UploadProgressProps) => {\n const percent = Math.round(value * 100)\n return (\n <div className=\"sc:flex sc:flex-col sc:gap-1 sc:min-w-60\">\n <div\n role=\"progressbar\"\n aria-label={label}\n aria-valuenow={percent}\n aria-valuemin={0}\n aria-valuemax={100}\n className=\"sc:h-2 sc:w-full sc:overflow-hidden sc:rounded-full sc:bg-black/10\"\n >\n <div className=\"sc:h-full sc:bg-response\" style={{ width: `${percent}%` }} />\n </div>\n <span className=\"sc:text-xs sc:text-black/60\">{percent}%</span>\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\n\nexport type VideoPlayerProps = {\n /** Local recorded blob (just-submitted answer), played without a network call. */\n blob?: Blob\n /** Lazily resolves a signed playback URL (historical answers). */\n resolveUrl?: () => Promise<string>\n playLabel: string\n label: string\n}\n\n/**\n * Plays a recorded video answer. Uses the local blob when available, otherwise\n * fetches a signed URL on demand. Native <video controls> — keyboard accessible.\n */\nexport const VideoPlayer = ({ blob, resolveUrl, playLabel, label }: VideoPlayerProps) => {\n const [src, setSrc] = useState<string | undefined>(undefined)\n const [loading, setLoading] = useState(false)\n\n useEffect(() => {\n if (!blob) return\n const objectUrl = URL.createObjectURL(blob)\n setSrc(objectUrl)\n return () => URL.revokeObjectURL(objectUrl)\n }, [blob])\n\n const handleLoad = async () => {\n if (!resolveUrl) return\n setLoading(true)\n try {\n setSrc(await resolveUrl())\n } finally {\n setLoading(false)\n }\n }\n\n if (!src) {\n return (\n <button\n type=\"button\"\n onClick={handleLoad}\n disabled={loading || !resolveUrl}\n className=\"sc:rounded-2xl sc:bg-response sc:text-response-fg sc:px-4 sc:py-2.5 sc:text-sm sc:cursor-pointer sc:disabled:opacity-60\"\n >\n {playLabel}\n </button>\n )\n }\n\n return (\n // eslint-disable-next-line jsx-a11y/media-has-caption -- candidate's own recorded answer, no caption track\n <video\n src={src}\n controls\n aria-label={label}\n className=\"sc:max-w-[500px] sc:w-full sc:rounded-2xl sc:bg-black\"\n />\n )\n}\n","import type { ReactNode, Ref } from 'react'\nimport Markdown from 'react-markdown'\nimport { sanitizeRichText } from '../../richText'\nimport { DropdownInput } from '../../inputs/DropdownInput/DropdownInput'\nimport { OptionList } from '../../inputs/OptionList/OptionList'\nimport { SliderInput } from '../../inputs/SliderInput/SliderInput'\nimport { EmbeddedVideo } from '../../media/EmbeddedVideo/EmbeddedVideo'\nimport { UploadProgress } from '../../media/UploadProgress/UploadProgress'\nimport { VideoPlayer } from '../../media/VideoPlayer/VideoPlayer'\nimport type { ChatLogItem } from '../types'\n\nexport type SliderLabels = {\n label: string\n hint: string\n submitLabel: string\n}\n\nexport type DropdownLabels = {\n searchPlaceholder: string\n searchLabel: string\n}\n\nexport type MediaLabels = {\n uploadProgress: string\n uploadFailed: string\n retryUpload: string\n playVideo: string\n videoAnswer: string\n /** Accessible title for a backend-delivered embedded agent video. */\n embeddedVideo: string\n}\n\nexport type ChatBubbleLabels = {\n retry: string\n optionsGroup: string\n edit: string\n cancelEdit: string\n /** Eyebrow on every agent transcript turn, e.g. \"Interviewer\". */\n speakerLabel: string\n}\n\nexport type ChatBubbleProps = {\n item: ChatLogItem\n labels: ChatBubbleLabels\n sliderLabels: SliderLabels\n dropdownLabels: DropdownLabels\n mediaLabels: MediaLabels\n onRetry?: () => void\n onSelectOption?: (optionId: string) => void\n onSubmitSlider?: (score: number) => void\n onEdit?: (questionId: string) => void\n onCancelEdit?: () => void\n onRetryVideo?: () => void\n onResolveVideoUrl?: (questionId: string, extension: string) => Promise<string>\n /** Attaches to the bubble's root <li> so the log can scroll it into view. */\n rootRef?: Ref<HTMLLIElement>\n /** Rendered inside the question card body (e.g. the video recorder). */\n footer?: ReactNode\n}\n\nexport const ChatBubble = ({\n item,\n labels,\n sliderLabels,\n dropdownLabels,\n mediaLabels,\n onRetry,\n onSelectOption,\n onSubmitSlider,\n onEdit,\n onCancelEdit,\n onRetryVideo,\n onResolveVideoUrl,\n rootRef,\n footer,\n}: ChatBubbleProps) => {\n const isAgent = item.sender === 'agent'\n const isCard = item.variant === 'card'\n // Interactive candidate content (options/slider/video) spans full width, left-aligned;\n // plain text/HTML answers render as the right-aligned grey bubble.\n const isFullWidth = isCard || isAgent || Boolean(item.options || item.slider || item.video)\n // Candidate = grey right-aligned bubble. Agent (non-card) = transcript turn (below).\n const bubbleClass = `sc:rounded-[18px] sc:rounded-br-[6px] sc:px-[17px] sc:py-[13px] sc:text-base/relaxed sc:break-words sc:[animation:sc-msg-in_.3s_ease_both] sc:[text-wrap:pretty] sc:bg-response sc:text-response-fg ${\n item.pending ? 'sc:opacity-60' : ''\n } ${item.failed ? 'sc:opacity-60 sc:border sc:border-red-400' : ''}`\n\n // Blinking caret shown inline at the end of an agent message while it streams.\n // Decorative (aria-hidden); inline-style animation is immune to class re-gen on\n // each reveal tick, and the prefers-reduced-motion block still neutralises it.\n const caret = item.streaming ? (\n <span\n aria-hidden=\"true\"\n className=\"sc:ml-px sc:inline-block sc:h-[1em] sc:w-[3px] sc:translate-y-[0.12em] sc:rounded-[1px] sc:bg-pink-strong\"\n style={{ animation: 'sc-caret-blink 1s step-end infinite' }}\n />\n ) : null\n\n // While streaming, render plain inline text so the caret sits on the last line;\n // Markdown's block <p> would push it to its own line. The settled bubble uses Markdown.\n const renderText = (paragraph: string) =>\n isAgent && !item.streaming ? (\n <Markdown\n components={{\n a: ({ children, href }) => (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"sc:underline\">\n {children}\n </a>\n ),\n }}\n >\n {paragraph}\n </Markdown>\n ) : (\n paragraph\n )\n\n return (\n <li\n ref={rootRef}\n className={\n isFullWidth\n ? 'sc:flex sc:flex-col sc:gap-2 sc:self-start sc:w-full'\n : 'sc:flex sc:flex-col sc:gap-1 sc:max-w-[82%] sc:self-end sc:items-end'\n }\n >\n {isCard ? (\n <div\n className={`sc:w-full sc:border-l-[3px] sc:border-speaker sc:pl-4 sc:[animation:sc-msg-in_.35s_ease_both] ${item.pending ? 'sc:opacity-60' : ''} ${item.failed ? 'sc:opacity-60' : ''}`}\n >\n {item.questionLabel || item.questionBadge ? (\n <div className=\"sc:flex sc:items-center sc:gap-2.5\">\n {item.questionLabel ? (\n <span className=\"sc:text-[11.5px] sc:font-bold sc:uppercase sc:tracking-[0.1em] sc:text-speaker\">\n {item.questionLabel}\n </span>\n ) : null}\n {item.questionBadge ? (\n <span className=\"sc:inline-flex sc:items-center sc:gap-1.5 sc:rounded-full sc:bg-button sc:px-2.5 sc:py-1 sc:text-[10.5px] sc:font-bold sc:tracking-[0.08em] sc:text-button-fg sc:uppercase\">\n <span aria-hidden=\"true\" className=\"sc:size-1.5 sc:rounded-full sc:bg-pink-strong\" />\n {item.questionBadge}\n </span>\n ) : null}\n </div>\n ) : null}\n <div className=\"sc:mt-2.5 sc:text-[21px]/[1.38] sc:font-bold sc:text-question-fg sc:[text-wrap:pretty]\">\n {item.paragraphs.map((paragraph, index) => (\n <div key={`${item.id}-${index}`}>\n {renderText(paragraph)}\n {index === item.paragraphs.length - 1 ? caret : null}\n </div>\n ))}\n </div>\n {footer}\n </div>\n ) : isAgent ? (\n // Interviewer conversational turn: labelled transcript entry, not a bubble.\n <div className=\"sc:flex sc:flex-col sc:gap-1 sc:border-l-2 sc:border-pink sc:pl-4 sc:[animation:sc-msg-in_.3s_ease_both]\">\n <span className=\"sc:text-[11px] sc:font-semibold sc:uppercase sc:tracking-[0.11em] sc:text-speaker\">\n {labels.speakerLabel}\n </span>\n <div className=\"sc:text-base/[1.62] sc:text-[#37333d] sc:[text-wrap:pretty]\">\n {item.paragraphs.map((paragraph, index) => (\n <div key={`${item.id}-${index}`} className=\"sc:whitespace-pre-wrap\">\n {renderText(paragraph)}\n {index === item.paragraphs.length - 1 ? caret : null}\n </div>\n ))}\n </div>\n </div>\n ) : item.answerHtml ? (\n // Candidate rich-text answer: re-sanitized on render (defense in depth).\n <div\n className={`${bubbleClass} sc:[&_ul]:list-disc sc:[&_ol]:list-decimal`}\n dangerouslySetInnerHTML={{ __html: sanitizeRichText(item.answerHtml) }}\n />\n ) : (\n item.paragraphs.map((paragraph, index) => (\n <div key={`${item.id}-${index}`} className={`${bubbleClass} sc:whitespace-pre-wrap`}>\n {renderText(paragraph)}\n {index === item.paragraphs.length - 1 ? caret : null}\n </div>\n ))\n )}\n {item.options && item.optionsKind === 'dropdown' ? (\n <DropdownInput\n options={item.options}\n selectedOptionId={item.selectedOptionId}\n enabled={Boolean(item.optionsEnabled)}\n pending={item.pending}\n searchPlaceholder={dropdownLabels.searchPlaceholder}\n searchLabel={dropdownLabels.searchLabel}\n groupLabel={labels.optionsGroup}\n onSelect={onSelectOption}\n />\n ) : item.options ? (\n <OptionList\n options={item.options}\n selectedOptionId={item.selectedOptionId}\n enabled={Boolean(item.optionsEnabled)}\n pending={item.pending}\n groupLabel={labels.optionsGroup}\n onSelect={onSelectOption}\n />\n ) : null}\n {item.slider ? (\n <SliderInput\n min={item.slider.min}\n max={item.slider.max}\n defaultValue={item.slider.defaultValue}\n submittedValue={item.slider.submittedValue}\n enabled={item.slider.enabled}\n pending={item.pending}\n label={sliderLabels.label}\n hint={sliderLabels.hint}\n submitLabel={sliderLabels.submitLabel}\n onSubmit={onSubmitSlider}\n />\n ) : null}\n {item.video ? (\n item.video.uploadProgress !== undefined && !item.video.failed ? (\n <UploadProgress value={item.video.uploadProgress} label={mediaLabels.uploadProgress} />\n ) : item.video.failed ? (\n <div className=\"sc:flex sc:flex-col sc:gap-1 sc:items-end\">\n <p role=\"alert\" className=\"sc:text-sm sc:text-red-600\">\n {mediaLabels.uploadFailed}\n </p>\n {onRetryVideo ? (\n <button\n type=\"button\"\n onClick={onRetryVideo}\n className=\"sc:text-xs sc:font-medium sc:text-red-600 sc:underline sc:cursor-pointer\"\n >\n {mediaLabels.retryUpload}\n </button>\n ) : null}\n </div>\n ) : (\n <VideoPlayer\n blob={item.video.blob}\n resolveUrl={\n !item.video.blob && onResolveVideoUrl && item.video.extension\n ? () =>\n onResolveVideoUrl(item.video!.questionId, item.video!.extension as string)\n : undefined\n }\n playLabel={mediaLabels.playVideo}\n label={mediaLabels.videoAnswer}\n />\n )\n ) : null}\n {item.embeddedVideo ? (\n <EmbeddedVideo url={item.embeddedVideo.url} label={mediaLabels.embeddedVideo} />\n ) : null}\n {item.failed && onRetry ? (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"sc:text-xs sc:font-medium sc:text-red-600 sc:underline sc:cursor-pointer\"\n >\n {labels.retry}\n </button>\n ) : null}\n {item.editableQuestionId && onEdit ? (\n <button\n type=\"button\"\n onClick={() => onEdit(item.editableQuestionId as string)}\n className=\"sc:text-xs sc:font-medium sc:text-response sc:underline sc:cursor-pointer\"\n >\n {labels.edit}\n </button>\n ) : null}\n {item.editing && onCancelEdit ? (\n <button\n type=\"button\"\n onClick={onCancelEdit}\n className=\"sc:text-xs sc:font-medium sc:text-black/60 sc:underline sc:cursor-pointer\"\n >\n {labels.cancelEdit}\n </button>\n ) : null}\n </li>\n )\n}\n","import { useEffect, useState } from 'react'\n\nexport type TypingIndicatorProps = {\n /** Stable accessible description for screen readers, e.g. \"Interviewer is typing\". */\n ariaLabel: string\n /** Phase-1 status shown briefly when responding to a candidate answer. */\n readingLabel: string\n /** Phase-2 status (and the only status when there's no answer to read). */\n thinkingLabel: string\n /** True when the previous message is a candidate answer (enables the \"reading\" phase). */\n afterAnswer: boolean\n}\n\n/** How long the \"reading\" phase shows before switching to \"thinking\" — a quick\n * flash so \"thinking\" gets the airtime (the typing window is often under a second). */\nconst READING_PHASE_MS = 400\n\nconst DOT_CLASS = 'sc:size-[5px] sc:rounded-full sc:bg-pink-strong sc:[animation:sc-dot-blink_1.2s_infinite]'\n\n/**\n * Pre-stream loading status: a phrase + animated dots rendered directly in the\n * transcript (no bubble/background) under the interviewer left rule. When\n * responding to an answer it reads \"Reading your response…\" then \"Thinking about\n * it…\"; on the first agent turn it shows only the \"thinking\" phrase.\n */\nexport const TypingIndicator = ({\n ariaLabel,\n readingLabel,\n thinkingLabel,\n afterAnswer,\n}: TypingIndicatorProps) => {\n const [thinking, setThinking] = useState(!afterAnswer)\n\n useEffect(() => {\n if (!afterAnswer) return\n const timer = setTimeout(() => setThinking(true), READING_PHASE_MS)\n return () => clearTimeout(timer)\n }, [afterAnswer])\n\n const phrase = thinking ? thinkingLabel : readingLabel\n\n return (\n <div\n role=\"status\"\n aria-label={ariaLabel}\n className=\"sc:flex sc:items-center sc:gap-2 sc:self-start sc:border-l-2 sc:border-pink sc:pl-4 sc:[animation:sc-msg-in_.25s_ease_both]\"\n >\n <span aria-hidden=\"true\" className=\"sc:text-[13px] sc:font-medium sc:text-muted\">\n {phrase}\n </span>\n <span aria-hidden=\"true\" className=\"sc:flex sc:items-center sc:gap-1\">\n <span className={DOT_CLASS} />\n <span className={`${DOT_CLASS} sc:[animation-delay:.15s]`} />\n <span className={`${DOT_CLASS} sc:[animation-delay:.3s]`} />\n </span>\n </div>\n )\n}\n","import { useCallback, useEffect, useLayoutEffect, useRef, type ReactNode } from 'react'\nimport {\n ChatBubble,\n type ChatBubbleLabels,\n type DropdownLabels,\n type MediaLabels,\n type SliderLabels,\n} from '../ChatBubble/ChatBubble'\nimport { TypingIndicator } from '../TypingIndicator/TypingIndicator'\nimport type { ChatLogItem } from '../types'\n\nexport type ChatLogProps = {\n items: ChatLogItem[]\n typing: boolean\n /** Stable screen-reader label for the loading status, e.g. \"Interviewer is typing\". */\n typingLabel: string\n /** Phase-1 loading phrase shown after a candidate answer. */\n typingReadingLabel: string\n /** Phase-2 loading phrase (and the only one on the first agent turn). */\n typingThinkingLabel: string\n bubbleLabels: ChatBubbleLabels\n sliderLabels: SliderLabels\n dropdownLabels: DropdownLabels\n mediaLabels: MediaLabels\n onRetry?: () => void\n onSelectOption?: (optionId: string) => void\n onSubmitSlider?: (score: number) => void\n onEdit?: (questionId: string) => void\n onCancelEdit?: () => void\n onRetryVideo?: () => void\n onResolveVideoUrl?: (questionId: string, extension: string) => Promise<string>\n /** Node rendered inside the question card identified by cardFooterItemId (e.g. video recorder). */\n cardFooter?: ReactNode\n /** Bubble id whose card receives cardFooter. */\n cardFooterItemId?: string\n}\n\n/**\n * Scrollable interview transcript. aria-live announces new bubbles to screen\n * readers; the log auto-scrolls to the newest message.\n */\nexport const ChatLog = ({\n items,\n typing,\n typingLabel,\n typingReadingLabel,\n typingThinkingLabel,\n bubbleLabels,\n sliderLabels,\n dropdownLabels,\n mediaLabels,\n onRetry,\n onSelectOption,\n onSubmitSlider,\n onEdit,\n onCancelEdit,\n onRetryVideo,\n onResolveVideoUrl,\n cardFooter,\n cardFooterItemId,\n}: ChatLogProps) => {\n const scrollRef = useRef<HTMLDivElement>(null)\n const contentRef = useRef<HTMLOListElement>(null)\n const spacerRef = useRef<HTMLDivElement>(null)\n const anchorRef = useRef<HTMLLIElement>(null)\n\n // The latest candidate (user) message is the scroll/pin anchor.\n let anchorIndex = -1\n for (let i = items.length - 1; i >= 0; i--) {\n if (items[i].sender === 'candidate') {\n anchorIndex = i\n break\n }\n }\n const lastItem = items[items.length - 1]\n const lastId = lastItem?.id\n // Pin-to-top fires ONLY when the candidate just produced an answer (free-text send\n // or an option select that collapsed to text). It must not fire when a question\n // renders — including the MCQ options bubble, which is a candidate bubble that\n // starts empty (options, no answer text yet).\n const lastIsAnswer =\n lastItem?.sender === 'candidate' &&\n (lastItem.paragraphs.length > 0 || Boolean(lastItem.answerHtml))\n // Pin-to-top fires when a new candidate bubble appears (free-text send) AND when\n // the latest candidate bubble collapses to an answer in place (MCQ/dropdown\n // select, same bubble id) — so a selection scrolls to top like a sent answer.\n const lastAnswerSig = lastItem\n ? `${lastItem.paragraphs.join('\u0001')}${lastItem.answerHtml ?? ''}`\n : ''\n\n // Size a bottom spacer so the anchored message can sit at the very top while the\n // agent reply streams in below it. Shrinks as the reply grows (no excess blank\n // space), grows when there isn't enough reply yet. Never changes scrollTop.\n //\n // The natural (spacer-less) content height is derived by SUBTRACTING the spacer's\n // current height — not by zeroing the spacer to remeasure. Zeroing transiently\n // collapses scrollHeight, and since scrollTop sits at the max right after a pin,\n // the browser clamps scrollTop downward and never restores it (a jump toward the\n // bottom — seen when the next question is also an MCQ and the anchor switches to\n // the freshly appended options bubble). Subtraction keeps scrollTop untouched.\n const fitSpacer = useCallback(() => {\n const container = scrollRef.current\n const anchor = anchorRef.current\n const spacer = spacerRef.current\n if (!container || !anchor || !spacer) return\n const anchorTop =\n anchor.getBoundingClientRect().top -\n container.getBoundingClientRect().top +\n container.scrollTop\n const naturalHeight = container.scrollHeight - spacer.offsetHeight\n const fill = container.clientHeight - (naturalHeight - anchorTop)\n spacer.style.height = fill > 0 ? `${fill}px` : '0px'\n }, [])\n\n // On a new candidate answer (sent or selected): size the spacer, then scroll the\n // answer to the top. Runs in a layout effect (before paint) so the spacer is grown\n // BEFORE the browser paints the collapsed bubble — otherwise an MCQ select shrinks\n // the content (tall options -> one line), the browser clamps scrollTop upward, and\n // the subsequent scroll glides back down (visible bounce). Question/options renders\n // and agent content never scroll.\n useLayoutEffect(() => {\n if (!lastIsAnswer) return\n fitSpacer()\n const container = scrollRef.current\n const anchor = anchorRef.current\n if (!container || !anchor) return\n const top =\n anchor.getBoundingClientRect().top -\n container.getBoundingClientRect().top +\n container.scrollTop\n container.scrollTo?.({ top, behavior: 'smooth' })\n }, [lastId, lastIsAnswer, lastAnswerSig, fitSpacer])\n\n // Re-fit the spacer as content height changes (streaming reveal), without scrolling.\n useEffect(() => {\n if (typeof ResizeObserver === 'undefined') return\n const content = contentRef.current\n if (!content) return\n const observer = new ResizeObserver(() => fitSpacer())\n observer.observe(content)\n return () => observer.disconnect()\n }, [fitSpacer])\n\n return (\n <div\n ref={scrollRef}\n className=\"sc:flex-1 sc:overflow-y-auto sc:bg-canvas sc:px-4 sc:py-5\"\n aria-live=\"polite\"\n >\n <ol\n ref={contentRef}\n className=\"sc:mx-auto sc:flex sc:max-w-[640px] sc:flex-col sc:gap-2.5 sc:list-none\"\n >\n {items.map((item, index) => (\n <ChatBubble\n key={item.id}\n rootRef={index === anchorIndex ? anchorRef : undefined}\n item={item}\n labels={bubbleLabels}\n sliderLabels={sliderLabels}\n dropdownLabels={dropdownLabels}\n mediaLabels={mediaLabels}\n onRetry={item.failed ? onRetry : undefined}\n onSelectOption={item.optionsEnabled ? onSelectOption : undefined}\n onSubmitSlider={item.slider?.enabled ? onSubmitSlider : undefined}\n onEdit={onEdit}\n onCancelEdit={onCancelEdit}\n onRetryVideo={item.video?.failed ? onRetryVideo : undefined}\n onResolveVideoUrl={onResolveVideoUrl}\n footer={cardFooterItemId && item.id === cardFooterItemId ? cardFooter : undefined}\n />\n ))}\n {typing ? (\n <li className=\"sc:flex sc:flex-col\">\n <TypingIndicator\n ariaLabel={typingLabel}\n readingLabel={typingReadingLabel}\n thinkingLabel={typingThinkingLabel}\n afterAnswer={lastIsAnswer}\n />\n </li>\n ) : null}\n </ol>\n {/* Dynamic spacer: lets the latest user message scroll to the top. */}\n <div ref={spacerRef} aria-hidden=\"true\" />\n </div>\n )\n}\n","// src/primitive.tsx\nvar canUseDOM = !!(typeof window !== \"undefined\" && window.document && window.document.createElement);\nfunction composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {\n return function handleEvent(event) {\n originalEventHandler?.(event);\n if (checkForDefaultPrevented === false || !event.defaultPrevented) {\n return ourEventHandler?.(event);\n }\n };\n}\nfunction getOwnerWindow(element) {\n if (!canUseDOM) {\n throw new Error(\"Cannot access window outside of the DOM\");\n }\n return element?.ownerDocument?.defaultView ?? window;\n}\nfunction getOwnerDocument(element) {\n if (!canUseDOM) {\n throw new Error(\"Cannot access document outside of the DOM\");\n }\n return element?.ownerDocument ?? document;\n}\nfunction getActiveElement(node, activeDescendant = false) {\n const { activeElement } = getOwnerDocument(node);\n if (!activeElement?.nodeName) {\n return null;\n }\n if (isFrame(activeElement) && activeElement.contentDocument) {\n return getActiveElement(activeElement.contentDocument.body, activeDescendant);\n }\n if (activeDescendant) {\n const id = activeElement.getAttribute(\"aria-activedescendant\");\n if (id) {\n const element = getOwnerDocument(activeElement).getElementById(id);\n if (element) {\n return element;\n }\n }\n }\n return activeElement;\n}\nfunction isFrame(element) {\n return element.tagName === \"IFRAME\";\n}\nexport {\n canUseDOM,\n composeEventHandlers,\n getActiveElement,\n getOwnerDocument,\n getOwnerWindow,\n isFrame\n};\n//# sourceMappingURL=index.mjs.map\n","// src/compose-refs.tsx\nimport * as React from \"react\";\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\nfunction composeRefs(...refs) {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup == \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup == \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\nfunction useComposedRefs(...refs) {\n return React.useCallback(composeRefs(...refs), refs);\n}\nexport {\n composeRefs,\n useComposedRefs\n};\n//# sourceMappingURL=index.mjs.map\n","// src/create-context.tsx\nimport * as React from \"react\";\nimport { jsx } from \"react/jsx-runtime\";\nfunction createContext2(rootComponentName, defaultContext) {\n const Context = React.createContext(defaultContext);\n Context.displayName = rootComponentName + \"Context\";\n const Provider = (props) => {\n const { children, ...context } = props;\n const value = React.useMemo(() => context, Object.values(context));\n return /* @__PURE__ */ jsx(Context.Provider, { value, children });\n };\n Provider.displayName = rootComponentName + \"Provider\";\n function useContext2(consumerName) {\n const context = React.useContext(Context);\n if (context) return context;\n if (defaultContext !== void 0) return defaultContext;\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n return [Provider, useContext2];\n}\nfunction createContextScope(scopeName, createContextScopeDeps = []) {\n let defaultContexts = [];\n function createContext3(rootComponentName, defaultContext) {\n const BaseContext = React.createContext(defaultContext);\n BaseContext.displayName = rootComponentName + \"Context\";\n const index = defaultContexts.length;\n defaultContexts = [...defaultContexts, defaultContext];\n const Provider = (props) => {\n const { scope, children, ...context } = props;\n const Context = scope?.[scopeName]?.[index] || BaseContext;\n const value = React.useMemo(() => context, Object.values(context));\n return /* @__PURE__ */ jsx(Context.Provider, { value, children });\n };\n Provider.displayName = rootComponentName + \"Provider\";\n function useContext2(consumerName, scope) {\n const Context = scope?.[scopeName]?.[index] || BaseContext;\n const context = React.useContext(Context);\n if (context) return context;\n if (defaultContext !== void 0) return defaultContext;\n throw new Error(`\\`${consumerName}\\` must be used within \\`${rootComponentName}\\``);\n }\n return [Provider, useContext2];\n }\n const createScope = () => {\n const scopeContexts = defaultContexts.map((defaultContext) => {\n return React.createContext(defaultContext);\n });\n return function useScope(scope) {\n const contexts = scope?.[scopeName] || scopeContexts;\n return React.useMemo(\n () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),\n [scope, contexts]\n );\n };\n };\n createScope.scopeName = scopeName;\n return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)];\n}\nfunction composeContextScopes(...scopes) {\n const baseScope = scopes[0];\n if (scopes.length === 1) return baseScope;\n const createScope = () => {\n const scopeHooks = scopes.map((createScope2) => ({\n useScope: createScope2(),\n scopeName: createScope2.scopeName\n }));\n return function useComposedScopes(overrideScopes) {\n const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {\n const scopeProps = useScope(overrideScopes);\n const currentScope = scopeProps[`__scope${scopeName}`];\n return { ...nextScopes2, ...currentScope };\n }, {});\n return React.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);\n };\n };\n createScope.scopeName = baseScope.scopeName;\n return createScope;\n}\nexport {\n createContext2 as createContext,\n createContextScope\n};\n//# sourceMappingURL=index.mjs.map\n","// src/use-layout-effect.tsx\nimport * as React from \"react\";\nvar useLayoutEffect2 = globalThis?.document ? React.useLayoutEffect : () => {\n};\nexport {\n useLayoutEffect2 as useLayoutEffect\n};\n//# sourceMappingURL=index.mjs.map\n","// src/id.tsx\nimport * as React from \"react\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nvar useReactId = React[\" useId \".trim().toString()] || (() => void 0);\nvar count = 0;\nfunction useId(deterministicId) {\n const [id, setId] = React.useState(useReactId());\n useLayoutEffect(() => {\n if (!deterministicId) setId((reactId) => reactId ?? String(count++));\n }, [deterministicId]);\n return deterministicId || (id ? `radix-${id}` : \"\");\n}\nexport {\n useId\n};\n//# sourceMappingURL=index.mjs.map\n","// src/use-controllable-state.tsx\nimport * as React from \"react\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nvar useInsertionEffect = React[\" useInsertionEffect \".trim().toString()] || useLayoutEffect;\nfunction useControllableState({\n prop,\n defaultProp,\n onChange = () => {\n },\n caller\n}) {\n const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({\n defaultProp,\n onChange\n });\n const isControlled = prop !== void 0;\n const value = isControlled ? prop : uncontrolledProp;\n if (true) {\n const isControlledRef = React.useRef(prop !== void 0);\n React.useEffect(() => {\n const wasControlled = isControlledRef.current;\n if (wasControlled !== isControlled) {\n const from = wasControlled ? \"controlled\" : \"uncontrolled\";\n const to = isControlled ? \"controlled\" : \"uncontrolled\";\n console.warn(\n `${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`\n );\n }\n isControlledRef.current = isControlled;\n }, [isControlled, caller]);\n }\n const setValue = React.useCallback(\n (nextValue) => {\n if (isControlled) {\n const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;\n if (value2 !== prop) {\n onChangeRef.current?.(value2);\n }\n } else {\n setUncontrolledProp(nextValue);\n }\n },\n [isControlled, prop, setUncontrolledProp, onChangeRef]\n );\n return [value, setValue];\n}\nfunction useUncontrolledState({\n defaultProp,\n onChange\n}) {\n const [value, setValue] = React.useState(defaultProp);\n const prevValueRef = React.useRef(value);\n const onChangeRef = React.useRef(onChange);\n useInsertionEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n React.useEffect(() => {\n if (prevValueRef.current !== value) {\n onChangeRef.current?.(value);\n prevValueRef.current = value;\n }\n }, [value, prevValueRef]);\n return [value, setValue, onChangeRef];\n}\nfunction isFunction(value) {\n return typeof value === \"function\";\n}\n\n// src/use-controllable-state-reducer.tsx\nimport * as React2 from \"react\";\nimport { useEffectEvent } from \"@radix-ui/react-use-effect-event\";\nvar SYNC_STATE = Symbol(\"RADIX:SYNC_STATE\");\nfunction useControllableStateReducer(reducer, userArgs, initialArg, init) {\n const { prop: controlledState, defaultProp, onChange: onChangeProp, caller } = userArgs;\n const isControlled = controlledState !== void 0;\n const onChange = useEffectEvent(onChangeProp);\n if (true) {\n const isControlledRef = React2.useRef(controlledState !== void 0);\n React2.useEffect(() => {\n const wasControlled = isControlledRef.current;\n if (wasControlled !== isControlled) {\n const from = wasControlled ? \"controlled\" : \"uncontrolled\";\n const to = isControlled ? \"controlled\" : \"uncontrolled\";\n console.warn(\n `${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`\n );\n }\n isControlledRef.current = isControlled;\n }, [isControlled, caller]);\n }\n const args = [{ ...initialArg, state: defaultProp }];\n if (init) {\n args.push(init);\n }\n const [internalState, dispatch] = React2.useReducer(\n (state2, action) => {\n if (action.type === SYNC_STATE) {\n return { ...state2, state: action.state };\n }\n const next = reducer(state2, action);\n if (isControlled && !Object.is(next.state, state2.state)) {\n onChange(next.state);\n }\n return next;\n },\n ...args\n );\n const uncontrolledState = internalState.state;\n const prevValueRef = React2.useRef(uncontrolledState);\n React2.useEffect(() => {\n if (prevValueRef.current !== uncontrolledState) {\n prevValueRef.current = uncontrolledState;\n if (!isControlled) {\n onChange(uncontrolledState);\n }\n }\n }, [uncontrolledState, prevValueRef, isControlled]);\n const state = React2.useMemo(() => {\n const isControlled2 = controlledState !== void 0;\n if (isControlled2) {\n return { ...internalState, state: controlledState };\n }\n return internalState;\n }, [internalState, controlledState]);\n React2.useEffect(() => {\n if (isControlled && !Object.is(controlledState, internalState.state)) {\n dispatch({ type: SYNC_STATE, state: controlledState });\n }\n }, [controlledState, internalState.state, isControlled]);\n return [state, dispatch];\n}\nexport {\n useControllableState,\n useControllableStateReducer\n};\n//# sourceMappingURL=index.mjs.map\n","// src/slot.tsx\nimport * as React from \"react\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\n// @__NO_SIDE_EFFECTS__\nfunction createSlot(ownerName) {\n const Slot2 = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n let slottableElement = null;\n let hasSlottable = false;\n const newChildren = [];\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n React.Children.forEach(children, (maybeSlottable) => {\n if (isSlottable(maybeSlottable)) {\n hasSlottable = true;\n const slottable = maybeSlottable;\n let child = \"child\" in slottable.props ? slottable.props.child : slottable.props.children;\n if (isLazyComponent(child) && typeof use === \"function\") {\n child = use(child._payload);\n }\n slottableElement = getSlottableElementFromSlottable(slottable, child);\n newChildren.push(slottableElement?.props?.children);\n } else {\n newChildren.push(maybeSlottable);\n }\n });\n if (slottableElement) {\n slottableElement = React.cloneElement(slottableElement, void 0, newChildren);\n } else if (\n // A `Slottable` was found but it didn't resolve to a single element (e.g.\n // it wrapped multiple elements, text, or a render-prop `child` that\n // wasn't an element). Don't fall back to treating the `Slottable` wrapper\n // itself as the slot target — throw a descriptive error below instead.\n !hasSlottable && React.Children.count(children) === 1 && React.isValidElement(children)\n ) {\n slottableElement = children;\n }\n const slottableElementRef = slottableElement ? getElementRef(slottableElement) : void 0;\n const composedRef = useComposedRefs(forwardedRef, slottableElementRef);\n if (!slottableElement) {\n if (children || children === 0) {\n throw new Error(\n hasSlottable ? createSlottableError(ownerName) : createSlotError(ownerName)\n );\n }\n return children;\n }\n const mergedProps = mergeProps(slotProps, slottableElement.props ?? {});\n if (slottableElement.type !== React.Fragment) {\n mergedProps.ref = forwardedRef ? composedRef : slottableElementRef;\n }\n return React.cloneElement(slottableElement, mergedProps);\n });\n Slot2.displayName = `${ownerName}.Slot`;\n return Slot2;\n}\nvar Slot = /* @__PURE__ */ createSlot(\"Slot\");\nvar SLOTTABLE_IDENTIFIER = Symbol.for(\"radix.slottable\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlottable(ownerName) {\n const Slottable2 = (props) => \"child\" in props ? props.children(props.child) : props.children;\n Slottable2.displayName = `${ownerName}.Slottable`;\n Slottable2.__radixId = SLOTTABLE_IDENTIFIER;\n return Slottable2;\n}\nvar Slottable = /* @__PURE__ */ createSlottable(\"Slottable\");\nvar getSlottableElementFromSlottable = (slottable, child) => {\n if (\"child\" in slottable.props) {\n const child2 = slottable.props.child;\n if (!React.isValidElement(child2)) return null;\n return React.cloneElement(child2, void 0, slottable.props.children(child2.props.children));\n }\n return React.isValidElement(child) ? child : null;\n};\nfunction mergeProps(slotProps, childProps) {\n const overrideProps = { ...childProps };\n for (const propName in childProps) {\n const slotPropValue = slotProps[propName];\n const childPropValue = childProps[propName];\n const isHandler = /^on[A-Z]/.test(propName);\n if (isHandler) {\n if (slotPropValue && childPropValue) {\n overrideProps[propName] = (...args) => {\n const result = childPropValue(...args);\n slotPropValue(...args);\n return result;\n };\n } else if (slotPropValue) {\n overrideProps[propName] = slotPropValue;\n }\n } else if (propName === \"style\") {\n overrideProps[propName] = { ...slotPropValue, ...childPropValue };\n } else if (propName === \"className\") {\n overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(\" \");\n }\n }\n return { ...slotProps, ...overrideProps };\n}\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\nfunction isSlottable(child) {\n return React.isValidElement(child) && typeof child.type === \"function\" && \"__radixId\" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;\n}\nvar REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nfunction isLazyComponent(element) {\n return element != null && typeof element === \"object\" && \"$$typeof\" in element && element.$$typeof === REACT_LAZY_TYPE && \"_payload\" in element && isPromiseLike(element._payload);\n}\nfunction isPromiseLike(value) {\n return typeof value === \"object\" && value !== null && \"then\" in value;\n}\nvar createSlotError = (ownerName) => {\n return `${ownerName} failed to slot onto its children. Expected a single React element child or \\`Slottable\\`.`;\n};\nvar createSlottableError = (ownerName) => {\n return `${ownerName} failed to slot onto its \\`Slottable\\`. Expected \\`Slottable\\` to receive a single React element child.`;\n};\nvar use = React[\" use \".trim().toString()];\nexport {\n Slot as Root,\n Slot,\n Slottable,\n createSlot,\n createSlottable\n};\n//# sourceMappingURL=index.mjs.map\n","// src/primitive.tsx\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { jsx } from \"react/jsx-runtime\";\nvar NODES = [\n \"a\",\n \"button\",\n \"div\",\n \"form\",\n \"h2\",\n \"h3\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"nav\",\n \"ol\",\n \"p\",\n \"select\",\n \"span\",\n \"svg\",\n \"ul\"\n];\nvar Primitive = NODES.reduce((primitive, node) => {\n const Slot = createSlot(`Primitive.${node}`);\n const Node = React.forwardRef((props, forwardedRef) => {\n const { asChild, ...primitiveProps } = props;\n const Comp = asChild ? Slot : node;\n if (typeof window !== \"undefined\") {\n window[Symbol.for(\"radix-ui\")] = true;\n }\n return /* @__PURE__ */ jsx(Comp, { ...primitiveProps, ref: forwardedRef });\n });\n Node.displayName = `Primitive.${node}`;\n return { ...primitive, [node]: Node };\n}, {});\nfunction dispatchDiscreteCustomEvent(target, event) {\n if (target) ReactDOM.flushSync(() => target.dispatchEvent(event));\n}\nvar Root = Primitive;\nexport {\n Primitive,\n Root,\n dispatchDiscreteCustomEvent\n};\n//# sourceMappingURL=index.mjs.map\n","// src/use-callback-ref.tsx\nimport * as React from \"react\";\nfunction useCallbackRef(callback) {\n const callbackRef = React.useRef(callback);\n React.useEffect(() => {\n callbackRef.current = callback;\n });\n return React.useMemo(() => ((...args) => callbackRef.current?.(...args)), []);\n}\nexport {\n useCallbackRef\n};\n//# sourceMappingURL=index.mjs.map\n","// src/use-escape-keydown.tsx\nimport * as React from \"react\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nfunction useEscapeKeydown(onEscapeKeyDownProp, ownerDocument = globalThis?.document) {\n const onEscapeKeyDown = useCallbackRef(onEscapeKeyDownProp);\n React.useEffect(() => {\n const handleKeyDown = (event) => {\n if (event.key === \"Escape\") {\n onEscapeKeyDown(event);\n }\n };\n ownerDocument.addEventListener(\"keydown\", handleKeyDown, { capture: true });\n return () => ownerDocument.removeEventListener(\"keydown\", handleKeyDown, { capture: true });\n }, [onEscapeKeyDown, ownerDocument]);\n}\nexport {\n useEscapeKeydown\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/dismissable-layer.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { Primitive, dispatchDiscreteCustomEvent } from \"@radix-ui/react-primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useEscapeKeydown } from \"@radix-ui/react-use-escape-keydown\";\nimport { jsx } from \"react/jsx-runtime\";\nvar DISMISSABLE_LAYER_NAME = \"DismissableLayer\";\nvar CONTEXT_UPDATE = \"dismissableLayer.update\";\nvar POINTER_DOWN_OUTSIDE = \"dismissableLayer.pointerDownOutside\";\nvar FOCUS_OUTSIDE = \"dismissableLayer.focusOutside\";\nvar originalBodyPointerEvents;\nvar DismissableLayerContext = React.createContext({\n layers: /* @__PURE__ */ new Set(),\n layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),\n branches: /* @__PURE__ */ new Set()\n});\nvar DismissableLayer = React.forwardRef(\n (props, forwardedRef) => {\n const {\n disableOutsidePointerEvents = false,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onInteractOutside,\n onDismiss,\n ...layerProps\n } = props;\n const context = React.useContext(DismissableLayerContext);\n const [node, setNode] = React.useState(null);\n const ownerDocument = node?.ownerDocument ?? globalThis?.document;\n const [, force] = React.useState({});\n const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));\n const layers = Array.from(context.layers);\n const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);\n const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);\n const index = node ? layers.indexOf(node) : -1;\n const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;\n const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;\n const pointerDownOutside = usePointerDownOutside((event) => {\n const target = event.target;\n const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));\n if (!isPointerEventsEnabled || isPointerDownOnBranch) return;\n onPointerDownOutside?.(event);\n onInteractOutside?.(event);\n if (!event.defaultPrevented) onDismiss?.();\n }, ownerDocument);\n const focusOutside = useFocusOutside((event) => {\n const target = event.target;\n const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));\n if (isFocusInBranch) return;\n onFocusOutside?.(event);\n onInteractOutside?.(event);\n if (!event.defaultPrevented) onDismiss?.();\n }, ownerDocument);\n useEscapeKeydown((event) => {\n const isHighestLayer = index === context.layers.size - 1;\n if (!isHighestLayer) return;\n onEscapeKeyDown?.(event);\n if (!event.defaultPrevented && onDismiss) {\n event.preventDefault();\n onDismiss();\n }\n }, ownerDocument);\n React.useEffect(() => {\n if (!node) return;\n if (disableOutsidePointerEvents) {\n if (context.layersWithOutsidePointerEventsDisabled.size === 0) {\n originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;\n ownerDocument.body.style.pointerEvents = \"none\";\n }\n context.layersWithOutsidePointerEventsDisabled.add(node);\n }\n context.layers.add(node);\n dispatchUpdate();\n return () => {\n if (disableOutsidePointerEvents) {\n context.layersWithOutsidePointerEventsDisabled.delete(node);\n if (context.layersWithOutsidePointerEventsDisabled.size === 0) {\n ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;\n }\n }\n };\n }, [node, ownerDocument, disableOutsidePointerEvents, context]);\n React.useEffect(() => {\n return () => {\n if (!node) return;\n context.layers.delete(node);\n context.layersWithOutsidePointerEventsDisabled.delete(node);\n dispatchUpdate();\n };\n }, [node, context]);\n React.useEffect(() => {\n const handleUpdate = () => force({});\n document.addEventListener(CONTEXT_UPDATE, handleUpdate);\n return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);\n }, []);\n return /* @__PURE__ */ jsx(\n Primitive.div,\n {\n ...layerProps,\n ref: composedRefs,\n style: {\n pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? \"auto\" : \"none\" : void 0,\n ...props.style\n },\n onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),\n onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),\n onPointerDownCapture: composeEventHandlers(\n props.onPointerDownCapture,\n pointerDownOutside.onPointerDownCapture\n )\n }\n );\n }\n);\nDismissableLayer.displayName = DISMISSABLE_LAYER_NAME;\nvar BRANCH_NAME = \"DismissableLayerBranch\";\nvar DismissableLayerBranch = React.forwardRef((props, forwardedRef) => {\n const context = React.useContext(DismissableLayerContext);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n React.useEffect(() => {\n const node = ref.current;\n if (node) {\n context.branches.add(node);\n return () => {\n context.branches.delete(node);\n };\n }\n }, [context.branches]);\n return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref: composedRefs });\n});\nDismissableLayerBranch.displayName = BRANCH_NAME;\nfunction usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) {\n const handlePointerDownOutside = useCallbackRef(onPointerDownOutside);\n const isPointerInsideReactTreeRef = React.useRef(false);\n const handleClickRef = React.useRef(() => {\n });\n React.useEffect(() => {\n const handlePointerDown = (event) => {\n if (event.target && !isPointerInsideReactTreeRef.current) {\n let handleAndDispatchPointerDownOutsideEvent2 = function() {\n handleAndDispatchCustomEvent(\n POINTER_DOWN_OUTSIDE,\n handlePointerDownOutside,\n eventDetail,\n { discrete: true }\n );\n };\n var handleAndDispatchPointerDownOutsideEvent = handleAndDispatchPointerDownOutsideEvent2;\n const eventDetail = { originalEvent: event };\n if (event.pointerType === \"touch\") {\n ownerDocument.removeEventListener(\"click\", handleClickRef.current);\n handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2;\n ownerDocument.addEventListener(\"click\", handleClickRef.current, { once: true });\n } else {\n handleAndDispatchPointerDownOutsideEvent2();\n }\n } else {\n ownerDocument.removeEventListener(\"click\", handleClickRef.current);\n }\n isPointerInsideReactTreeRef.current = false;\n };\n const timerId = window.setTimeout(() => {\n ownerDocument.addEventListener(\"pointerdown\", handlePointerDown);\n }, 0);\n return () => {\n window.clearTimeout(timerId);\n ownerDocument.removeEventListener(\"pointerdown\", handlePointerDown);\n ownerDocument.removeEventListener(\"click\", handleClickRef.current);\n };\n }, [ownerDocument, handlePointerDownOutside]);\n return {\n // ensures we check React component tree (not just DOM tree)\n onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true\n };\n}\nfunction useFocusOutside(onFocusOutside, ownerDocument = globalThis?.document) {\n const handleFocusOutside = useCallbackRef(onFocusOutside);\n const isFocusInsideReactTreeRef = React.useRef(false);\n React.useEffect(() => {\n const handleFocus = (event) => {\n if (event.target && !isFocusInsideReactTreeRef.current) {\n const eventDetail = { originalEvent: event };\n handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {\n discrete: false\n });\n }\n };\n ownerDocument.addEventListener(\"focusin\", handleFocus);\n return () => ownerDocument.removeEventListener(\"focusin\", handleFocus);\n }, [ownerDocument, handleFocusOutside]);\n return {\n onFocusCapture: () => isFocusInsideReactTreeRef.current = true,\n onBlurCapture: () => isFocusInsideReactTreeRef.current = false\n };\n}\nfunction dispatchUpdate() {\n const event = new CustomEvent(CONTEXT_UPDATE);\n document.dispatchEvent(event);\n}\nfunction handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {\n const target = detail.originalEvent.target;\n const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });\n if (handler) target.addEventListener(name, handler, { once: true });\n if (discrete) {\n dispatchDiscreteCustomEvent(target, event);\n } else {\n target.dispatchEvent(event);\n }\n}\nvar Root = DismissableLayer;\nvar Branch = DismissableLayerBranch;\nexport {\n Branch,\n DismissableLayer,\n DismissableLayerBranch,\n Root\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/focus-scope.tsx\nimport * as React from \"react\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { jsx } from \"react/jsx-runtime\";\nvar AUTOFOCUS_ON_MOUNT = \"focusScope.autoFocusOnMount\";\nvar AUTOFOCUS_ON_UNMOUNT = \"focusScope.autoFocusOnUnmount\";\nvar EVENT_OPTIONS = { bubbles: false, cancelable: true };\nvar FOCUS_SCOPE_NAME = \"FocusScope\";\nvar FocusScope = React.forwardRef((props, forwardedRef) => {\n const {\n loop = false,\n trapped = false,\n onMountAutoFocus: onMountAutoFocusProp,\n onUnmountAutoFocus: onUnmountAutoFocusProp,\n ...scopeProps\n } = props;\n const [container, setContainer] = React.useState(null);\n const onMountAutoFocus = useCallbackRef(onMountAutoFocusProp);\n const onUnmountAutoFocus = useCallbackRef(onUnmountAutoFocusProp);\n const lastFocusedElementRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setContainer(node));\n const focusScope = React.useRef({\n paused: false,\n pause() {\n this.paused = true;\n },\n resume() {\n this.paused = false;\n }\n }).current;\n React.useEffect(() => {\n if (trapped) {\n let handleFocusIn2 = function(event) {\n if (focusScope.paused || !container) return;\n const target = event.target;\n if (container.contains(target)) {\n lastFocusedElementRef.current = target;\n } else {\n focus(lastFocusedElementRef.current, { select: true });\n }\n }, handleFocusOut2 = function(event) {\n if (focusScope.paused || !container) return;\n const relatedTarget = event.relatedTarget;\n if (relatedTarget === null) return;\n if (!container.contains(relatedTarget)) {\n focus(lastFocusedElementRef.current, { select: true });\n }\n }, handleMutations2 = function(mutations) {\n const focusedElement = document.activeElement;\n if (focusedElement !== document.body) return;\n for (const mutation of mutations) {\n if (mutation.removedNodes.length > 0) focus(container);\n }\n };\n var handleFocusIn = handleFocusIn2, handleFocusOut = handleFocusOut2, handleMutations = handleMutations2;\n document.addEventListener(\"focusin\", handleFocusIn2);\n document.addEventListener(\"focusout\", handleFocusOut2);\n const mutationObserver = new MutationObserver(handleMutations2);\n if (container) mutationObserver.observe(container, { childList: true, subtree: true });\n return () => {\n document.removeEventListener(\"focusin\", handleFocusIn2);\n document.removeEventListener(\"focusout\", handleFocusOut2);\n mutationObserver.disconnect();\n };\n }\n }, [trapped, container, focusScope.paused]);\n React.useEffect(() => {\n if (container) {\n focusScopesStack.add(focusScope);\n const previouslyFocusedElement = document.activeElement;\n const hasFocusedCandidate = container.contains(previouslyFocusedElement);\n if (!hasFocusedCandidate) {\n const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS);\n container.addEventListener(AUTOFOCUS_ON_MOUNT, onMountAutoFocus);\n container.dispatchEvent(mountEvent);\n if (!mountEvent.defaultPrevented) {\n focusFirst(removeLinks(getTabbableCandidates(container)), { select: true });\n if (document.activeElement === previouslyFocusedElement) {\n focus(container);\n }\n }\n }\n return () => {\n container.removeEventListener(AUTOFOCUS_ON_MOUNT, onMountAutoFocus);\n setTimeout(() => {\n const unmountEvent = new CustomEvent(AUTOFOCUS_ON_UNMOUNT, EVENT_OPTIONS);\n container.addEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);\n container.dispatchEvent(unmountEvent);\n if (!unmountEvent.defaultPrevented) {\n focus(previouslyFocusedElement ?? document.body, { select: true });\n }\n container.removeEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);\n focusScopesStack.remove(focusScope);\n }, 0);\n };\n }\n }, [container, onMountAutoFocus, onUnmountAutoFocus, focusScope]);\n const handleKeyDown = React.useCallback(\n (event) => {\n if (!loop && !trapped) return;\n if (focusScope.paused) return;\n const isTabKey = event.key === \"Tab\" && !event.altKey && !event.ctrlKey && !event.metaKey;\n const focusedElement = document.activeElement;\n if (isTabKey && focusedElement) {\n const container2 = event.currentTarget;\n const [first, last] = getTabbableEdges(container2);\n const hasTabbableElementsInside = first && last;\n if (!hasTabbableElementsInside) {\n if (focusedElement === container2) event.preventDefault();\n } else {\n if (!event.shiftKey && focusedElement === last) {\n event.preventDefault();\n if (loop) focus(first, { select: true });\n } else if (event.shiftKey && focusedElement === first) {\n event.preventDefault();\n if (loop) focus(last, { select: true });\n }\n }\n }\n },\n [loop, trapped, focusScope.paused]\n );\n return /* @__PURE__ */ jsx(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });\n});\nFocusScope.displayName = FOCUS_SCOPE_NAME;\nfunction focusFirst(candidates, { select = false } = {}) {\n const previouslyFocusedElement = document.activeElement;\n for (const candidate of candidates) {\n focus(candidate, { select });\n if (document.activeElement !== previouslyFocusedElement) return;\n }\n}\nfunction getTabbableEdges(container) {\n const candidates = getTabbableCandidates(container);\n const first = findVisible(candidates, container);\n const last = findVisible(candidates.reverse(), container);\n return [first, last];\n}\nfunction getTabbableCandidates(container) {\n const nodes = [];\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node) => {\n const isHiddenInput = node.tagName === \"INPUT\" && node.type === \"hidden\";\n if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;\n return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;\n }\n });\n while (walker.nextNode()) nodes.push(walker.currentNode);\n return nodes;\n}\nfunction findVisible(elements, container) {\n for (const element of elements) {\n if (!isHidden(element, { upTo: container })) return element;\n }\n}\nfunction isHidden(node, { upTo }) {\n if (getComputedStyle(node).visibility === \"hidden\") return true;\n while (node) {\n if (upTo !== void 0 && node === upTo) return false;\n if (getComputedStyle(node).display === \"none\") return true;\n node = node.parentElement;\n }\n return false;\n}\nfunction isSelectableInput(element) {\n return element instanceof HTMLInputElement && \"select\" in element;\n}\nfunction focus(element, { select = false } = {}) {\n if (element && element.focus) {\n const previouslyFocusedElement = document.activeElement;\n element.focus({ preventScroll: true });\n if (element !== previouslyFocusedElement && isSelectableInput(element) && select)\n element.select();\n }\n}\nvar focusScopesStack = createFocusScopesStack();\nfunction createFocusScopesStack() {\n let stack = [];\n return {\n add(focusScope) {\n const activeFocusScope = stack[0];\n if (focusScope !== activeFocusScope) {\n activeFocusScope?.pause();\n }\n stack = arrayRemove(stack, focusScope);\n stack.unshift(focusScope);\n },\n remove(focusScope) {\n stack = arrayRemove(stack, focusScope);\n stack[0]?.resume();\n }\n };\n}\nfunction arrayRemove(array, item) {\n const updatedArray = [...array];\n const index = updatedArray.indexOf(item);\n if (index !== -1) {\n updatedArray.splice(index, 1);\n }\n return updatedArray;\n}\nfunction removeLinks(items) {\n return items.filter((item) => item.tagName !== \"A\");\n}\nvar Root = FocusScope;\nexport {\n FocusScope,\n Root\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/portal.tsx\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nimport { jsx } from \"react/jsx-runtime\";\nvar PORTAL_NAME = \"Portal\";\nvar Portal = React.forwardRef((props, forwardedRef) => {\n const { container: containerProp, ...portalProps } = props;\n const [mounted, setMounted] = React.useState(false);\n useLayoutEffect(() => setMounted(true), []);\n const container = containerProp || mounted && globalThis?.document?.body;\n return container ? ReactDOM.createPortal(/* @__PURE__ */ jsx(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;\n});\nPortal.displayName = PORTAL_NAME;\nvar Root = Portal;\nexport {\n Portal,\n Root\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/presence.tsx\nimport * as React2 from \"react\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\n\n// src/use-state-machine.tsx\nimport * as React from \"react\";\nfunction useStateMachine(initialState, machine) {\n return React.useReducer((state, event) => {\n const nextState = machine[state][event];\n return nextState ?? state;\n }, initialState);\n}\n\n// src/presence.tsx\nvar Presence = (props) => {\n const { present, children } = props;\n const presence = usePresence(present);\n const child = typeof children === \"function\" ? children({ present: presence.isPresent }) : React2.Children.only(children);\n const ref = useStableComposedRefs(presence.ref, getElementRef(child));\n const forceMount = typeof children === \"function\";\n return forceMount || presence.isPresent ? React2.cloneElement(child, { ref }) : null;\n};\nPresence.displayName = \"Presence\";\nfunction usePresence(present) {\n const [node, setNode] = React2.useState();\n const stylesRef = React2.useRef(null);\n const prevPresentRef = React2.useRef(present);\n const prevAnimationNameRef = React2.useRef(\"none\");\n const initialState = present ? \"mounted\" : \"unmounted\";\n const [state, send] = useStateMachine(initialState, {\n mounted: {\n UNMOUNT: \"unmounted\",\n ANIMATION_OUT: \"unmountSuspended\"\n },\n unmountSuspended: {\n MOUNT: \"mounted\",\n ANIMATION_END: \"unmounted\"\n },\n unmounted: {\n MOUNT: \"mounted\"\n }\n });\n React2.useEffect(() => {\n const currentAnimationName = getAnimationName(stylesRef.current);\n prevAnimationNameRef.current = state === \"mounted\" ? currentAnimationName : \"none\";\n }, [state]);\n useLayoutEffect(() => {\n const styles = stylesRef.current;\n const wasPresent = prevPresentRef.current;\n const hasPresentChanged = wasPresent !== present;\n if (hasPresentChanged) {\n const prevAnimationName = prevAnimationNameRef.current;\n const currentAnimationName = getAnimationName(styles);\n if (present) {\n send(\"MOUNT\");\n } else if (currentAnimationName === \"none\" || styles?.display === \"none\") {\n send(\"UNMOUNT\");\n } else {\n const isAnimating = prevAnimationName !== currentAnimationName;\n if (wasPresent && isAnimating) {\n send(\"ANIMATION_OUT\");\n } else {\n send(\"UNMOUNT\");\n }\n }\n prevPresentRef.current = present;\n }\n }, [present, send]);\n useLayoutEffect(() => {\n if (node) {\n let timeoutId;\n const ownerWindow = node.ownerDocument.defaultView ?? window;\n const handleAnimationEnd = (event) => {\n const currentAnimationName = getAnimationName(stylesRef.current);\n const isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName));\n if (event.target === node && isCurrentAnimation) {\n send(\"ANIMATION_END\");\n if (!prevPresentRef.current) {\n const currentFillMode = node.style.animationFillMode;\n node.style.animationFillMode = \"forwards\";\n timeoutId = ownerWindow.setTimeout(() => {\n if (node.style.animationFillMode === \"forwards\") {\n node.style.animationFillMode = currentFillMode;\n }\n });\n }\n }\n };\n const handleAnimationStart = (event) => {\n if (event.target === node) {\n prevAnimationNameRef.current = getAnimationName(stylesRef.current);\n }\n };\n node.addEventListener(\"animationstart\", handleAnimationStart);\n node.addEventListener(\"animationcancel\", handleAnimationEnd);\n node.addEventListener(\"animationend\", handleAnimationEnd);\n return () => {\n ownerWindow.clearTimeout(timeoutId);\n node.removeEventListener(\"animationstart\", handleAnimationStart);\n node.removeEventListener(\"animationcancel\", handleAnimationEnd);\n node.removeEventListener(\"animationend\", handleAnimationEnd);\n };\n } else {\n send(\"ANIMATION_END\");\n }\n }, [node, send]);\n return {\n isPresent: [\"mounted\", \"unmountSuspended\"].includes(state),\n ref: React2.useCallback((node2) => {\n stylesRef.current = node2 ? getComputedStyle(node2) : null;\n setNode(node2);\n }, [])\n };\n}\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\nfunction useStableComposedRefs(...refs) {\n const refsRef = React2.useRef(refs);\n refsRef.current = refs;\n return React2.useCallback((node) => {\n const currentRefs = refsRef.current;\n let hasCleanup = false;\n const cleanups = currentRefs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(currentRefs[i], null);\n }\n }\n };\n }\n }, []);\n}\nfunction getAnimationName(styles) {\n return styles?.animationName || \"none\";\n}\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\nvar Root = Presence;\nexport {\n Presence,\n Root\n};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\n\n// src/focus-guards.tsx\nimport * as React from \"react\";\nvar count = 0;\nvar guards = null;\nfunction FocusGuards(props) {\n useFocusGuards();\n return props.children;\n}\nfunction useFocusGuards() {\n React.useEffect(() => {\n if (!guards) {\n guards = { start: createFocusGuard(), end: createFocusGuard() };\n }\n const { start, end } = guards;\n if (document.body.firstElementChild !== start) {\n document.body.insertAdjacentElement(\"afterbegin\", start);\n }\n if (document.body.lastElementChild !== end) {\n document.body.insertAdjacentElement(\"beforeend\", end);\n }\n count++;\n return () => {\n if (count === 1) {\n guards?.start.remove();\n guards?.end.remove();\n guards = null;\n }\n count = Math.max(0, count - 1);\n };\n }, []);\n}\nfunction createFocusGuard() {\n const element = document.createElement(\"span\");\n element.setAttribute(\"data-radix-focus-guard\", \"\");\n element.tabIndex = 0;\n element.style.outline = \"none\";\n element.style.opacity = \"0\";\n element.style.position = \"fixed\";\n element.style.pointerEvents = \"none\";\n return element;\n}\nexport {\n FocusGuards,\n FocusGuards as Root,\n useFocusGuards\n};\n//# sourceMappingURL=index.mjs.map\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","export var zeroRightClassName = 'right-scroll-bar-position';\nexport var fullWidthClassName = 'width-before-scroll-bar';\nexport var noScrollbarsClassName = 'with-scroll-bars-hidden';\n/**\n * Name of a CSS variable containing the amount of \"hidden\" scrollbar\n * ! might be undefined ! use will fallback!\n */\nexport var removedBarSizeVariable = '--removed-body-scroll-bar-size';\n","/**\n * Assigns a value for a given ref, no matter of the ref format\n * @param {RefObject} ref - a callback function or ref object\n * @param value - a new value\n *\n * @see https://github.com/theKashey/use-callback-ref#assignref\n * @example\n * const refObject = useRef();\n * const refFn = (ref) => {....}\n *\n * assignRef(refObject, \"refValue\");\n * assignRef(refFn, \"refValue\");\n */\nexport function assignRef(ref, value) {\n if (typeof ref === 'function') {\n ref(value);\n }\n else if (ref) {\n ref.current = value;\n }\n return ref;\n}\n","import { useState } from 'react';\n/**\n * creates a MutableRef with ref change callback\n * @param initialValue - initial ref value\n * @param {Function} callback - a callback to run when value changes\n *\n * @example\n * const ref = useCallbackRef(0, (newValue, oldValue) => console.log(oldValue, '->', newValue);\n * ref.current = 1;\n * // prints 0 -> 1\n *\n * @see https://reactjs.org/docs/hooks-reference.html#useref\n * @see https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref\n * @returns {MutableRefObject}\n */\nexport function useCallbackRef(initialValue, callback) {\n var ref = useState(function () { return ({\n // value\n value: initialValue,\n // last callback\n callback: callback,\n // \"memoized\" public interface\n facade: {\n get current() {\n return ref.value;\n },\n set current(value) {\n var last = ref.value;\n if (last !== value) {\n ref.value = value;\n ref.callback(value, last);\n }\n },\n },\n }); })[0];\n // update callback\n ref.callback = callback;\n return ref.facade;\n}\n","import * as React from 'react';\nimport { assignRef } from './assignRef';\nimport { useCallbackRef } from './useRef';\nvar useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\nvar currentValues = new WeakMap();\n/**\n * Merges two or more refs together providing a single interface to set their value\n * @param {RefObject|Ref} refs\n * @returns {MutableRefObject} - a new ref, which translates all changes to {refs}\n *\n * @see {@link mergeRefs} a version without buit-in memoization\n * @see https://github.com/theKashey/use-callback-ref#usemergerefs\n * @example\n * const Component = React.forwardRef((props, ref) => {\n * const ownRef = useRef();\n * const domRef = useMergeRefs([ref, ownRef]); // 👈 merge together\n * return <div ref={domRef}>...</div>\n * }\n */\nexport function useMergeRefs(refs, defaultValue) {\n var callbackRef = useCallbackRef(defaultValue || null, function (newValue) {\n return refs.forEach(function (ref) { return assignRef(ref, newValue); });\n });\n // handle refs changes - added or removed\n useIsomorphicLayoutEffect(function () {\n var oldValue = currentValues.get(callbackRef);\n if (oldValue) {\n var prevRefs_1 = new Set(oldValue);\n var nextRefs_1 = new Set(refs);\n var current_1 = callbackRef.current;\n prevRefs_1.forEach(function (ref) {\n if (!nextRefs_1.has(ref)) {\n assignRef(ref, null);\n }\n });\n nextRefs_1.forEach(function (ref) {\n if (!prevRefs_1.has(ref)) {\n assignRef(ref, current_1);\n }\n });\n }\n currentValues.set(callbackRef, refs);\n }, [refs]);\n return callbackRef;\n}\n","import { __assign } from \"tslib\";\nfunction ItoI(a) {\n return a;\n}\nfunction innerCreateMedium(defaults, middleware) {\n if (middleware === void 0) { middleware = ItoI; }\n var buffer = [];\n var assigned = false;\n var medium = {\n read: function () {\n if (assigned) {\n throw new Error('Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.');\n }\n if (buffer.length) {\n return buffer[buffer.length - 1];\n }\n return defaults;\n },\n useMedium: function (data) {\n var item = middleware(data, assigned);\n buffer.push(item);\n return function () {\n buffer = buffer.filter(function (x) { return x !== item; });\n };\n },\n assignSyncMedium: function (cb) {\n assigned = true;\n while (buffer.length) {\n var cbs = buffer;\n buffer = [];\n cbs.forEach(cb);\n }\n buffer = {\n push: function (x) { return cb(x); },\n filter: function () { return buffer; },\n };\n },\n assignMedium: function (cb) {\n assigned = true;\n var pendingQueue = [];\n if (buffer.length) {\n var cbs = buffer;\n buffer = [];\n cbs.forEach(cb);\n pendingQueue = buffer;\n }\n var executeQueue = function () {\n var cbs = pendingQueue;\n pendingQueue = [];\n cbs.forEach(cb);\n };\n var cycle = function () { return Promise.resolve().then(executeQueue); };\n cycle();\n buffer = {\n push: function (x) {\n pendingQueue.push(x);\n cycle();\n },\n filter: function (filter) {\n pendingQueue = pendingQueue.filter(filter);\n return buffer;\n },\n };\n },\n };\n return medium;\n}\nexport function createMedium(defaults, middleware) {\n if (middleware === void 0) { middleware = ItoI; }\n return innerCreateMedium(defaults, middleware);\n}\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function createSidecarMedium(options) {\n if (options === void 0) { options = {}; }\n var medium = innerCreateMedium(null);\n medium.options = __assign({ async: true, ssr: false }, options);\n return medium;\n}\n","import { __assign, __rest } from \"tslib\";\nimport * as React from 'react';\nvar SideCar = function (_a) {\n var sideCar = _a.sideCar, rest = __rest(_a, [\"sideCar\"]);\n if (!sideCar) {\n throw new Error('Sidecar: please provide `sideCar` property to import the right car');\n }\n var Target = sideCar.read();\n if (!Target) {\n throw new Error('Sidecar medium not found');\n }\n return React.createElement(Target, __assign({}, rest));\n};\nSideCar.isSideCarExport = true;\nexport function exportSidecar(medium, exported) {\n medium.useMedium(exported);\n return SideCar;\n}\n","import { createSidecarMedium } from 'use-sidecar';\nexport var effectCar = createSidecarMedium();\n","import { __assign, __rest } from \"tslib\";\nimport * as React from 'react';\nimport { fullWidthClassName, zeroRightClassName } from 'react-remove-scroll-bar/constants';\nimport { useMergeRefs } from 'use-callback-ref';\nimport { effectCar } from './medium';\nvar nothing = function () {\n return;\n};\n/**\n * Removes scrollbar from the page and contain the scroll within the Lock\n */\nvar RemoveScroll = React.forwardRef(function (props, parentRef) {\n var ref = React.useRef(null);\n var _a = React.useState({\n onScrollCapture: nothing,\n onWheelCapture: nothing,\n onTouchMoveCapture: nothing,\n }), callbacks = _a[0], setCallbacks = _a[1];\n var forwardProps = props.forwardProps, children = props.children, className = props.className, removeScrollBar = props.removeScrollBar, enabled = props.enabled, shards = props.shards, sideCar = props.sideCar, noRelative = props.noRelative, noIsolation = props.noIsolation, inert = props.inert, allowPinchZoom = props.allowPinchZoom, _b = props.as, Container = _b === void 0 ? 'div' : _b, gapMode = props.gapMode, rest = __rest(props, [\"forwardProps\", \"children\", \"className\", \"removeScrollBar\", \"enabled\", \"shards\", \"sideCar\", \"noRelative\", \"noIsolation\", \"inert\", \"allowPinchZoom\", \"as\", \"gapMode\"]);\n var SideCar = sideCar;\n var containerRef = useMergeRefs([ref, parentRef]);\n var containerProps = __assign(__assign({}, rest), callbacks);\n return (React.createElement(React.Fragment, null,\n enabled && (React.createElement(SideCar, { sideCar: effectCar, removeScrollBar: removeScrollBar, shards: shards, noRelative: noRelative, noIsolation: noIsolation, inert: inert, setCallbacks: setCallbacks, allowPinchZoom: !!allowPinchZoom, lockRef: ref, gapMode: gapMode })),\n forwardProps ? (React.cloneElement(React.Children.only(children), __assign(__assign({}, containerProps), { ref: containerRef }))) : (React.createElement(Container, __assign({}, containerProps, { className: className, ref: containerRef }), children))));\n});\nRemoveScroll.defaultProps = {\n enabled: true,\n removeScrollBar: true,\n inert: false,\n};\nRemoveScroll.classNames = {\n fullWidth: fullWidthClassName,\n zeroRight: zeroRightClassName,\n};\nexport { RemoveScroll };\n","var currentNonce;\nexport var setNonce = function (nonce) {\n currentNonce = nonce;\n};\nexport var getNonce = function () {\n if (currentNonce) {\n return currentNonce;\n }\n if (typeof __webpack_nonce__ !== 'undefined') {\n return __webpack_nonce__;\n }\n return undefined;\n};\n","import { getNonce } from 'get-nonce';\nfunction makeStyleTag() {\n if (!document)\n return null;\n var tag = document.createElement('style');\n tag.type = 'text/css';\n var nonce = getNonce();\n if (nonce) {\n tag.setAttribute('nonce', nonce);\n }\n return tag;\n}\nfunction injectStyles(tag, css) {\n // @ts-ignore\n if (tag.styleSheet) {\n // @ts-ignore\n tag.styleSheet.cssText = css;\n }\n else {\n tag.appendChild(document.createTextNode(css));\n }\n}\nfunction insertStyleTag(tag) {\n var head = document.head || document.getElementsByTagName('head')[0];\n head.appendChild(tag);\n}\nexport var stylesheetSingleton = function () {\n var counter = 0;\n var stylesheet = null;\n return {\n add: function (style) {\n if (counter == 0) {\n if ((stylesheet = makeStyleTag())) {\n injectStyles(stylesheet, style);\n insertStyleTag(stylesheet);\n }\n }\n counter++;\n },\n remove: function () {\n counter--;\n if (!counter && stylesheet) {\n stylesheet.parentNode && stylesheet.parentNode.removeChild(stylesheet);\n stylesheet = null;\n }\n },\n };\n};\n","import * as React from 'react';\nimport { stylesheetSingleton } from './singleton';\n/**\n * creates a hook to control style singleton\n * @see {@link styleSingleton} for a safer component version\n * @example\n * ```tsx\n * const useStyle = styleHookSingleton();\n * ///\n * useStyle('body { overflow: hidden}');\n */\nexport var styleHookSingleton = function () {\n var sheet = stylesheetSingleton();\n return function (styles, isDynamic) {\n React.useEffect(function () {\n sheet.add(styles);\n return function () {\n sheet.remove();\n };\n }, [styles && isDynamic]);\n };\n};\n","import { styleHookSingleton } from './hook';\n/**\n * create a Component to add styles on demand\n * - styles are added when first instance is mounted\n * - styles are removed when the last instance is unmounted\n * - changing styles in runtime does nothing unless dynamic is set. But with multiple components that can lead to the undefined behavior\n */\nexport var styleSingleton = function () {\n var useStyle = styleHookSingleton();\n var Sheet = function (_a) {\n var styles = _a.styles, dynamic = _a.dynamic;\n useStyle(styles, dynamic);\n return null;\n };\n return Sheet;\n};\n","export var zeroGap = {\n left: 0,\n top: 0,\n right: 0,\n gap: 0,\n};\nvar parse = function (x) { return parseInt(x || '', 10) || 0; };\nvar getOffset = function (gapMode) {\n var cs = window.getComputedStyle(document.body);\n var left = cs[gapMode === 'padding' ? 'paddingLeft' : 'marginLeft'];\n var top = cs[gapMode === 'padding' ? 'paddingTop' : 'marginTop'];\n var right = cs[gapMode === 'padding' ? 'paddingRight' : 'marginRight'];\n return [parse(left), parse(top), parse(right)];\n};\nexport var getGapWidth = function (gapMode) {\n if (gapMode === void 0) { gapMode = 'margin'; }\n if (typeof window === 'undefined') {\n return zeroGap;\n }\n var offsets = getOffset(gapMode);\n var documentWidth = document.documentElement.clientWidth;\n var windowWidth = window.innerWidth;\n return {\n left: offsets[0],\n top: offsets[1],\n right: offsets[2],\n gap: Math.max(0, windowWidth - documentWidth + offsets[2] - offsets[0]),\n };\n};\n","import * as React from 'react';\nimport { styleSingleton } from 'react-style-singleton';\nimport { fullWidthClassName, zeroRightClassName, noScrollbarsClassName, removedBarSizeVariable } from './constants';\nimport { getGapWidth } from './utils';\nvar Style = styleSingleton();\nexport var lockAttribute = 'data-scroll-locked';\n// important tip - once we measure scrollBar width and remove them\n// we could not repeat this operation\n// thus we are using style-singleton - only the first \"yet correct\" style will be applied.\nvar getStyles = function (_a, allowRelative, gapMode, important) {\n var left = _a.left, top = _a.top, right = _a.right, gap = _a.gap;\n if (gapMode === void 0) { gapMode = 'margin'; }\n return \"\\n .\".concat(noScrollbarsClassName, \" {\\n overflow: hidden \").concat(important, \";\\n padding-right: \").concat(gap, \"px \").concat(important, \";\\n }\\n body[\").concat(lockAttribute, \"] {\\n overflow: hidden \").concat(important, \";\\n overscroll-behavior: contain;\\n \").concat([\n allowRelative && \"position: relative \".concat(important, \";\"),\n gapMode === 'margin' &&\n \"\\n padding-left: \".concat(left, \"px;\\n padding-top: \").concat(top, \"px;\\n padding-right: \").concat(right, \"px;\\n margin-left:0;\\n margin-top:0;\\n margin-right: \").concat(gap, \"px \").concat(important, \";\\n \"),\n gapMode === 'padding' && \"padding-right: \".concat(gap, \"px \").concat(important, \";\"),\n ]\n .filter(Boolean)\n .join(''), \"\\n }\\n \\n .\").concat(zeroRightClassName, \" {\\n right: \").concat(gap, \"px \").concat(important, \";\\n }\\n \\n .\").concat(fullWidthClassName, \" {\\n margin-right: \").concat(gap, \"px \").concat(important, \";\\n }\\n \\n .\").concat(zeroRightClassName, \" .\").concat(zeroRightClassName, \" {\\n right: 0 \").concat(important, \";\\n }\\n \\n .\").concat(fullWidthClassName, \" .\").concat(fullWidthClassName, \" {\\n margin-right: 0 \").concat(important, \";\\n }\\n \\n body[\").concat(lockAttribute, \"] {\\n \").concat(removedBarSizeVariable, \": \").concat(gap, \"px;\\n }\\n\");\n};\nvar getCurrentUseCounter = function () {\n var counter = parseInt(document.body.getAttribute(lockAttribute) || '0', 10);\n return isFinite(counter) ? counter : 0;\n};\nexport var useLockAttribute = function () {\n React.useEffect(function () {\n document.body.setAttribute(lockAttribute, (getCurrentUseCounter() + 1).toString());\n return function () {\n var newCounter = getCurrentUseCounter() - 1;\n if (newCounter <= 0) {\n document.body.removeAttribute(lockAttribute);\n }\n else {\n document.body.setAttribute(lockAttribute, newCounter.toString());\n }\n };\n }, []);\n};\n/**\n * Removes page scrollbar and blocks page scroll when mounted\n */\nexport var RemoveScrollBar = function (_a) {\n var noRelative = _a.noRelative, noImportant = _a.noImportant, _b = _a.gapMode, gapMode = _b === void 0 ? 'margin' : _b;\n useLockAttribute();\n /*\n gap will be measured on every component mount\n however it will be used only by the \"first\" invocation\n due to singleton nature of <Style\n */\n var gap = React.useMemo(function () { return getGapWidth(gapMode); }, [gapMode]);\n return React.createElement(Style, { styles: getStyles(gap, !noRelative, gapMode, !noImportant ? '!important' : '') });\n};\n","var passiveSupported = false;\nif (typeof window !== 'undefined') {\n try {\n var options = Object.defineProperty({}, 'passive', {\n get: function () {\n passiveSupported = true;\n return true;\n },\n });\n // @ts-ignore\n window.addEventListener('test', options, options);\n // @ts-ignore\n window.removeEventListener('test', options, options);\n }\n catch (err) {\n passiveSupported = false;\n }\n}\nexport var nonPassive = passiveSupported ? { passive: false } : false;\n","var alwaysContainsScroll = function (node) {\n // textarea will always _contain_ scroll inside self. It only can be hidden\n return node.tagName === 'TEXTAREA';\n};\nvar elementCanBeScrolled = function (node, overflow) {\n if (!(node instanceof Element)) {\n return false;\n }\n var styles = window.getComputedStyle(node);\n return (\n // not-not-scrollable\n styles[overflow] !== 'hidden' &&\n // contains scroll inside self\n !(styles.overflowY === styles.overflowX && !alwaysContainsScroll(node) && styles[overflow] === 'visible'));\n};\nvar elementCouldBeVScrolled = function (node) { return elementCanBeScrolled(node, 'overflowY'); };\nvar elementCouldBeHScrolled = function (node) { return elementCanBeScrolled(node, 'overflowX'); };\nexport var locationCouldBeScrolled = function (axis, node) {\n var ownerDocument = node.ownerDocument;\n var current = node;\n do {\n // Skip over shadow root\n if (typeof ShadowRoot !== 'undefined' && current instanceof ShadowRoot) {\n current = current.host;\n }\n var isScrollable = elementCouldBeScrolled(axis, current);\n if (isScrollable) {\n var _a = getScrollVariables(axis, current), scrollHeight = _a[1], clientHeight = _a[2];\n if (scrollHeight > clientHeight) {\n return true;\n }\n }\n current = current.parentNode;\n } while (current && current !== ownerDocument.body);\n return false;\n};\nvar getVScrollVariables = function (_a) {\n var scrollTop = _a.scrollTop, scrollHeight = _a.scrollHeight, clientHeight = _a.clientHeight;\n return [\n scrollTop,\n scrollHeight,\n clientHeight,\n ];\n};\nvar getHScrollVariables = function (_a) {\n var scrollLeft = _a.scrollLeft, scrollWidth = _a.scrollWidth, clientWidth = _a.clientWidth;\n return [\n scrollLeft,\n scrollWidth,\n clientWidth,\n ];\n};\nvar elementCouldBeScrolled = function (axis, node) {\n return axis === 'v' ? elementCouldBeVScrolled(node) : elementCouldBeHScrolled(node);\n};\nvar getScrollVariables = function (axis, node) {\n return axis === 'v' ? getVScrollVariables(node) : getHScrollVariables(node);\n};\nvar getDirectionFactor = function (axis, direction) {\n /**\n * If the element's direction is rtl (right-to-left), then scrollLeft is 0 when the scrollbar is at its rightmost position,\n * and then increasingly negative as you scroll towards the end of the content.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft\n */\n return axis === 'h' && direction === 'rtl' ? -1 : 1;\n};\nexport var handleScroll = function (axis, endTarget, event, sourceDelta, noOverscroll) {\n var directionFactor = getDirectionFactor(axis, window.getComputedStyle(endTarget).direction);\n var delta = directionFactor * sourceDelta;\n // find scrollable target\n var target = event.target;\n var targetInLock = endTarget.contains(target);\n var shouldCancelScroll = false;\n var isDeltaPositive = delta > 0;\n var availableScroll = 0;\n var availableScrollTop = 0;\n do {\n if (!target) {\n break;\n }\n var _a = getScrollVariables(axis, target), position = _a[0], scroll_1 = _a[1], capacity = _a[2];\n var elementScroll = scroll_1 - capacity - directionFactor * position;\n if (position || elementScroll) {\n if (elementCouldBeScrolled(axis, target)) {\n availableScroll += elementScroll;\n availableScrollTop += position;\n }\n }\n var parent_1 = target.parentNode;\n // we will \"bubble\" from ShadowDom in case we are, or just to the parent in normal case\n // this is the same logic used in focus-lock\n target = (parent_1 && parent_1.nodeType === Node.DOCUMENT_FRAGMENT_NODE ? parent_1.host : parent_1);\n } while (\n // portaled content\n (!targetInLock && target !== document.body) ||\n // self content\n (targetInLock && (endTarget.contains(target) || endTarget === target)));\n // handle epsilon around 0 (non standard zoom levels)\n if (isDeltaPositive &&\n ((noOverscroll && Math.abs(availableScroll) < 1) || (!noOverscroll && delta > availableScroll))) {\n shouldCancelScroll = true;\n }\n else if (!isDeltaPositive &&\n ((noOverscroll && Math.abs(availableScrollTop) < 1) || (!noOverscroll && -delta > availableScrollTop))) {\n shouldCancelScroll = true;\n }\n return shouldCancelScroll;\n};\n","import { __spreadArray } from \"tslib\";\nimport * as React from 'react';\nimport { RemoveScrollBar } from 'react-remove-scroll-bar';\nimport { styleSingleton } from 'react-style-singleton';\nimport { nonPassive } from './aggresiveCapture';\nimport { handleScroll, locationCouldBeScrolled } from './handleScroll';\nexport var getTouchXY = function (event) {\n return 'changedTouches' in event ? [event.changedTouches[0].clientX, event.changedTouches[0].clientY] : [0, 0];\n};\nexport var getDeltaXY = function (event) { return [event.deltaX, event.deltaY]; };\nvar extractRef = function (ref) {\n return ref && 'current' in ref ? ref.current : ref;\n};\nvar deltaCompare = function (x, y) { return x[0] === y[0] && x[1] === y[1]; };\nvar generateStyle = function (id) { return \"\\n .block-interactivity-\".concat(id, \" {pointer-events: none;}\\n .allow-interactivity-\").concat(id, \" {pointer-events: all;}\\n\"); };\nvar idCounter = 0;\nvar lockStack = [];\nexport function RemoveScrollSideCar(props) {\n var shouldPreventQueue = React.useRef([]);\n var touchStartRef = React.useRef([0, 0]);\n var activeAxis = React.useRef();\n var id = React.useState(idCounter++)[0];\n var Style = React.useState(styleSingleton)[0];\n var lastProps = React.useRef(props);\n React.useEffect(function () {\n lastProps.current = props;\n }, [props]);\n React.useEffect(function () {\n if (props.inert) {\n document.body.classList.add(\"block-interactivity-\".concat(id));\n var allow_1 = __spreadArray([props.lockRef.current], (props.shards || []).map(extractRef), true).filter(Boolean);\n allow_1.forEach(function (el) { return el.classList.add(\"allow-interactivity-\".concat(id)); });\n return function () {\n document.body.classList.remove(\"block-interactivity-\".concat(id));\n allow_1.forEach(function (el) { return el.classList.remove(\"allow-interactivity-\".concat(id)); });\n };\n }\n return;\n }, [props.inert, props.lockRef.current, props.shards]);\n var shouldCancelEvent = React.useCallback(function (event, parent) {\n if (('touches' in event && event.touches.length === 2) || (event.type === 'wheel' && event.ctrlKey)) {\n return !lastProps.current.allowPinchZoom;\n }\n var touch = getTouchXY(event);\n var touchStart = touchStartRef.current;\n var deltaX = 'deltaX' in event ? event.deltaX : touchStart[0] - touch[0];\n var deltaY = 'deltaY' in event ? event.deltaY : touchStart[1] - touch[1];\n var currentAxis;\n var target = event.target;\n var moveDirection = Math.abs(deltaX) > Math.abs(deltaY) ? 'h' : 'v';\n // allow horizontal touch move on Range inputs. They will not cause any scroll\n if ('touches' in event && moveDirection === 'h' && target.type === 'range') {\n return false;\n }\n // allow drag selection (iOS); check if selection's anchorNode is the same as target or contains target\n var selection = window.getSelection();\n var anchorNode = selection && selection.anchorNode;\n var isTouchingSelection = anchorNode ? anchorNode === target || anchorNode.contains(target) : false;\n if (isTouchingSelection) {\n return false;\n }\n var canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);\n if (!canBeScrolledInMainDirection) {\n return true;\n }\n if (canBeScrolledInMainDirection) {\n currentAxis = moveDirection;\n }\n else {\n currentAxis = moveDirection === 'v' ? 'h' : 'v';\n canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);\n // other axis might be not scrollable\n }\n if (!canBeScrolledInMainDirection) {\n return false;\n }\n if (!activeAxis.current && 'changedTouches' in event && (deltaX || deltaY)) {\n activeAxis.current = currentAxis;\n }\n if (!currentAxis) {\n return true;\n }\n var cancelingAxis = activeAxis.current || currentAxis;\n return handleScroll(cancelingAxis, parent, event, cancelingAxis === 'h' ? deltaX : deltaY, true);\n }, []);\n var shouldPrevent = React.useCallback(function (_event) {\n var event = _event;\n if (!lockStack.length || lockStack[lockStack.length - 1] !== Style) {\n // not the last active\n return;\n }\n var delta = 'deltaY' in event ? getDeltaXY(event) : getTouchXY(event);\n var sourceEvent = shouldPreventQueue.current.filter(function (e) { return e.name === event.type && (e.target === event.target || event.target === e.shadowParent) && deltaCompare(e.delta, delta); })[0];\n // self event, and should be canceled\n if (sourceEvent && sourceEvent.should) {\n if (event.cancelable) {\n event.preventDefault();\n }\n return;\n }\n // outside or shard event\n if (!sourceEvent) {\n var shardNodes = (lastProps.current.shards || [])\n .map(extractRef)\n .filter(Boolean)\n .filter(function (node) { return node.contains(event.target); });\n var shouldStop = shardNodes.length > 0 ? shouldCancelEvent(event, shardNodes[0]) : !lastProps.current.noIsolation;\n if (shouldStop) {\n if (event.cancelable) {\n event.preventDefault();\n }\n }\n }\n }, []);\n var shouldCancel = React.useCallback(function (name, delta, target, should) {\n var event = { name: name, delta: delta, target: target, should: should, shadowParent: getOutermostShadowParent(target) };\n shouldPreventQueue.current.push(event);\n setTimeout(function () {\n shouldPreventQueue.current = shouldPreventQueue.current.filter(function (e) { return e !== event; });\n }, 1);\n }, []);\n var scrollTouchStart = React.useCallback(function (event) {\n touchStartRef.current = getTouchXY(event);\n activeAxis.current = undefined;\n }, []);\n var scrollWheel = React.useCallback(function (event) {\n shouldCancel(event.type, getDeltaXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));\n }, []);\n var scrollTouchMove = React.useCallback(function (event) {\n shouldCancel(event.type, getTouchXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));\n }, []);\n React.useEffect(function () {\n lockStack.push(Style);\n props.setCallbacks({\n onScrollCapture: scrollWheel,\n onWheelCapture: scrollWheel,\n onTouchMoveCapture: scrollTouchMove,\n });\n document.addEventListener('wheel', shouldPrevent, nonPassive);\n document.addEventListener('touchmove', shouldPrevent, nonPassive);\n document.addEventListener('touchstart', scrollTouchStart, nonPassive);\n return function () {\n lockStack = lockStack.filter(function (inst) { return inst !== Style; });\n document.removeEventListener('wheel', shouldPrevent, nonPassive);\n document.removeEventListener('touchmove', shouldPrevent, nonPassive);\n document.removeEventListener('touchstart', scrollTouchStart, nonPassive);\n };\n }, []);\n var removeScrollBar = props.removeScrollBar, inert = props.inert;\n return (React.createElement(React.Fragment, null,\n inert ? React.createElement(Style, { styles: generateStyle(id) }) : null,\n removeScrollBar ? React.createElement(RemoveScrollBar, { noRelative: props.noRelative, gapMode: props.gapMode }) : null));\n}\nfunction getOutermostShadowParent(node) {\n var shadowParent = null;\n while (node !== null) {\n if (node instanceof ShadowRoot) {\n shadowParent = node.host;\n node = node.host;\n }\n node = node.parentNode;\n }\n return shadowParent;\n}\n","import { exportSidecar } from 'use-sidecar';\nimport { RemoveScrollSideCar } from './SideEffect';\nimport { effectCar } from './medium';\nexport default exportSidecar(effectCar, RemoveScrollSideCar);\n","import { __assign } from \"tslib\";\nimport * as React from 'react';\nimport { RemoveScroll } from './UI';\nimport SideCar from './sidecar';\nvar ReactRemoveScroll = React.forwardRef(function (props, ref) { return (React.createElement(RemoveScroll, __assign({}, props, { ref: ref, sideCar: SideCar }))); });\nReactRemoveScroll.classNames = RemoveScroll.classNames;\nexport default ReactRemoveScroll;\n","var getDefaultParent = function (originalTarget) {\n if (typeof document === 'undefined') {\n return null;\n }\n var sampleTarget = Array.isArray(originalTarget) ? originalTarget[0] : originalTarget;\n return sampleTarget.ownerDocument.body;\n};\nvar counterMap = new WeakMap();\nvar uncontrolledNodes = new WeakMap();\nvar markerMap = {};\nvar lockCount = 0;\nvar unwrapHost = function (node) {\n return node && (node.host || unwrapHost(node.parentNode));\n};\nvar correctTargets = function (parent, targets) {\n return targets\n .map(function (target) {\n if (parent.contains(target)) {\n return target;\n }\n var correctedTarget = unwrapHost(target);\n if (correctedTarget && parent.contains(correctedTarget)) {\n return correctedTarget;\n }\n console.error('aria-hidden', target, 'in not contained inside', parent, '. Doing nothing');\n return null;\n })\n .filter(function (x) { return Boolean(x); });\n};\n/**\n * Marks everything except given node(or nodes) as aria-hidden\n * @param {Element | Element[]} originalTarget - elements to keep on the page\n * @param [parentNode] - top element, defaults to document.body\n * @param {String} [markerName] - a special attribute to mark every node\n * @param {String} [controlAttribute] - html Attribute to control\n * @return {Undo} undo command\n */\nvar applyAttributeToOthers = function (originalTarget, parentNode, markerName, controlAttribute) {\n var targets = correctTargets(parentNode, Array.isArray(originalTarget) ? originalTarget : [originalTarget]);\n if (!markerMap[markerName]) {\n markerMap[markerName] = new WeakMap();\n }\n var markerCounter = markerMap[markerName];\n var hiddenNodes = [];\n var elementsToKeep = new Set();\n var elementsToStop = new Set(targets);\n var keep = function (el) {\n if (!el || elementsToKeep.has(el)) {\n return;\n }\n elementsToKeep.add(el);\n keep(el.parentNode);\n };\n targets.forEach(keep);\n var deep = function (parent) {\n if (!parent || elementsToStop.has(parent)) {\n return;\n }\n Array.prototype.forEach.call(parent.children, function (node) {\n if (elementsToKeep.has(node)) {\n deep(node);\n }\n else {\n try {\n var attr = node.getAttribute(controlAttribute);\n var alreadyHidden = attr !== null && attr !== 'false';\n var counterValue = (counterMap.get(node) || 0) + 1;\n var markerValue = (markerCounter.get(node) || 0) + 1;\n counterMap.set(node, counterValue);\n markerCounter.set(node, markerValue);\n hiddenNodes.push(node);\n if (counterValue === 1 && alreadyHidden) {\n uncontrolledNodes.set(node, true);\n }\n if (markerValue === 1) {\n node.setAttribute(markerName, 'true');\n }\n if (!alreadyHidden) {\n node.setAttribute(controlAttribute, 'true');\n }\n }\n catch (e) {\n console.error('aria-hidden: cannot operate on ', node, e);\n }\n }\n });\n };\n deep(parentNode);\n elementsToKeep.clear();\n lockCount++;\n return function () {\n hiddenNodes.forEach(function (node) {\n var counterValue = counterMap.get(node) - 1;\n var markerValue = markerCounter.get(node) - 1;\n counterMap.set(node, counterValue);\n markerCounter.set(node, markerValue);\n if (!counterValue) {\n if (!uncontrolledNodes.has(node)) {\n node.removeAttribute(controlAttribute);\n }\n uncontrolledNodes.delete(node);\n }\n if (!markerValue) {\n node.removeAttribute(markerName);\n }\n });\n lockCount--;\n if (!lockCount) {\n // clear\n counterMap = new WeakMap();\n counterMap = new WeakMap();\n uncontrolledNodes = new WeakMap();\n markerMap = {};\n }\n };\n};\n/**\n * Marks everything except given node(or nodes) as aria-hidden\n * @param {Element | Element[]} originalTarget - elements to keep on the page\n * @param [parentNode] - top element, defaults to document.body\n * @param {String} [markerName] - a special attribute to mark every node\n * @return {Undo} undo command\n */\nexport var hideOthers = function (originalTarget, parentNode, markerName) {\n if (markerName === void 0) { markerName = 'data-aria-hidden'; }\n var targets = Array.from(Array.isArray(originalTarget) ? originalTarget : [originalTarget]);\n var activeParentNode = parentNode || getDefaultParent(originalTarget);\n if (!activeParentNode) {\n return function () { return null; };\n }\n // we should not hide aria-live elements - https://github.com/theKashey/aria-hidden/issues/10\n // and script elements, as they have no impact on accessibility.\n targets.push.apply(targets, Array.from(activeParentNode.querySelectorAll('[aria-live], script')));\n return applyAttributeToOthers(targets, activeParentNode, markerName, 'aria-hidden');\n};\n/**\n * Marks everything except given node(or nodes) as inert\n * @param {Element | Element[]} originalTarget - elements to keep on the page\n * @param [parentNode] - top element, defaults to document.body\n * @param {String} [markerName] - a special attribute to mark every node\n * @return {Undo} undo command\n */\nexport var inertOthers = function (originalTarget, parentNode, markerName) {\n if (markerName === void 0) { markerName = 'data-inert-ed'; }\n var activeParentNode = parentNode || getDefaultParent(originalTarget);\n if (!activeParentNode) {\n return function () { return null; };\n }\n return applyAttributeToOthers(originalTarget, activeParentNode, markerName, 'inert');\n};\n/**\n * @returns if current browser supports inert\n */\nexport var supportsInert = function () {\n return typeof HTMLElement !== 'undefined' && HTMLElement.prototype.hasOwnProperty('inert');\n};\n/**\n * Automatic function to \"suppress\" DOM elements - _hide_ or _inert_ in the best possible way\n * @param {Element | Element[]} originalTarget - elements to keep on the page\n * @param [parentNode] - top element, defaults to document.body\n * @param {String} [markerName] - a special attribute to mark every node\n * @return {Undo} undo command\n */\nexport var suppressOthers = function (originalTarget, parentNode, markerName) {\n if (markerName === void 0) { markerName = 'data-suppressed'; }\n return (supportsInert() ? inertOthers : hideOthers)(originalTarget, parentNode, markerName);\n};\n","\"use client\";\n\n// src/dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContext, createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = (props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: DIALOG_NAME\n });\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n};\nDialog.displayName = DIALOG_NAME;\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.open ? context.contentId : void 0,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }\n);\nDialogTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = (props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n};\nDialogPortal.displayName = PORTAL_NAME;\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }\n);\nDialogOverlay.displayName = OVERLAY_NAME;\nvar Slot = createSlot(\"DialogOverlay.RemoveScroll\");\nvar DialogOverlayImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: forwardedRef,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nDialogContent.displayName = CONTENT_NAME;\nvar DialogContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: context.open,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }\n);\nvar DialogContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }\n);\nvar DialogContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, contentRef);\n useFocusGuards();\n return /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionId,\n \"aria-labelledby\": context.titleId,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: composedRefs,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ),\n /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(TitleWarning, { titleId: context.titleId }),\n /* @__PURE__ */ jsx(DescriptionWarning, { contentRef, descriptionId: context.descriptionId })\n ] })\n ] });\n }\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }\n);\nDialogTitle.displayName = TITLE_NAME;\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }\n);\nDialogDescription.displayName = DESCRIPTION_NAME;\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }\n);\nDialogClose.displayName = CLOSE_NAME;\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar TITLE_WARNING_NAME = \"DialogTitleWarning\";\nvar [WarningProvider, useWarningContext] = createContext(TITLE_WARNING_NAME, {\n contentName: CONTENT_NAME,\n titleName: TITLE_NAME,\n docsSlug: \"dialog\"\n});\nvar TitleWarning = ({ titleId }) => {\n const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);\n const MESSAGE = `\\`${titleWarningContext.contentName}\\` requires a \\`${titleWarningContext.titleName}\\` for the component to be accessible for screen reader users.\n\nIf you want to hide the \\`${titleWarningContext.titleName}\\`, you can wrap it with our VisuallyHidden component.\n\nFor more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`;\n React.useEffect(() => {\n if (titleId) {\n const hasTitle = document.getElementById(titleId);\n if (!hasTitle) console.error(MESSAGE);\n }\n }, [MESSAGE, titleId]);\n return null;\n};\nvar DESCRIPTION_WARNING_NAME = \"DialogDescriptionWarning\";\nvar DescriptionWarning = ({ contentRef, descriptionId }) => {\n const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);\n const MESSAGE = `Warning: Missing \\`Description\\` or \\`aria-describedby={undefined}\\` for {${descriptionWarningContext.contentName}}.`;\n React.useEffect(() => {\n const describedById = contentRef.current?.getAttribute(\"aria-describedby\");\n if (descriptionId && describedById) {\n const hasDescription = document.getElementById(descriptionId);\n if (!hasDescription) console.warn(MESSAGE);\n }\n }, [MESSAGE, contentRef, descriptionId]);\n return null;\n};\nvar Root = Dialog;\nvar Trigger = DialogTrigger;\nvar Portal = DialogPortal;\nvar Overlay = DialogOverlay;\nvar Content = DialogContent;\nvar Title = DialogTitle;\nvar Description = DialogDescription;\nvar Close = DialogClose;\nexport {\n Close,\n Content,\n Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n Overlay,\n Portal,\n Root,\n Title,\n Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as RadixDialog from '@radix-ui/react-dialog'\nimport type { ReactNode } from 'react'\nimport { Button } from '../Button/Button'\n\nexport type DialogAction = {\n label: string\n onClick: () => void\n variant?: 'primary' | 'ghost'\n}\n\nexport type DialogProps = {\n open: boolean\n title: string\n children?: ReactNode\n actions: DialogAction[]\n /** Called on Escape / overlay click; omit to force an action choice. */\n onClose?: () => void\n}\n\n/** Modal dialog on Radix (focus trap, aria handled). Replaces AntD Modal. */\nexport const Dialog = ({ open, title, children, actions, onClose }: DialogProps) => (\n <RadixDialog.Root open={open} onOpenChange={(next) => !next && onClose?.()}>\n <RadixDialog.Portal>\n <RadixDialog.Overlay className=\"sc:fixed sc:inset-0 sc:bg-black/40 sc:z-50\" />\n <RadixDialog.Content\n className=\"sapia-chatbot sc:fixed sc:left-1/2 sc:top-1/2 sc:-translate-x-1/2 sc:-translate-y-1/2 sc:z-50 sc:w-[90vw] sc:max-w-md sc:rounded-xl sc:bg-white sc:p-5 sc:shadow-lg\"\n onEscapeKeyDown={onClose ? undefined : (event) => event.preventDefault()}\n onPointerDownOutside={onClose ? undefined : (event) => event.preventDefault()}\n >\n <RadixDialog.Title className=\"sc:text-base sc:font-semibold sc:text-question-fg\">\n {title}\n </RadixDialog.Title>\n {children ? (\n <RadixDialog.Description asChild>\n <div className=\"sc:mt-2 sc:text-sm sc:text-question-fg\">{children}</div>\n </RadixDialog.Description>\n ) : null}\n <div className=\"sc:mt-4 sc:flex sc:justify-end sc:gap-2\">\n {actions.map((action) => (\n <Button key={action.label} variant={action.variant} onClick={action.onClick}>\n {action.label}\n </Button>\n ))}\n </div>\n </RadixDialog.Content>\n </RadixDialog.Portal>\n </RadixDialog.Root>\n)\n","import { useId, useState, type FormEvent } from 'react'\nimport { Button } from '../../primitives/Button/Button'\n\nexport type AccessVerificationLabels = {\n title: string\n description: string\n inputLabel: string\n placeholder: string\n submit: string\n mismatchError: string\n}\n\nexport type AccessVerificationFormProps = {\n /** Masked email hint, e.g. \"du*****@sapia.ai\". */\n emailHint?: string\n mismatch?: boolean\n submitting?: boolean\n labels: AccessVerificationLabels\n onSubmit: (email: string) => void\n}\n\n/**\n * Email gate shown before the interview when the assessment requires\n * verification (legacy AccessVerification). Pure presentational.\n */\nexport const AccessVerificationForm = ({\n emailHint,\n mismatch = false,\n submitting = false,\n labels,\n onSubmit,\n}: AccessVerificationFormProps) => {\n const [email, setEmail] = useState('')\n const errorId = useId()\n\n const handleSubmit = (event: FormEvent) => {\n event.preventDefault()\n if (email.trim().length > 0 && !submitting) onSubmit(email.trim())\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"sc:flex sc:flex-col sc:gap-3 sc:p-4\">\n <h2 className=\"sc:text-base sc:font-semibold sc:text-question-fg\">{labels.title}</h2>\n <p className=\"sc:text-sm sc:text-question-fg\">{labels.description}</p>\n {emailHint ? (\n <p className=\"sc:text-sm sc:font-medium sc:text-question-fg\">{emailHint}</p>\n ) : null}\n <input\n type=\"email\"\n inputMode=\"email\"\n value={email}\n onChange={(event) => setEmail(event.target.value)}\n disabled={submitting}\n aria-label={labels.inputLabel}\n aria-invalid={mismatch || undefined}\n aria-describedby={mismatch ? errorId : undefined}\n placeholder={labels.placeholder}\n className=\"sc:rounded-md sc:border sc:border-black/20 sc:px-3 sc:py-2 sc:text-sm sc:focus-visible:outline-2 sc:focus-visible:outline-offset-1 sc:disabled:opacity-50\"\n />\n {mismatch ? (\n <p id={errorId} role=\"alert\" className=\"sc:text-sm sc:text-red-600\">\n {labels.mismatchError}\n </p>\n ) : null}\n <Button type=\"submit\" disabled={submitting || email.trim().length === 0}>\n {labels.submit}\n </Button>\n </form>\n )\n}\n","export type DoneScreenLabels = {\n title: string\n subtitle: string\n nextLabel: string\n steps: [string, string, string]\n ratingPrompt: string\n}\n\nexport type DoneScreenProps = {\n labels: DoneScreenLabels\n}\n\nconst Step = ({ n, text }: { n: number; text: string }) => (\n <div className=\"sc:mt-3.5 sc:flex sc:items-start sc:gap-3.5 sc:first:mt-4\">\n <span\n aria-hidden=\"true\"\n className=\"sc:flex sc:size-7 sc:flex-shrink-0 sc:items-center sc:justify-center sc:rounded-full sc:bg-pink sc:text-sm sc:font-extrabold sc:text-question-fg\"\n >\n {n}\n </span>\n <span className=\"sc:text-sm/relaxed sc:text-[#37333d]\">{text}</span>\n </div>\n)\n\n/**\n * Completion screen shown when the interview has ended. The star rating is\n * decorative only (no submission) per the redesign scope decision.\n */\nexport const DoneScreen = ({ labels }: DoneScreenProps) => (\n <div className=\"sc:flex sc:flex-1 sc:items-center sc:justify-center sc:overflow-y-auto sc:bg-canvas sc:px-6 sc:py-10\">\n <div className=\"sc:flex sc:w-full sc:max-w-[480px] sc:flex-col sc:items-center sc:text-center\">\n <span\n aria-hidden=\"true\"\n className=\"sc:h-10 sc:w-[88px] sc:-rotate-3 sc:rounded-b-[100%] sc:border-b-[9px] sc:border-pink sc:[animation:sc-msg-in_.5s_ease_both]\"\n />\n <h1 className=\"sc:mt-6 sc:text-[36px]/[1.1] sc:font-extrabold sc:tracking-tight sc:text-question-fg\">\n {labels.title}\n </h1>\n <p className=\"sc:mt-3.5 sc:text-base/relaxed sc:text-[#37333d] sc:[text-wrap:pretty]\">\n {labels.subtitle}\n </p>\n\n <div className=\"sc:mt-7 sc:w-full sc:rounded-[24px] sc:border sc:border-line sc:bg-white sc:p-5 sc:text-left\">\n <span className=\"sc:text-xs sc:font-semibold sc:tracking-[0.18em] sc:text-muted sc:uppercase\">\n {labels.nextLabel}\n </span>\n {labels.steps.map((text, index) => (\n <Step key={index} n={index + 1} text={text} />\n ))}\n </div>\n\n <div className=\"sc:mt-4 sc:w-full sc:rounded-[24px] sc:bg-pink-tint sc:p-5\">\n <span className=\"sc:text-[15px] sc:font-bold sc:text-question-fg\">{labels.ratingPrompt}</span>\n <div className=\"sc:mt-2.5 sc:flex sc:justify-center sc:gap-1\" aria-hidden=\"true\">\n {[1, 2, 3, 4, 5].map((n) => (\n <span key={n} className=\"sc:text-[28px] sc:text-line\">\n ★\n </span>\n ))}\n </div>\n </div>\n </div>\n </div>\n)\n","export type HeaderProps = {\n title: string\n /** Muted second line, e.g. \"Sapia chat interview\". */\n subtitle?: string\n logoUrl?: string\n logoAlt?: string\n /** Progress pill text, e.g. \"Question 2 of 4\" or \"Getting started\". */\n progressLabel?: string\n}\n\n/**\n * Interview header: branding/title, a muted subtitle, and a progress pill.\n */\nexport const Header = ({\n title,\n subtitle,\n logoUrl,\n logoAlt,\n progressLabel,\n}: HeaderProps) => (\n <header className=\"sc:flex-shrink-0 sc:border-b sc:border-line sc:bg-header sc:text-header-fg\">\n <div className=\"sc:mx-auto sc:flex sc:w-full sc:max-w-[720px] sc:items-center sc:justify-between sc:gap-3 sc:px-4 sc:py-2.5\">\n <div className=\"sc:flex sc:min-w-0 sc:items-center sc:gap-3\">\n {logoUrl ? <img src={logoUrl} alt={logoAlt ?? ''} className=\"sc:h-7 sc:w-auto\" /> : null}\n <div className=\"sc:flex sc:min-w-0 sc:flex-col sc:gap-0.5\">\n <h1 className=\"sc:truncate sc:text-[15px] sc:font-bold sc:text-header-fg\">{title}</h1>\n {subtitle ? (\n <span className=\"sc:truncate sc:text-[13px] sc:text-muted\">{subtitle}</span>\n ) : null}\n </div>\n </div>\n {progressLabel ? (\n <span className=\"sc:flex-shrink-0 sc:rounded-full sc:bg-pink-tint sc:px-3.5 sc:py-1.5 sc:text-[13px] sc:font-bold sc:text-header-fg sc:tabular-nums\">\n {progressLabel}\n </span>\n ) : null}\n </div>\n </header>\n)\n","export type PreparingScreenProps = {\n /** Status text, e.g. \"Preparing your interview…\". */\n label: string\n}\n\nconst DOT = 'sc:size-2 sc:rounded-full sc:bg-pink-strong sc:[animation:sc-dot-blink_1.2s_infinite]'\n\n/**\n * Full-screen loading state shown while the interview is being fetched/started.\n * Re-skin of the previous loading paragraph; announced via role=\"status\".\n */\nexport const PreparingScreen = ({ label }: PreparingScreenProps) => (\n <div\n role=\"status\"\n className=\"sc:flex sc:flex-1 sc:flex-col sc:items-center sc:justify-center sc:gap-5 sc:bg-canvas sc:p-6\"\n >\n <span\n aria-hidden=\"true\"\n className=\"sc:h-[34px] sc:w-[76px] sc:-rotate-3 sc:rounded-b-[100%] sc:border-b-[8px] sc:border-pink\"\n />\n <span className=\"sc:text-lg sc:font-bold sc:text-question-fg\">{label}</span>\n <div className=\"sc:flex sc:gap-1.5\" aria-hidden=\"true\">\n <span className={DOT} />\n <span className={`${DOT} sc:[animation-delay:.15s]`} />\n <span className={`${DOT} sc:[animation-delay:.3s]`} />\n </div>\n </div>\n)\n","export type ProgressBarProps = {\n /** Answered question count. */\n value: number\n /** Total question count; bar hidden when 0. */\n max: number\n /** Accessible name, e.g. \"Interview progress\". */\n label: string\n}\n\nexport const ProgressBar = ({ value, max, label }: ProgressBarProps) => {\n if (max <= 0) return null\n const percent = Math.min(100, Math.round((value / max) * 100))\n return (\n <div\n role=\"progressbar\"\n aria-label={label}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuenow={Math.min(value, max)}\n className=\"sc:h-[3px] sc:w-full sc:bg-[#f1f1f1]\"\n >\n <div\n className=\"sc:h-full sc:rounded-r-[3px] sc:bg-pink-strong sc:transition-[width] sc:duration-500 sc:ease-out\"\n style={{ width: `${percent}%` }}\n />\n </div>\n )\n}\n","import { useRef, useState } from 'react'\n\nexport type CopyLinkButtonProps = {\n copyLabel: string\n copiedLabel: string\n /** Style overrides; the base only sets cursor/transition. */\n className?: string\n}\n\n/**\n * Copies the current page URL (the pause-and-resume link) and flashes a\n * confirmation. Purely client-side — no core/api involvement.\n */\nexport const CopyLinkButton = ({ copyLabel, copiedLabel, className = '' }: CopyLinkButtonProps) => {\n const [copied, setCopied] = useState(false)\n const timerRef = useRef<ReturnType<typeof setTimeout>>(undefined)\n\n const copy = () => {\n try {\n void navigator.clipboard?.writeText(window.location.href)\n } catch {\n // Clipboard unavailable (insecure context / denied) — fail silently.\n }\n setCopied(true)\n clearTimeout(timerRef.current)\n timerRef.current = setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button type=\"button\" onClick={copy} className={`sc:cursor-pointer sc:transition-colors ${className}`}>\n {copied ? copiedLabel : copyLabel}\n </button>\n )\n}\n","import { Button } from '../../primitives/Button/Button'\nimport { CopyLinkButton } from '../CopyLinkButton/CopyLinkButton'\n\nexport type WelcomeScreenLabels = {\n /** Eyebrow above the greeting, e.g. \"Chat interview\". */\n eyebrow: string\n greeting: string\n intro: string\n /** Copy-link affordance, e.g. \"Copy link · resume later\". */\n copyLinkResume: string\n copied: string\n next: string\n}\n\nexport type WelcomeScreenProps = {\n labels: WelcomeScreenLabels\n logoUrl?: string\n logoAlt?: string\n onNext: () => void\n}\n\n/**\n * Pre-interview welcome gate. Greets the candidate (name/role/company when the\n * API supplies them) and starts the interview on \"Begin\". A centred column with\n * a smile eyebrow — the library bundles no stock photography.\n */\nexport const WelcomeScreen = ({ labels, logoUrl, logoAlt, onNext }: WelcomeScreenProps) => (\n <div className=\"sc:flex sc:min-h-full sc:flex-1 sc:flex-col sc:items-center sc:justify-center sc:bg-canvas sc:px-6 sc:py-10\">\n <div className=\"sc:flex sc:w-full sc:max-w-[520px] sc:flex-col sc:items-center sc:text-center\">\n {logoUrl ? <img src={logoUrl} alt={logoAlt ?? ''} className=\"sc:h-7 sc:w-auto\" /> : null}\n <div className=\"sc:mt-7 sc:flex sc:items-center sc:gap-2.5\">\n <span\n aria-hidden=\"true\"\n className=\"sc:h-2.5 sc:w-7 sc:-rotate-3 sc:rounded-b-[100%] sc:border-b-[5px] sc:border-pink-strong\"\n />\n <span className=\"sc:text-[12px] sc:font-bold sc:tracking-[0.18em] sc:text-muted sc:uppercase\">\n {labels.eyebrow}\n </span>\n </div>\n <h1 className=\"sc:mt-4 sc:text-[38px]/[1.06] sc:font-extrabold sc:tracking-tight sc:text-question-fg\">\n {labels.greeting}\n </h1>\n <p className=\"sc:mt-4 sc:text-base/relaxed sc:text-[#37333d] sc:[text-wrap:pretty]\">\n {labels.intro}\n </p>\n <Button onClick={onNext} className=\"sc:mt-7 sc:h-14 sc:w-full sc:text-[17px]\">\n {labels.next}\n </Button>\n <CopyLinkButton\n copyLabel={labels.copyLinkResume}\n copiedLabel={labels.copied}\n className=\"sc:mt-3.5 sc:text-[13px] sc:font-bold sc:text-muted sc:hover:text-question-fg\"\n />\n </div>\n </div>\n)\n","// Layer C — UI-owned constants.\n\n/** Class scoping every style in dist/sapia-chatbot.css (see src/styles/index.css). */\nexport const WIDGET_ROOT_CLASS = 'sapia-chatbot'\n","import type { CSSProperties, ReactNode } from 'react'\nimport { WIDGET_ROOT_CLASS } from '../../constants'\n\nexport type WidgetRootProps = {\n children: ReactNode\n /** CSS custom properties (--sc-*) produced by core/theme. */\n themeVariables?: Record<string, string>\n dir?: 'ltr' | 'rtl'\n}\n\n/**\n * Root element of the widget. Carries the scoping class for all packaged\n * styles plus the theme CSS variables, so theming never re-renders children.\n */\nexport const WidgetRoot = ({ children, themeVariables, dir = 'ltr' }: WidgetRootProps) => (\n <div className={`${WIDGET_ROOT_CLASS} sc:flex sc:h-full sc:flex-col`} dir={dir} style={themeVariables as CSSProperties}>\n {children}\n </div>\n)\n","// Layer B — country list for the phone input, derived at runtime from\n// libphonenumber-js metadata + Intl.DisplayNames. Replaces the legacy\n// 1300-line PhoneCodeSelect/sources.ts data file (ADR-008).\n\nimport type { Region } from '../../api/config'\n\nexport type PhoneCountry = {\n /** ISO 3166-1 alpha-2, e.g. \"AU\". */\n code: string\n /** Calling code without \"+\", e.g. \"61\". */\n callingCode: string\n /** Localized display name, e.g. \"Australia\". */\n name: string\n /** Flag emoji derived from the country code. */\n flag: string\n}\n\n/** Legacy REGION_AREA_MAP: default phone country per backend region. */\nexport const DEFAULT_COUNTRY_BY_REGION: Record<Region, string> = {\n 'ap-southeast-2': 'AU',\n 'eu-west-1': 'GB',\n 'us-east-1': 'US',\n}\n\nexport const DEFAULT_PHONE_COUNTRY = 'AU'\n\nconst REGIONAL_INDICATOR_OFFSET = 0x1f1e6 - 'A'.charCodeAt(0)\n\nconst flagEmoji = (countryCode: string): string =>\n String.fromCodePoint(\n ...countryCode\n .toUpperCase()\n .split('')\n .map((char) => char.charCodeAt(0) + REGIONAL_INDICATOR_OFFSET),\n )\n\n/** Loads libphonenumber metadata on demand and builds the sorted country list. */\nexport const loadPhoneCountries = async (locale = 'en'): Promise<PhoneCountry[]> => {\n const { getCountries, getCountryCallingCode } = await import('libphonenumber-js/max')\n const displayNames = new Intl.DisplayNames([locale], { type: 'region' })\n return getCountries()\n .map((code) => ({\n code: code as string,\n callingCode: getCountryCallingCode(code) as string,\n name: displayNames.of(code) ?? code,\n flag: flagEmoji(code),\n }))\n .sort((a, b) => a.name.localeCompare(b.name))\n}\n\n/** Initial country: candidate's detected country, else the region default. */\nexport const resolveDefaultPhoneCountry = ({\n candidateCountryCode,\n region,\n}: {\n candidateCountryCode?: string\n region?: Region\n}): string =>\n candidateCountryCode?.toUpperCase() ??\n (region ? DEFAULT_COUNTRY_BY_REGION[region] : undefined) ??\n DEFAULT_PHONE_COUNTRY\n","import { useState } from 'react'\nimport { Button } from '../../primitives/Button/Button'\n\nexport type PhoneCountryOption = {\n code: string\n callingCode: string\n name: string\n flag: string\n}\n\nexport type PhoneAnswerInputProps = {\n countries: PhoneCountryOption[]\n defaultCountryCode: string\n disabled?: boolean\n countryLabel: string\n inputLabel: string\n placeholder: string\n sendLabel: string\n /** Receives the national number text and the selected ISO country code. */\n onSubmit: (text: string, countryCode: string) => void\n}\n\n/** Phone PII input: country picker + national number (replaces legacy PhoneEditor). */\nexport const PhoneAnswerInput = ({\n countries,\n defaultCountryCode,\n disabled = false,\n countryLabel,\n inputLabel,\n placeholder,\n sendLabel,\n onSubmit,\n}: PhoneAnswerInputProps) => {\n const [countryCode, setCountryCode] = useState(defaultCountryCode)\n const [text, setText] = useState('')\n\n const canSend = !disabled && text.trim().length > 0\n\n const handleSend = () => {\n if (!canSend) return\n onSubmit(text.trim(), countryCode)\n }\n\n return (\n <div className=\"sc:border-t sc:border-black/10 sc:p-3\">\n <div className=\"sc:flex sc:items-center sc:gap-2\">\n <select\n value={countryCode}\n onChange={(event) => setCountryCode(event.target.value)}\n disabled={disabled}\n aria-label={countryLabel}\n className=\"sc:max-w-36 sc:rounded-md sc:border sc:border-black/20 sc:px-2 sc:py-2 sc:text-sm sc:disabled:opacity-50\"\n >\n {countries.map((country) => (\n <option key={country.code} value={country.code}>\n {country.flag} {country.name} +{country.callingCode}\n </option>\n ))}\n </select>\n <input\n type=\"tel\"\n inputMode=\"tel\"\n value={text}\n onChange={(event) => setText(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n handleSend()\n }\n }}\n disabled={disabled}\n placeholder={placeholder}\n aria-label={inputLabel}\n className=\"sc:flex-1 sc:rounded-md sc:border sc:border-black/20 sc:px-3 sc:py-2 sc:text-sm sc:focus-visible:outline-2 sc:focus-visible:outline-offset-1 sc:disabled:opacity-50\"\n />\n <Button onClick={handleSend} disabled={!canSend} aria-label={sendLabel}>\n {sendLabel}\n </Button>\n </div>\n </div>\n )\n}\n","import {\n useId,\n useRef,\n useState,\n type ChangeEvent,\n type KeyboardEvent,\n type MouseEvent,\n} from 'react'\nimport { Button } from '../../primitives/Button/Button'\nimport { sanitizeRichText } from '../../richText'\n\nexport type RichToolbarLabels = {\n toolbar: string\n bold: string\n italic: string\n underline: string\n bulletList: string\n numberList: string\n}\n\nexport type TextAnswerInputProps = {\n /** Receives plain text and, in rich mode, the sanitized HTML rendering. */\n onSubmit: (text: string, html?: string) => void\n disabled?: boolean\n /** Character rules from the current question (legacy RuleName min/max/recommended). */\n minLength?: number\n maxLength?: number\n recommendedLength?: number\n placeholder: string\n sendLabel: string\n /** Hint shown while below minLength, e.g. \"Please write at least {min} characters\". */\n minLengthHint?: string\n /** Affirmation shown once the minimum is met, e.g. \"Looking good\". */\n okHint?: string\n /** Reassurance caption under the composer. */\n footer?: string\n inputLabel: string\n /** Enables the rich-text editor + formatting toolbar (plain-text FTQ only). */\n richText?: boolean\n toolbarLabels?: RichToolbarLabels\n /** Called when the candidate pastes (AGC paste logging). */\n onPaste?: () => void\n}\n\ntype Format = 'bold' | 'italic' | 'underline' | 'insertUnorderedList' | 'insertOrderedList'\n\n/** innerText in browsers; textContent fallback for jsdom (no innerText). */\nconst editorText = (el: HTMLElement | null): string => el?.innerText ?? el?.textContent ?? ''\n\nconst queryState = (command: Format): boolean => {\n try {\n return document.queryCommandState(command)\n } catch {\n return false\n }\n}\n\nexport const TextAnswerInput = ({\n onSubmit,\n disabled = false,\n minLength,\n maxLength,\n recommendedLength,\n placeholder,\n sendLabel,\n minLengthHint,\n okHint,\n footer,\n inputLabel,\n richText = false,\n toolbarLabels,\n onPaste,\n}: TextAnswerInputProps) => {\n const [text, setText] = useState('')\n const [fmt, setFmt] = useState({ bold: false, italic: false, underline: false, ul: false, ol: false })\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const editorRef = useRef<HTMLDivElement>(null)\n const hintId = useId()\n\n const trimmedLength = text.trim().length\n const belowMin = minLength !== undefined && trimmedLength < minLength\n const canSend = !disabled && trimmedLength > 0 && !belowMin\n\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n const value =\n maxLength !== undefined ? event.target.value.slice(0, maxLength) : event.target.value\n setText(value)\n const element = event.target\n element.style.height = 'auto'\n element.style.height = `${element.scrollHeight}px`\n }\n\n const syncEditor = () => {\n setText(editorText(editorRef.current))\n setFmt({\n bold: queryState('bold'),\n italic: queryState('italic'),\n underline: queryState('underline'),\n ul: queryState('insertUnorderedList'),\n ol: queryState('insertOrderedList'),\n })\n }\n\n const exec = (command: Format) => (event: MouseEvent) => {\n event.preventDefault() // keep selection/focus in the editor\n editorRef.current?.focus()\n try {\n document.execCommand(command)\n } catch {\n // execCommand unsupported — toolbar is a no-op, typing still works.\n }\n syncEditor()\n }\n\n const handleSend = () => {\n if (!canSend) return\n if (richText && editorRef.current) {\n const html = sanitizeRichText(editorRef.current.innerHTML)\n onSubmit(text.trim(), html)\n editorRef.current.innerHTML = ''\n } else {\n onSubmit(text.trim())\n if (textareaRef.current) textareaRef.current.style.height = 'auto'\n }\n setText('')\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {\n event.preventDefault()\n handleSend()\n }\n }\n\n const showCounter = maxLength !== undefined || recommendedLength !== undefined\n const counterMax = maxLength ?? recommendedLength\n const hasContent = trimmedLength > 0\n let counterLabel = belowMin && hasContent ? (minLengthHint ?? '') : hasContent ? (okHint ?? '') : ''\n if (showCounter) {\n const count = `${trimmedLength}${counterMax !== undefined ? ` / ${counterMax}` : ''}`\n counterLabel = counterLabel ? `${counterLabel} · ${count}` : count\n }\n const announceHint = belowMin && hasContent\n const statusColor = belowMin ? 'sc:text-muted' : 'sc:text-ok'\n const showRich = richText && toolbarLabels\n\n const toolButton = (\n label: string,\n active: boolean,\n command: Format,\n content: string,\n extra = '',\n ) => (\n <button\n type=\"button\"\n aria-label={label}\n aria-pressed={active}\n title={label}\n onMouseDown={exec(command)}\n className={`sc:h-[34px] sc:rounded-[9px] sc:px-2.5 sc:text-[15px] sc:font-bold sc:text-question-fg sc:hover:bg-pink-tint ${active ? 'sc:bg-pink-tint' : ''} ${extra}`}\n >\n {content}\n </button>\n )\n\n return (\n <div className=\"sc:flex-shrink-0 sc:bg-canvas sc:px-4 sc:pt-2 sc:pb-3.5\">\n <div className=\"sc:mx-auto sc:max-w-[640px]\">\n <div className=\"sc:rounded-[14px] sc:border-[1.5px] sc:border-[#dedee6] sc:bg-white sc:px-[14px] sc:py-2\">\n {showRich ? (\n <div\n role=\"toolbar\"\n aria-label={toolbarLabels.toolbar}\n className=\"sc:mb-1 sc:flex sc:items-center sc:gap-0.5 sc:border-b sc:border-[#f1f1f1] sc:pb-2\"\n >\n {toolButton(toolbarLabels.bold, fmt.bold, 'bold', 'B', 'sc:w-[34px]')}\n {toolButton(toolbarLabels.italic, fmt.italic, 'italic', 'I', 'sc:w-[34px] sc:italic')}\n {toolButton(\n toolbarLabels.underline,\n fmt.underline,\n 'underline',\n 'U',\n 'sc:w-[34px] sc:underline',\n )}\n <span className=\"sc:mx-1.5 sc:h-5 sc:w-px sc:bg-line\" />\n {toolButton(toolbarLabels.bulletList, fmt.ul, 'insertUnorderedList', '• List')}\n {toolButton(toolbarLabels.numberList, fmt.ol, 'insertOrderedList', '1. List')}\n </div>\n ) : null}\n <div className=\"sc:flex sc:items-end sc:gap-2\">\n {showRich ? (\n <div className=\"sc:relative sc:flex-1\">\n <div\n ref={editorRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={inputLabel}\n aria-describedby={counterLabel ? hintId : undefined}\n tabIndex={disabled ? -1 : 0}\n contentEditable={!disabled}\n suppressContentEditableWarning\n onInput={syncEditor}\n onKeyUp={syncEditor}\n onMouseUp={syncEditor}\n onKeyDown={handleKeyDown}\n onPaste={onPaste}\n className=\"sc:max-h-[200px] sc:min-h-[44px] sc:overflow-y-auto sc:px-1 sc:py-2 sc:text-base/relaxed sc:text-question-fg sc:outline-none\"\n />\n {!hasContent ? (\n <span className=\"sc:pointer-events-none sc:absolute sc:top-2 sc:left-1 sc:text-base sc:text-[#b9b3c2]\">\n {placeholder}\n </span>\n ) : null}\n </div>\n ) : (\n <textarea\n ref={textareaRef}\n value={text}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={onPaste}\n disabled={disabled}\n placeholder={placeholder}\n aria-label={inputLabel}\n aria-describedby={counterLabel ? hintId : undefined}\n rows={1}\n className=\"sc:max-h-[200px] sc:min-h-[44px] sc:flex-1 sc:resize-none sc:overflow-y-auto sc:bg-transparent sc:px-1 sc:py-2 sc:text-base/relaxed sc:text-question-fg sc:outline-none sc:placeholder:text-[#b9b3c2] sc:disabled:opacity-50\"\n />\n )}\n <Button\n onClick={handleSend}\n disabled={!canSend}\n aria-label={sendLabel}\n className=\"sc:rounded-[10px] sc:px-5\"\n >\n {sendLabel}\n </Button>\n </div>\n </div>\n <div className=\"sc:mt-1.5 sc:flex sc:items-center sc:justify-between sc:gap-3 sc:px-1\">\n <span\n id={hintId}\n role={announceHint ? 'status' : undefined}\n className={`sc:text-[13px] sc:font-semibold sc:tabular-nums ${statusColor}`}\n >\n {counterLabel}\n </span>\n {footer ? <span className=\"sc:text-xs sc:text-muted\">{footer}</span> : null}\n </div>\n </div>\n </div>\n )\n}\n","import type { RefObject } from 'react'\nimport { Button } from '../../primitives/Button/Button'\n\nexport type VideoRecorderLabels = {\n openCamera: string\n startRecording: string\n stopRecording: string\n reRecord: string\n submit: string\n cameraError: string\n preview: string\n /** Design-only setup/recording labels (optional; fall back to no chrome). */\n camera?: string\n microphone?: string\n on?: string\n off?: string\n finishHint?: string\n cameraOff?: string\n}\n\nexport type VideoRecorderPhase = 'idle' | 'preview' | 'recording' | 'review' | 'error'\n\nexport type VideoRecorderProps = {\n phase: VideoRecorderPhase\n elapsedSeconds: number\n maxSeconds: number\n /** True once a recording is captured and ready to submit. */\n hasResult: boolean\n showPreview: boolean\n videoRef: RefObject<HTMLVideoElement | null>\n disabled?: boolean\n labels: VideoRecorderLabels\n onOpenCamera: () => void\n /** Begins the 3-2-1 countdown before recording (preferred over onStartRecording). */\n onBeginCountdown?: () => void\n onStartRecording?: () => void\n onStopRecording: () => void\n onReRecord: () => void\n onSubmit: () => void\n /** Camera/mic toggle state + handlers (setup phase). */\n camOn?: boolean\n micOn?: boolean\n onToggleCamera?: () => void\n onToggleMicrophone?: () => void\n /** 3-2-1 countdown value before recording (null/<=0 = hidden). */\n countdown?: number | null\n /** Precomposed \"n/max attempts\" label; hides the re-record button at the cap. */\n attemptsLabel?: string\n canRetake?: boolean\n /** Object URL for the recorded take, played back in review. */\n reviewUrl?: string | null\n}\n\nconst formatTime = (seconds: number): string => {\n const m = Math.floor(seconds / 60)\n const s = seconds % 60\n return `${m}:${s.toString().padStart(2, '0')}`\n}\n\nconst Toggle = ({\n label,\n on,\n onLabel,\n offLabel,\n onToggle,\n disabled,\n}: {\n label: string\n on: boolean\n onLabel: string\n offLabel: string\n onToggle: () => void\n disabled?: boolean\n}) => (\n <div className=\"sc:flex sc:items-center sc:justify-between sc:py-2.5\">\n <span className=\"sc:text-sm sc:font-semibold sc:text-[#37333d]\">{label}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={on}\n aria-label={label}\n disabled={disabled}\n onClick={onToggle}\n className=\"sc:flex sc:items-center sc:gap-2\"\n >\n <span className={`sc:text-[13px] sc:font-bold ${on ? 'sc:text-ok' : 'sc:text-muted'}`}>\n {on ? onLabel : offLabel}\n </span>\n <span\n className={`sc:relative sc:inline-block sc:h-[26px] sc:w-[44px] sc:rounded-full sc:transition-colors ${on ? 'sc:bg-button' : 'sc:bg-[#d9d2e0]'}`}\n >\n <span\n className={`sc:absolute sc:top-[3px] sc:size-5 sc:rounded-full sc:bg-white sc:shadow sc:transition-all ${on ? 'sc:left-[21px]' : 'sc:left-[3px]'}`}\n />\n </span>\n </button>\n </div>\n)\n\n/**\n * Camera preview + record/review controls, styled to the Chat-3000 design.\n * The MediaRecorder lifecycle, countdown, toggles and attempts live in\n * react/useVideoRecorder; this component only renders state + buttons.\n */\nexport const VideoRecorder = ({\n phase,\n elapsedSeconds,\n maxSeconds,\n hasResult,\n showPreview,\n videoRef,\n disabled = false,\n labels,\n onOpenCamera,\n onBeginCountdown,\n onStartRecording,\n onStopRecording,\n onReRecord,\n onSubmit,\n camOn = true,\n micOn = true,\n onToggleCamera,\n onToggleMicrophone,\n countdown,\n attemptsLabel,\n canRetake = true,\n reviewUrl,\n}: VideoRecorderProps) => {\n const showStage =\n showPreview && (phase === 'preview' || phase === 'recording')\n const countingDown = countdown != null && countdown > 0\n const recordPct = maxSeconds > 0 ? Math.min(100, Math.round((elapsedSeconds / maxSeconds) * 100)) : 0\n const beginRecording = onBeginCountdown ?? onStartRecording ?? (() => {})\n\n return (\n <div className=\"sc:mt-3.5 sc:flex sc:flex-col sc:gap-3\">\n <div className=\"sc:flex sc:w-full sc:flex-col sc:gap-3\">\n {phase === 'error' ? (\n <p role=\"alert\" className=\"sc:text-sm sc:text-red-600\">\n {labels.cameraError}\n </p>\n ) : null}\n\n {showStage ? (\n <div className=\"sc:relative sc:aspect-[4/3] sc:max-h-[420px] sc:overflow-hidden sc:rounded-[20px] sc:bg-ink-strong\">\n <video\n ref={videoRef}\n autoPlay\n muted\n playsInline\n aria-label={labels.preview}\n className=\"sc:absolute sc:inset-0 sc:size-full sc:-scale-x-100 sc:object-cover\"\n />\n {!camOn && labels.cameraOff ? (\n <div className=\"sc:absolute sc:inset-0 sc:flex sc:items-center sc:justify-center sc:bg-ink-strong sc:text-sm sc:font-semibold sc:text-white/60\">\n {labels.cameraOff}\n </div>\n ) : null}\n {countingDown ? (\n <div className=\"sc:absolute sc:inset-0 sc:flex sc:items-center sc:justify-center sc:bg-ink-strong/45\">\n <span className=\"sc:text-[100px] sc:font-extrabold sc:text-pink\">{countdown}</span>\n </div>\n ) : null}\n {phase === 'recording' ? (\n <>\n <div className=\"sc:absolute sc:top-3.5 sc:left-3.5 sc:flex sc:items-center sc:gap-2 sc:rounded-full sc:bg-black/45 sc:px-3 sc:py-1.5\">\n <span className=\"sc:size-2.5 sc:rounded-full sc:bg-[#ff5a5a] sc:[animation:sc-rec-pulse_1.1s_infinite]\" />\n <span\n role=\"timer\"\n aria-live=\"off\"\n className=\"sc:text-[13px] sc:font-bold sc:text-white sc:tabular-nums\"\n >\n {formatTime(elapsedSeconds)} / {formatTime(maxSeconds)}\n </span>\n </div>\n <div className=\"sc:absolute sc:inset-x-0 sc:bottom-0 sc:h-1.5 sc:bg-white/15\">\n <div className=\"sc:h-full sc:bg-pink-strong\" style={{ width: `${recordPct}%` }} />\n </div>\n </>\n ) : null}\n </div>\n ) : null}\n\n {phase === 'review' && reviewUrl ? (\n // eslint-disable-next-line jsx-a11y/media-has-caption -- candidate's own recorded answer, no caption track\n <video\n src={reviewUrl}\n controls\n playsInline\n aria-label={labels.preview}\n className=\"sc:aspect-[4/3] sc:max-h-[420px] sc:w-full sc:rounded-[20px] sc:bg-ink-strong sc:object-cover\"\n />\n ) : null}\n\n {phase === 'preview' && labels.camera && onToggleCamera && onToggleMicrophone ? (\n <div className=\"sc:rounded-2xl sc:bg-[#f5f4f7] sc:px-4 sc:py-1\">\n <Toggle\n label={labels.camera}\n on={camOn}\n onLabel={labels.on ?? 'On'}\n offLabel={labels.off ?? 'Off'}\n onToggle={onToggleCamera}\n disabled={disabled}\n />\n <div className=\"sc:h-px sc:bg-line\" />\n <Toggle\n label={labels.microphone ?? 'Microphone'}\n on={micOn}\n onLabel={labels.on ?? 'On'}\n offLabel={labels.off ?? 'Off'}\n onToggle={onToggleMicrophone}\n disabled={disabled}\n />\n </div>\n ) : null}\n\n {phase === 'idle' || phase === 'error' ? (\n <Button disabled={disabled} onClick={onOpenCamera}>\n {labels.openCamera}\n </Button>\n ) : null}\n\n {phase === 'preview' ? (\n <div className=\"sc:flex sc:items-center sc:gap-3\">\n <Button\n disabled={disabled || countingDown}\n onClick={beginRecording}\n className=\"sc:flex-1\"\n >\n {labels.startRecording}\n </Button>\n {attemptsLabel ? (\n <span className=\"sc:flex-shrink-0 sc:text-[13px] sc:font-bold sc:text-muted sc:tabular-nums\">\n {attemptsLabel}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {phase === 'recording' ? (\n <div className=\"sc:flex sc:flex-col sc:items-center sc:gap-1.5\">\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onStopRecording}\n aria-label={labels.stopRecording}\n className=\"sc:flex sc:size-16 sc:items-center sc:justify-center sc:rounded-full sc:border-[3px] sc:border-button sc:bg-white sc:hover:bg-pink-tint\"\n >\n <span className=\"sc:size-5 sc:rounded-md sc:bg-[#e5484d]\" />\n </button>\n {labels.finishHint ? (\n <span className=\"sc:text-[13px] sc:font-semibold sc:text-muted\">\n {labels.finishHint}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {phase === 'review' ? (\n <div className=\"sc:flex sc:flex-col sc:gap-2.5\">\n <div className=\"sc:flex sc:gap-2.5\">\n <Button disabled={disabled || !hasResult} onClick={onSubmit} className=\"sc:flex-[1.2]\">\n {labels.submit}\n </Button>\n {canRetake ? (\n <Button variant=\"ghost\" disabled={disabled} onClick={onReRecord} className=\"sc:flex-1\">\n {labels.reRecord}\n </Button>\n ) : null}\n </div>\n {attemptsLabel ? (\n <p className=\"sc:text-center sc:text-[12.5px] sc:font-semibold sc:text-muted sc:tabular-nums\">\n {attemptsLabel}\n </p>\n ) : null}\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n","// Layer B — pure MediaRecorder mimeType negotiation. No DOM access here; the\n// `isSupported` predicate is injected (MediaRecorder.isTypeSupported in the app).\n\n/** Preferred recording mimeTypes, best first (vp8/opus webm, then mp4 for Safari). */\nexport const VIDEO_MIME_CANDIDATES = [\n 'video/webm;codecs=vp8,opus',\n 'video/webm;codecs=vp9,opus',\n 'video/webm',\n 'video/mp4',\n] as const\n\nexport const AUDIO_MIME_CANDIDATES = [\n 'audio/webm;codecs=opus',\n 'audio/webm',\n 'audio/mp4',\n] as const\n\nexport type MimeSupportCheck = (mimeType: string) => boolean\n\n/** First supported candidate, or undefined to let the browser pick its default. */\nexport const negotiateMimeType = (\n candidates: readonly string[],\n isSupported: MimeSupportCheck,\n): string | undefined => candidates.find((candidate) => isSupported(candidate))\n\n/** File extension for a recorded blob's mimeType (mp4 vs webm). */\nexport const extensionForMimeType = (mimeType: string | undefined): string =>\n mimeType && mimeType.includes('mp4') ? 'mp4' : 'webm'\n\n/** webm duration metadata needs the fix-webm-duration patch; mp4 does not. */\nexport const needsWebmDurationFix = (mimeType: string | undefined): boolean =>\n extensionForMimeType(mimeType) === 'webm'\n","// Layer B — MediaRecorder state machine replacing video.js + videojs-record +\n// recordrtc. Camera/mic access and the MediaRecorder are injected so the\n// transition logic is unit-testable without a browser. idle → preview →\n// recording → review (+ error).\n\nimport {\n AUDIO_MIME_CANDIDATES,\n VIDEO_MIME_CANDIDATES,\n extensionForMimeType,\n needsWebmDurationFix,\n negotiateMimeType,\n type MimeSupportCheck,\n} from './mimeTypes'\n\nexport type RecorderPhase = 'idle' | 'preview' | 'recording' | 'review' | 'error'\n\nexport type RecorderState = {\n phase: RecorderPhase\n /** Seconds elapsed in the current recording. */\n elapsedSeconds: number\n /** Recorded result, available in the review phase. */\n result?: { blob: Blob; extension: string; durationSeconds: number }\n error?: string\n}\n\nexport type RecorderMedia = 'video' | 'audio'\n\nexport type RecorderDeps = {\n /** Max recording length in seconds; auto-stops when reached. */\n maxSeconds: number\n media?: RecorderMedia\n /** Resolves a camera/mic stream (navigator.mediaDevices.getUserMedia). */\n getStream: (constraints: MediaStreamConstraints) => Promise<MediaStream>\n /** Constructs a MediaRecorder (injected for tests). */\n createRecorder: (stream: MediaStream, options: MediaRecorderOptions) => MediaRecorder\n isTypeSupported: MimeSupportCheck\n /** Repairs webm duration metadata; defaults to fix-webm-duration (lazy). */\n fixWebmDuration?: (blob: Blob, durationMs: number) => Promise<Blob>\n /** Wall-clock source (injected for deterministic tests). */\n now?: () => number\n onChange?: (state: RecorderState) => void\n}\n\n/** Legacy bitrates (App.tsx monkey-patch): 240p-ish video, 64 kbps audio. */\nexport const VIDEO_BITS_PER_SECOND = 400_000\nexport const AUDIO_BITS_PER_SECOND = 64_000\n\nconst defaultFixWebmDuration = async (blob: Blob, durationMs: number): Promise<Blob> => {\n const mod = await import('fix-webm-duration')\n const fix = (mod.default ?? mod) as (b: Blob, d: number) => Promise<Blob>\n return fix(blob, durationMs)\n}\n\nexport class MediaRecorderController {\n private state: RecorderState = { phase: 'idle', elapsedSeconds: 0 }\n private stream?: MediaStream\n private recorder?: MediaRecorder\n private chunks: Blob[] = []\n private mimeType?: string\n private startedAt = 0\n private timer?: ReturnType<typeof setInterval>\n private readonly media: RecorderMedia\n private readonly now: () => number\n private readonly fixWebmDuration: (blob: Blob, durationMs: number) => Promise<Blob>\n\n constructor(private readonly deps: RecorderDeps) {\n this.media = deps.media ?? 'video'\n this.now = deps.now ?? (() => Date.now())\n this.fixWebmDuration = deps.fixWebmDuration ?? defaultFixWebmDuration\n }\n\n getState(): RecorderState {\n return this.state\n }\n\n getStream(): MediaStream | undefined {\n return this.stream\n }\n\n /** Request camera/mic and enter preview. */\n async openCamera(): Promise<void> {\n try {\n this.stream = await this.deps.getStream(\n this.media === 'video' ? { video: true, audio: true } : { audio: true },\n )\n this.setState({ phase: 'preview', elapsedSeconds: 0, result: undefined, error: undefined })\n } catch (error) {\n this.setState({ phase: 'error', elapsedSeconds: 0, error: errorMessage(error) })\n }\n }\n\n startRecording(): void {\n if (!this.stream || this.state.phase !== 'preview') return\n const candidates = this.media === 'video' ? VIDEO_MIME_CANDIDATES : AUDIO_MIME_CANDIDATES\n this.mimeType = negotiateMimeType(candidates, this.deps.isTypeSupported)\n const options: MediaRecorderOptions = {\n videoBitsPerSecond: this.media === 'video' ? VIDEO_BITS_PER_SECOND : undefined,\n audioBitsPerSecond: AUDIO_BITS_PER_SECOND,\n ...(this.mimeType ? { mimeType: this.mimeType } : {}),\n }\n this.chunks = []\n this.recorder = this.deps.createRecorder(this.stream, options)\n this.recorder.ondataavailable = (event) => {\n if (event.data && event.data.size > 0) this.chunks.push(event.data)\n }\n this.recorder.onstop = () => void this.finalize()\n this.recorder.start(1000)\n this.startedAt = this.now()\n this.setState({ phase: 'recording', elapsedSeconds: 0 })\n this.timer = setInterval(() => this.tick(), 1000)\n }\n\n stopRecording(): void {\n if (this.state.phase !== 'recording' || !this.recorder) return\n this.clearTimer()\n this.recorder.stop()\n }\n\n /** Discard the recording and return to preview to re-record. */\n reset(): void {\n this.clearTimer()\n this.chunks = []\n this.setState({ phase: 'preview', elapsedSeconds: 0, result: undefined, error: undefined })\n }\n\n /** Stop tracks and release the camera/mic. */\n dispose(): void {\n this.clearTimer()\n this.recorder = undefined\n this.stream?.getTracks().forEach((track) => track.stop())\n this.stream = undefined\n }\n\n private tick(): void {\n const elapsed = Math.floor((this.now() - this.startedAt) / 1000)\n this.setState({ ...this.state, elapsedSeconds: elapsed })\n if (elapsed >= this.deps.maxSeconds) this.stopRecording()\n }\n\n private async finalize(): Promise<void> {\n const durationMs = this.now() - this.startedAt\n const type = this.mimeType ?? this.chunks[0]?.type\n let blob = new Blob(this.chunks, type ? { type } : undefined)\n if (needsWebmDurationFix(type)) {\n try {\n blob = await this.fixWebmDuration(blob, durationMs)\n } catch {\n // Non-fatal: fall back to the raw blob (playback may lack seek metadata).\n }\n }\n this.setState({\n phase: 'review',\n elapsedSeconds: Math.floor(durationMs / 1000),\n result: {\n blob,\n extension: extensionForMimeType(type),\n durationSeconds: Math.floor(durationMs / 1000),\n },\n })\n }\n\n private clearTimer(): void {\n if (this.timer) clearInterval(this.timer)\n this.timer = undefined\n }\n\n private setState(next: RecorderState): void {\n this.state = next\n this.deps.onChange?.(next)\n }\n}\n\nconst errorMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error)\n","// react/ glue — owns the MediaRecorderController (Layer B) and the browser\n// MediaRecorder/getUserMedia wiring, exposing plain state + handlers so the\n// ui/ VideoRecorder stays presentational (no core import).\n//\n// The countdown, camera/mic toggles and attempts counter are client-side UX\n// (ADR: not backend-enforced); they live here, above the core recorder.\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n MediaRecorderController,\n type RecorderMedia,\n type RecorderState,\n} from '../core/media/recorder'\n\n/** Max number of takes a candidate may record (client-side UX cap). */\nexport const MAX_VIDEO_ATTEMPTS = 5\n\nexport type UseVideoRecorder = {\n state: RecorderState\n videoRef: React.RefObject<HTMLVideoElement | null>\n /** Camera/mic enabled flags (track.enabled), toggled in the setup phase. */\n camOn: boolean\n micOn: boolean\n /** 3-2-1 countdown value before recording starts, or null when inactive. */\n countdown: number | null\n /** Current take number and the cap. */\n attempts: number\n maxAttempts: number\n /** Object URL for the recorded take, available in the review phase. */\n reviewUrl: string | null\n openCamera: () => void\n beginCountdown: () => void\n stopRecording: () => void\n reRecord: () => void\n toggleCamera: () => void\n toggleMicrophone: () => void\n}\n\nexport const useVideoRecorder = (\n maxSeconds: number,\n media: RecorderMedia = 'video',\n): UseVideoRecorder => {\n const videoRef = useRef<HTMLVideoElement>(null)\n const controllerRef = useRef<MediaRecorderController | null>(null)\n const [state, setState] = useState<RecorderState>({ phase: 'idle', elapsedSeconds: 0 })\n const [camOn, setCamOn] = useState(true)\n const [micOn, setMicOn] = useState(true)\n const [countdown, setCountdown] = useState<number | null>(null)\n const [attempts, setAttempts] = useState(1)\n const [reviewUrl, setReviewUrl] = useState<string | null>(null)\n\n useEffect(() => {\n const controller = new MediaRecorderController({\n maxSeconds,\n media,\n getStream: (constraints) => navigator.mediaDevices.getUserMedia(constraints),\n createRecorder: (stream, options) => new MediaRecorder(stream, options),\n isTypeSupported: (m) => MediaRecorder.isTypeSupported(m),\n onChange: setState,\n })\n controllerRef.current = controller\n return () => controller.dispose()\n }, [maxSeconds, media])\n\n // Attach the live stream to the preview element while previewing/recording.\n useEffect(() => {\n const stream = controllerRef.current?.getStream()\n if (videoRef.current && stream && (state.phase === 'preview' || state.phase === 'recording')) {\n videoRef.current.srcObject = stream\n }\n }, [state.phase])\n\n // Recorded-take playback URL for the review phase; revoked on change/unmount.\n useEffect(() => {\n if (state.phase === 'review' && state.result?.blob) {\n const url = URL.createObjectURL(state.result.blob)\n setReviewUrl(url)\n return () => URL.revokeObjectURL(url)\n }\n setReviewUrl(null)\n }, [state.phase, state.result])\n\n // Drive the 3-2-1 countdown, then hand off to the core recorder.\n useEffect(() => {\n if (countdown === null) return\n if (countdown <= 0) {\n setCountdown(null)\n controllerRef.current?.startRecording()\n return\n }\n const timer = setTimeout(() => setCountdown((value) => (value ?? 1) - 1), 1000)\n return () => clearTimeout(timer)\n }, [countdown])\n\n const toggleCamera = useCallback(() => {\n const stream = controllerRef.current?.getStream()\n setCamOn((on) => {\n const next = !on\n stream?.getVideoTracks().forEach((track) => {\n track.enabled = next\n })\n return next\n })\n }, [])\n\n const toggleMicrophone = useCallback(() => {\n const stream = controllerRef.current?.getStream()\n setMicOn((on) => {\n const next = !on\n stream?.getAudioTracks().forEach((track) => {\n track.enabled = next\n })\n return next\n })\n }, [])\n\n const reRecord = useCallback(() => {\n setAttempts((count) => Math.min(count + 1, MAX_VIDEO_ATTEMPTS))\n controllerRef.current?.reset()\n }, [])\n\n return {\n state,\n videoRef,\n camOn,\n micOn,\n countdown,\n attempts,\n maxAttempts: MAX_VIDEO_ATTEMPTS,\n reviewUrl,\n openCamera: useCallback(() => void controllerRef.current?.openCamera(), []),\n beginCountdown: useCallback(() => setCountdown(3), []),\n stopRecording: useCallback(() => controllerRef.current?.stopRecording(), []),\n reRecord,\n toggleCamera,\n toggleMicrophone,\n }\n}\n","// react/ glue: picks the right answer input for the current question and owns\n// the transient validation-error / name-confirm modal state (component-local,\n// matching legacy). Layer C inputs stay presentational; the engine validates.\n\nimport { useEffect, useState } from 'react'\nimport type { InterviewEngine, PiiSubmitOutcome } from '../core/interview'\nimport {\n loadPhoneCountries,\n resolveDefaultPhoneCountry,\n type PhoneCountry,\n} from '../core/validation/phoneCountries'\nimport type { Region } from '../api/config'\nimport { Dialog } from '../ui/primitives/Dialog/Dialog'\nimport { PhoneAnswerInput } from '../ui/inputs/PhoneAnswerInput/PhoneAnswerInput'\nimport { TextAnswerInput } from '../ui/inputs/TextAnswerInput/TextAnswerInput'\nimport { VideoRecorder } from '../ui/inputs/VideoRecorder/VideoRecorder'\nimport type { CurrentInputKind, TextRules } from './bubbleViewModel'\nimport { useVideoRecorder } from './useVideoRecorder'\nimport type { UiStrings } from './strings'\n\nexport type AnswerInputProps = {\n engine: InterviewEngine\n kind: CurrentInputKind\n disabled: boolean\n textRules: TextRules\n strings: UiStrings\n candidateCountryCode?: string\n region: Region\n /** Max video answer length in seconds (video questions). */\n maxVideoSeconds?: number\n /** True while re-editing an FTQ/PII answer; shows a cancel affordance. */\n editing?: boolean\n cancelEditLabel?: string\n /** Called when the candidate pastes into a text answer (AGC paste log). */\n onPaste?: () => void\n}\n\ntype NameConfirm = { suggested: string; original: string }\n\nexport const AnswerInput = ({\n engine,\n kind,\n disabled,\n textRules,\n strings,\n candidateCountryCode,\n region,\n maxVideoSeconds = 60,\n editing = false,\n cancelEditLabel,\n onPaste,\n}: AnswerInputProps) => {\n const [errorKey, setErrorKey] = useState<string | null>(null)\n const [nameConfirm, setNameConfirm] = useState<NameConfirm | null>(null)\n const [phoneCountries, setPhoneCountries] = useState<PhoneCountry[]>([])\n\n useEffect(() => {\n if (kind !== 'phone') return\n let active = true\n void loadPhoneCountries().then((countries) => {\n if (active) setPhoneCountries(countries)\n })\n return () => {\n active = false\n }\n }, [kind])\n\n const handleOutcome = (outcome: PiiSubmitOutcome) => {\n if (outcome.status === 'invalid') setErrorKey(outcome.errorKey)\n else if (outcome.status === 'confirm-name')\n setNameConfirm({ suggested: outcome.suggested, original: outcome.original })\n }\n\n const cancelBar =\n editing && cancelEditLabel ? (\n <div className=\"sc:flex sc:justify-end sc:px-3 sc:pt-2\">\n <button\n type=\"button\"\n onClick={() => engine.cancelEditMode()}\n className=\"sc:text-xs sc:font-medium sc:text-black/60 sc:underline sc:cursor-pointer\"\n >\n {cancelEditLabel}\n </button>\n </div>\n ) : null\n\n if (kind === 'video') {\n return (\n <>\n {cancelBar}\n <VideoAnswerInput\n engine={engine}\n maxSeconds={maxVideoSeconds}\n disabled={disabled}\n strings={strings}\n />\n </>\n )\n }\n\n if (kind === 'phone') {\n return (\n <>\n {cancelBar}\n <PhoneAnswerInput\n countries={phoneCountries}\n defaultCountryCode={resolveDefaultPhoneCountry({ candidateCountryCode, region })}\n disabled={disabled || phoneCountries.length === 0}\n countryLabel={strings.phoneCountryLabel}\n inputLabel={strings.phoneInputLabel}\n placeholder={strings.phonePlaceholder}\n sendLabel={strings.sendLabel}\n onSubmit={(text, countryCode) =>\n void engine.submitPhoneAnswer(text, countryCode).then(handleOutcome)\n }\n />\n <ErrorDialog errorKey={errorKey} strings={strings} onClose={() => setErrorKey(null)} />\n </>\n )\n }\n\n const submit =\n kind === 'email'\n ? (text: string) => void engine.submitEmailAnswer(text).then(handleOutcome)\n : kind === 'name'\n ? (text: string) => void engine.submitNameAnswer(text).then(handleOutcome)\n : (text: string, html?: string) => void engine.submitTextAnswer(text, html)\n\n // Email/name/location are single-line PII; plain text questions keep char-count rules.\n const isPlainText = kind === 'text'\n\n return (\n <>\n {cancelBar}\n <TextAnswerInput\n onSubmit={submit}\n onPaste={onPaste}\n disabled={disabled}\n minLength={isPlainText ? textRules.minLength : undefined}\n maxLength={isPlainText ? textRules.maxLength : undefined}\n recommendedLength={isPlainText ? textRules.recommendedLength : undefined}\n placeholder={kind === 'email' ? strings.emailPlaceholder : strings.inputPlaceholder}\n inputLabel={strings.inputLabel}\n sendLabel={strings.sendLabel}\n minLengthHint={\n isPlainText && textRules.minLength !== undefined\n ? strings.minLengthHint(textRules.minLength)\n : undefined\n }\n okHint={isPlainText ? strings.answerLooksGood : undefined}\n footer={strings.composerFooter}\n richText={isPlainText}\n toolbarLabels={{\n toolbar: strings.richToolbar,\n bold: strings.richBold,\n italic: strings.richItalic,\n underline: strings.richUnderline,\n bulletList: strings.richBulletList,\n numberList: strings.richNumberList,\n }}\n />\n <ErrorDialog errorKey={errorKey} strings={strings} onClose={() => setErrorKey(null)} />\n {nameConfirm ? (\n <Dialog\n open\n title={strings.nameConfirmTitle}\n actions={[\n {\n label: strings.useSuggestedLabel(nameConfirm.suggested),\n onClick: () => {\n const value = nameConfirm.suggested\n setNameConfirm(null)\n void engine.submitNameConfirmed(value)\n },\n },\n {\n label: strings.useOriginalLabel,\n variant: 'ghost',\n onClick: () => {\n const value = nameConfirm.original\n setNameConfirm(null)\n void engine.submitNameConfirmed(value)\n },\n },\n ]}\n >\n {strings.nameConfirmBody(nameConfirm.suggested)}\n </Dialog>\n ) : null}\n </>\n )\n}\n\nconst VideoAnswerInput = ({\n engine,\n maxSeconds,\n disabled,\n strings,\n}: {\n engine: InterviewEngine\n maxSeconds: number\n disabled: boolean\n strings: UiStrings\n}) => {\n const {\n state,\n videoRef,\n camOn,\n micOn,\n countdown,\n attempts,\n maxAttempts,\n reviewUrl,\n openCamera,\n beginCountdown,\n stopRecording,\n reRecord,\n toggleCamera,\n toggleMicrophone,\n } = useVideoRecorder(maxSeconds)\n return (\n <VideoRecorder\n phase={state.phase}\n elapsedSeconds={state.elapsedSeconds}\n maxSeconds={maxSeconds}\n hasResult={Boolean(state.result)}\n showPreview\n videoRef={videoRef}\n disabled={disabled}\n camOn={camOn}\n micOn={micOn}\n countdown={countdown}\n attemptsLabel={strings.videoAttempts(attempts, maxAttempts)}\n canRetake={attempts < maxAttempts}\n reviewUrl={reviewUrl}\n labels={{\n openCamera: strings.videoOpenCamera,\n startRecording: strings.videoStartRecording,\n stopRecording: strings.videoStopRecording,\n reRecord: strings.videoReRecord,\n submit: strings.videoSubmit,\n cameraError: strings.videoCameraError,\n preview: strings.videoPreview,\n camera: strings.videoCamera,\n microphone: strings.videoMicrophone,\n on: strings.videoOn,\n off: strings.videoOff,\n finishHint: strings.videoFinishHint,\n cameraOff: strings.videoCameraOff,\n }}\n onOpenCamera={openCamera}\n onBeginCountdown={beginCountdown}\n onStopRecording={stopRecording}\n onReRecord={reRecord}\n onToggleCamera={toggleCamera}\n onToggleMicrophone={toggleMicrophone}\n onSubmit={() => state.result && void engine.submitVideoAnswer(state.result.blob, state.result.extension)}\n />\n )\n}\n\nconst ErrorDialog = ({\n errorKey,\n strings,\n onClose,\n}: {\n errorKey: string | null\n strings: UiStrings\n onClose: () => void\n}) =>\n errorKey ? (\n <Dialog\n open\n title={strings.piiError(errorKey)}\n actions={[{ label: strings.editLabel, onClick: onClose }]}\n onClose={onClose}\n />\n ) : null\n","// react/ glue — maps core MessageBubbles to the UI's view-model (ChatLogItem).\n// This is the only place that knows both shapes, keeping ui/ domain-free.\n\nimport {\n ContentType,\n MessageSender,\n PiiQuestionType,\n QuestionType,\n RuleName,\n} from '../api/types/messages'\nimport { BubbleStatus, type MessageBubble, type MessageItem } from '../core/bubbles/types'\nimport {\n MAX_VIDEO_SECONDS_DEFAULT,\n SLIDER_DEFAULT_VALUE,\n SLIDER_MAX,\n SLIDER_MIN,\n} from '../core/constants'\nimport type { ChatEmbeddedVideoItem, ChatLogItem, ChatOptionItem } from '../ui/chat/types'\n\n/** Question types whose candidate bubble renders a selectable option list. */\nconst OPTION_BUBBLE_TYPES = [QuestionType.MCQ, QuestionType.DROPDOWN, QuestionType.BGQ]\n\n/** Question types the candidate may re-edit (legacy handleEditAnswer: FTQ/MCQ/DROPDOWN). */\nconst EDITABLE_TYPES = [QuestionType.FTQ, QuestionType.MCQ, QuestionType.DROPDOWN]\n\n/** MCQ values rendered as one-off buttons (terms accept / submit) — not editable. */\nconst NON_EDITABLE_ANSWER_VALUES = ['ph_i_accept', 'ph_submit_assessment']\n\nconst isOptionCandidateBubble = (bubble: MessageBubble): boolean =>\n bubble.sender === MessageSender.CANDIDATE &&\n (bubble.types ?? []).some((type) => OPTION_BUBBLE_TYPES.includes(type))\n\nconst isSliderCandidateBubble = (bubble: MessageBubble): boolean =>\n bubble.sender === MessageSender.CANDIDATE &&\n (bubble.types ?? []).includes(QuestionType.SLIDER)\n\nconst isVideoCandidateBubble = (bubble: MessageBubble): boolean =>\n bubble.sender === MessageSender.CANDIDATE &&\n (bubble.types ?? []).includes(QuestionType.VIDEO)\n\n/**\n * Agent content renders as a video embed when the BE says VideoPlayer, else by\n * ContentType (fallback). Prefer the BE indicator so a future BE mapping change\n * (e.g. grouped PII) drives rendering without a client edit.\n */\nconst isVideoContent = (item: MessageItem): boolean =>\n item.component ? item.component === 'VideoPlayer' : (item.types ?? []).includes(ContentType.VIDEO)\n\n/**\n * A backend-delivered embedded video on an agent bubble: the first messageItem\n * that renders as video. The URL is the content value.\n * (Legacy AgentMessageBubble.renderVideo parity — ADR-025.)\n */\nconst agentEmbeddedVideo = (bubble: MessageBubble): ChatEmbeddedVideoItem | undefined => {\n if (bubble.sender !== MessageSender.AGENT) return undefined\n const videoItem = (bubble.data.messageItems ?? []).find(isVideoContent)\n const url = videoItem?.contents?.[0]?.value\n return url ? { url } : undefined\n}\n\n/** Extracts the file extension from a stored video filename (e.g. \"...webm\"). */\nconst videoExtensionFromFileName = (fileName?: string): string | undefined => {\n if (!fileName || !fileName.includes('.')) return undefined\n return fileName.split('.').pop()\n}\n\nconst optionsActive = (status: BubbleStatus): boolean =>\n status === BubbleStatus.ANSWERING ||\n status === BubbleStatus.FAILED ||\n status === BubbleStatus.EDITING\n\n/** An answered candidate bubble whose answer can be re-edited. */\nconst editableQuestionId = (bubble: MessageBubble): string | undefined => {\n if (bubble.sender !== MessageSender.CANDIDATE || bubble.status !== BubbleStatus.ANSWERED) {\n return undefined\n }\n const isEditableType = (bubble.types ?? []).some((type) => EDITABLE_TYPES.includes(type))\n const value = bubble.data.answer?.value\n if (!isEditableType || (value && NON_EDITABLE_ANSWER_VALUES.includes(value))) return undefined\n return bubble.questionId\n}\n\nconst bubbleParagraphs = (bubble: MessageBubble): string[] => {\n if (bubble.sender === MessageSender.CANDIDATE && bubble.data.answer) {\n return [bubble.data.answer.text]\n }\n return (bubble.data.messageItems ?? [])\n // VIDEO content renders as an embed, not as a text paragraph (ADR-025).\n .filter((item) => !isVideoContent(item))\n .map((item) => item.contents?.[0]?.text ?? '')\n .filter((text) => text.length > 0)\n}\n\n/** Per-card eyebrow + optional dark badge, keyed by agent bubble id. */\nexport type QuestionCard = { label: string; badge?: string }\n\nconst toChatItem = (\n bubble: MessageBubble,\n cards: Map<string, QuestionCard>,\n streamingBubbleId?: string,\n): ChatLogItem => {\n const embeddedVideo = agentEmbeddedVideo(bubble)\n const card = cards.get(bubble.id)\n const isCard = card !== undefined\n const base: ChatLogItem = {\n id: bubble.id,\n sender: bubble.sender === MessageSender.AGENT ? 'agent' : 'candidate',\n paragraphs: bubbleParagraphs(bubble),\n pending: bubble.status === BubbleStatus.PENDING,\n failed: bubble.status === BubbleStatus.FAILED,\n editableQuestionId: editableQuestionId(bubble),\n editing: bubble.status === BubbleStatus.EDITING,\n ...(embeddedVideo ? { embeddedVideo } : {}),\n ...(isCard\n ? {\n variant: 'card' as const,\n questionLabel: card.label,\n ...(card.badge ? { questionBadge: card.badge } : {}),\n }\n : {}),\n ...(streamingBubbleId !== undefined && bubble.id === streamingBubbleId\n ? { streaming: true as const }\n : {}),\n ...(bubble.sender === MessageSender.CANDIDATE && bubble.data.answer?.html\n ? { answerHtml: bubble.data.answer.html }\n : {}),\n }\n if (isOptionCandidateBubble(bubble)) {\n // Once selected, the bubble collapses to the chosen answer text — shown\n // optimistically the moment the answer is in flight (PENDING), so the\n // selection reads like a sent free-text answer; re-editing re-shows options.\n const answer = bubble.data.answer\n if (\n bubble.status === BubbleStatus.ANSWERED ||\n (bubble.status === BubbleStatus.PENDING && answer != null)\n ) {\n return { ...base, paragraphs: answer ? [answer.text] : [] }\n }\n const contents = bubble.data.messageItems?.[0]?.contents ?? []\n const options: ChatOptionItem[] = contents.map(({ id, text }) => ({ id, text }))\n return {\n ...base,\n // The option list replaces the answer text while answering or editing.\n paragraphs: [],\n options,\n optionsKind: bubble.types?.includes(QuestionType.DROPDOWN) ? 'dropdown' : 'list',\n selectedOptionId: contents.find((content) => content.value === bubble.data.answer?.value)?.id,\n optionsEnabled: optionsActive(bubble.status),\n }\n }\n\n if (isVideoCandidateBubble(bubble)) {\n return {\n ...base,\n paragraphs: [],\n video: {\n uploadProgress: bubble.uploadProgress,\n blob: bubble.videoBlob,\n questionId: bubble.questionId,\n // Server-confirmed bubbles carry no extension field; derive it from the\n // stored videoFileName (answer value) so playback can fetch the access URL.\n extension: bubble.videoExtension ?? videoExtensionFromFileName(bubble.data.answer?.value),\n failed: bubble.status === BubbleStatus.FAILED,\n },\n }\n }\n\n if (isSliderCandidateBubble(bubble)) {\n const submitted = bubble.data.answer?.value\n return {\n ...base,\n paragraphs: [],\n slider: {\n min: SLIDER_MIN,\n max: SLIDER_MAX,\n defaultValue: SLIDER_DEFAULT_VALUE,\n submittedValue: submitted !== undefined ? Number(submitted) : undefined,\n enabled: optionsActive(bubble.status),\n },\n }\n }\n\n return base\n}\n\nexport const mapBubblesToChatItems = (\n bubbles: MessageBubble[],\n cards: Map<string, QuestionCard> = new Map(),\n streamingBubbleId?: string,\n): ChatLogItem[] =>\n bubbles\n .map((bubble) => toChatItem(bubble, cards, streamingBubbleId))\n .filter(\n (item) =>\n item.paragraphs.length > 0 ||\n (item.options?.length ?? 0) > 0 ||\n item.slider !== undefined ||\n item.video !== undefined ||\n item.embeddedVideo !== undefined,\n )\n\nexport type TextRules = {\n minLength?: number\n maxLength?: number\n recommendedLength?: number\n}\n\n/**\n * The agent bubble whose answer the bottom input targets: the question under\n * edit when editing, otherwise the last agent bubble (current question).\n */\nexport const currentAgentBubble = (\n bubbles: MessageBubble[],\n editingQuestionId?: string,\n): MessageBubble | undefined => {\n const agentBubbles = bubbles.filter((bubble) => bubble.sender === MessageSender.AGENT)\n if (editingQuestionId) {\n return agentBubbles.find((bubble) => bubble.questionId === editingQuestionId)\n }\n return agentBubbles[agentBubbles.length - 1]\n}\n\n/** Id of the question the bottom input currently targets (for remounting per question). */\nexport const currentQuestionId = (\n bubbles: MessageBubble[],\n editingQuestionId?: string,\n): string | undefined => currentAgentBubble(bubbles, editingQuestionId)?.questionId\n\n/** Question types presented as the elevated question card (design parity). */\nconst CARD_QUESTION_TYPES = [\n QuestionType.FTQ,\n QuestionType.MCQ,\n QuestionType.BGQ,\n QuestionType.DROPDOWN,\n QuestionType.VIDEO,\n]\n\nconst isAgentQuestionBubble = (bubble: MessageBubble): boolean =>\n bubble.sender === MessageSender.AGENT &&\n (bubble.types ?? []).some((type) => CARD_QUESTION_TYPES.includes(type))\n\n/** Eyebrow/badge copy builders, supplied by react/strings (keeps i18n out of the view-model). */\nexport type QuestionCardLabels = {\n /** \"Question {n} of {total}\" for written/video questions. */\n counter: (n: number, total: number) => string\n /** Type eyebrow for MCQ/BGQ/DROPDOWN. */\n singleChoice: string\n /** Dark badge shown on video question cards. */\n videoBadge: string\n}\n\n/**\n * Marks every agent question turn as a card (matching the prototype's permanent\n * question styling); conversational agent turns stay plain. Written/video show\n * \"Question n of N\"; choice questions show a type eyebrow; video adds a badge.\n * The ordinal increments for each counted question even when its number isn't\n * displayed. Editing a past answer suppresses all cards (inline re-edit).\n */\nexport const buildQuestionCards = (\n bubbles: MessageBubble[],\n total: number,\n labels: QuestionCardLabels,\n editingQuestionId?: string,\n): Map<string, QuestionCard> => {\n const cards = new Map<string, QuestionCard>()\n if (editingQuestionId) return cards\n let ordinal = 0\n for (const bubble of bubbles) {\n if (!isAgentQuestionBubble(bubble)) continue\n ordinal += 1\n const types = bubble.types ?? []\n if (types.includes(QuestionType.VIDEO)) {\n cards.set(bubble.id, { label: labels.counter(ordinal, total), badge: labels.videoBadge })\n } else if (\n types.includes(QuestionType.MCQ) ||\n types.includes(QuestionType.BGQ) ||\n types.includes(QuestionType.DROPDOWN)\n ) {\n cards.set(bubble.id, { label: labels.singleChoice })\n } else {\n cards.set(bubble.id, { label: labels.counter(ordinal, total) })\n }\n }\n return cards\n}\n\n/**\n * Bubble id of the active video question, so its recorder renders inside the\n * card. Undefined unless the current question is a (non-edited) video question.\n */\nexport const activeVideoCardId = (\n bubbles: MessageBubble[],\n editingQuestionId?: string,\n): string | undefined => {\n if (editingQuestionId) return undefined\n const current = currentAgentBubble(bubbles)\n if (!current) return undefined\n return (current.types ?? []).includes(QuestionType.VIDEO) ? current.id : undefined\n}\n\n/** The bottom free-text/PII input is shown only for FTQ-typed questions. */\nexport const isTextInputActive = (bubbles: MessageBubble[], editingQuestionId?: string): boolean => {\n const current = currentAgentBubble(bubbles, editingQuestionId)\n return Boolean(current?.types?.includes(QuestionType.FTQ))\n}\n\n/** Which composed input the current question needs (video, PII subtype, or plain text). */\nexport type CurrentInputKind = 'text' | 'email' | 'name' | 'phone' | 'location' | 'video'\n\nexport const currentInputKind = (\n bubbles: MessageBubble[],\n editingQuestionId?: string,\n): CurrentInputKind => {\n const bubble = currentAgentBubble(bubbles, editingQuestionId)\n if (bubble?.types?.includes(QuestionType.VIDEO)) return 'video'\n const pii = bubble?.piiQuestionType\n switch (pii) {\n case PiiQuestionType.EMAIL:\n return 'email'\n case PiiQuestionType.PHONE_NUMBER:\n return 'phone'\n case PiiQuestionType.LOCATION:\n return 'location'\n case PiiQuestionType.FULL_NAME:\n case PiiQuestionType.FIRST_NAME:\n case PiiQuestionType.LAST_NAME:\n return 'name'\n default:\n return 'text'\n }\n}\n\nconst ruleValueToNumber = (value: number | string | undefined): number | undefined => {\n if (value === undefined) return undefined\n const parsed = typeof value === 'number' ? value : Number(value)\n return Number.isFinite(parsed) ? parsed : undefined\n}\n\nexport const currentTextRules = (\n bubbles: MessageBubble[],\n editingQuestionId?: string,\n): TextRules => {\n const rules = currentAgentBubble(bubbles, editingQuestionId)?.data.rules ?? []\n const byName = (name: RuleName) => ruleValueToNumber(rules.find((rule) => rule.name === name)?.value)\n return {\n minLength: byName(RuleName.MIN_TEXT_LENGTH),\n maxLength: byName(RuleName.MAX_TEXT_LENGTH),\n recommendedLength: byName(RuleName.RECOMMENDED_TEXT_LENGTH),\n }\n}\n\n/** Max video answer length in seconds (legacy reuses the voice-seconds rule). */\nexport const currentMaxVideoSeconds = (\n bubbles: MessageBubble[],\n editingQuestionId?: string,\n): number => {\n const rules = currentAgentBubble(bubbles, editingQuestionId)?.data.rules ?? []\n const max = ruleValueToNumber(rules.find((rule) => rule.name === RuleName.MAX_VOICE_SECONDS)?.value)\n return max ?? MAX_VIDEO_SECONDS_DEFAULT\n}\n","// UI copy, sourced from the translator (fetched translation file + bundled\n// fallback). Legacy fi_* keys resolve against the backend translation file for\n// non-English languages; sc_* keys are widget chrome with English fallback.\n\nimport type { Translator } from '../core/i18n/translator'\n\nexport const buildStrings = (t: Translator) => ({\n headerTitle: t('sc_header_title'),\n headerSubtitle: t('sc_header_subtitle'),\n speakerInterviewer: t('sc_speaker_interviewer'),\n singleChoiceLabel: t('sc_single_choice_label'),\n videoBadge: t('sc_video_badge'),\n typingLabel: t('sc_typing'),\n typingReading: t('sc_typing_reading'),\n typingThinking: t('sc_typing_thinking'),\n progressLabel: t('sc_progress_label'),\n /** Header pill / question-card badge: \"Question {current} of {total}\". */\n questionCounter: (current: number, total: number) =>\n t('sc_question_counter', { current, total }),\n gettingStarted: t('sc_getting_started'),\n pauseHint: t('sc_pause_hint'),\n copyLinkLabel: t('sc_copy_link'),\n copiedLabel: t('sc_copied'),\n /** Header title \"{role} role with {company}\". */\n roleWithCompany: (role: string, company: string) =>\n t('sc_role_with_company', { role, company }),\n welcomeGreeting: (name?: string) =>\n name ? t('sc_welcome_greeting', { name }) : t('sc_welcome_greeting_generic'),\n welcomeTitle: t('sc_welcome_title'),\n welcomeEyebrow: t('sc_welcome_eyebrow'),\n welcomeCopyResume: t('sc_welcome_copy_resume'),\n welcomeIntro: (role?: string, company?: string) =>\n role && company\n ? t('sc_welcome_intro', { role, company })\n : t('sc_welcome_intro_generic'),\n welcomePause: t('sc_welcome_pause'),\n welcomeNext: t('sc_welcome_next'),\n welcomeReassurance: t('sc_welcome_reassurance'),\n answerLooksGood: t('sc_answer_looks_good'),\n composerFooter: t('sc_composer_footer'),\n richToolbar: t('sc_rich_toolbar'),\n richBold: t('sc_rich_bold'),\n richItalic: t('sc_rich_italic'),\n richUnderline: t('sc_rich_underline'),\n richBulletList: t('sc_rich_bullet_list'),\n richNumberList: t('sc_rich_number_list'),\n inputPlaceholder: t('fi_label_enterResponse'),\n inputLabel: t('sc_input_label'),\n sendLabel: t('sc_button_send'),\n retryLabel: t('fi_button_retry'),\n editLabel: t('fi_button_edit'),\n cancelEditLabel: t('fi_label_cancelEditDesktop'),\n optionsGroupLabel: t('sc_options_group'),\n sliderLabel: t('fi_label_ratingMessage'),\n sliderHint: t('fi_label_ratingMessage'),\n submitRatingLabel: t('fi_button_submitRating'),\n dropdownSearchPlaceholder: t('fi_placeholder_dropdown'),\n dropdownSearchLabel: t('sc_dropdown_search_label'),\n emailPlaceholder: t('fi_placeholder_demoEmailInput'),\n phoneCountryLabel: t('sc_phone_country_label'),\n phoneInputLabel: t('sc_phone_input_label'),\n phonePlaceholder: t('sc_phone_placeholder'),\n nameConfirmTitle: t('sc_name_confirm_title'),\n nameConfirmBody: (suggested: string) => t('sc_name_confirm_body', { suggested }),\n useSuggestedLabel: (suggested: string) => t('sc_name_use_suggested', { suggested }),\n useOriginalLabel: t('sc_name_use_original'),\n minLengthHint: (min: number) => t('sc_min_length_hint', { min }),\n loadingLabel: t('sc_loading'),\n preparingLabel: t('sc_preparing'),\n doneTitle: (name?: string) =>\n name ? t('sc_done_title_named', { name }) : t('sc_done_title'),\n doneSubtitle: (company?: string) =>\n company ? t('sc_done_subtitle', { company }) : t('sc_done_subtitle_generic'),\n doneNextLabel: t('sc_done_next_label'),\n doneSteps: [t('sc_done_step1'), t('sc_done_step2'), t('sc_done_step3')] as [\n string,\n string,\n string,\n ],\n doneRatingPrompt: t('sc_done_rating_prompt'),\n startFailedMessage: t('sc_start_failed'),\n /** PII validation error message for a given fi_error_pii* key. */\n piiError: (key: string) => t(key),\n videoOpenCamera: t('sc_video_open_camera'),\n videoStartRecording: t('fi_button_record'),\n videoStopRecording: t('fi_button_stop'),\n videoReRecord: t('sc_video_re_record'),\n videoSubmit: t('sc_video_submit'),\n videoCameraError: t('sc_video_camera_error'),\n videoPreview: t('sc_video_preview'),\n videoCamera: t('sc_video_camera'),\n videoMicrophone: t('sc_video_microphone'),\n videoOn: t('sc_video_on'),\n videoOff: t('sc_video_off'),\n videoFinishHint: t('sc_video_finish_hint'),\n videoCameraOff: t('sc_video_camera_off'),\n videoAttempts: (current: number, max: number) => t('sc_video_attempts', { current, max }),\n videoUploadProgress: t('fi_label_uploading'),\n videoUploadFailed: t('fi_label_uploadFailed'),\n videoRetryUpload: t('sc_video_retry_upload'),\n videoPlay: t('sc_video_play'),\n videoAnswer: t('sc_video_answer'),\n embeddedVideoLabel: t('sc_video_embed_label'),\n accessTitle: t('sc_access_title'),\n accessDescription: t('sc_access_description'),\n accessInputLabel: t('sc_access_input_label'),\n accessPlaceholder: t('sc_access_placeholder'),\n accessSubmit: t('sc_access_submit'),\n accessMismatch: t('fi_error_emailDoesNotMatch'),\n agcTitle: t('fi_error_agcTitle'),\n agcMessage: (attempt: number) =>\n attempt >= 2 ? t('fi_error_agcSecondMessage') : t('fi_error_agcFirstMessage'),\n agcEdit: t('fi_button_edit'),\n agcContinue: t('fi_button_continue'),\n})\n\nexport type UiStrings = ReturnType<typeof buildStrings>\n","import { useEffect } from 'react'\n\n/**\n * Warns the candidate before leaving while `active` (e.g. a video upload or\n * answer submission in flight) — legacy useBeforeUnload during video upload.\n */\nexport const useBeforeUnload = (active: boolean): void => {\n useEffect(() => {\n if (!active) return\n const handler = (event: BeforeUnloadEvent) => {\n event.preventDefault()\n event.returnValue = ''\n }\n window.addEventListener('beforeunload', handler)\n return () => window.removeEventListener('beforeunload', handler)\n }, [active])\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport { useStore } from 'zustand'\nimport { ChatbotApiClient } from '../api/client'\nimport type { Env, Region } from '../api/config'\nimport { ChatbotEventEmitter, CHATBOT_EVENTS, type ChatbotEventMap, type ChatbotEventName } from '../core/events'\nimport { InterviewEngine } from '../core/interview'\nimport { createInterviewStore } from '../core/store'\nimport { FALLBACK_TRANSLATIONS } from '../core/i18n/fallback'\nimport { directionForLanguage, resolveLanguage } from '../core/i18n/languages'\nimport { createTranslator } from '../core/i18n/translator'\nimport type { Theme } from '../core/theme/types'\nimport { brandingToTheme, mergeThemes } from '../core/theme/branding'\nimport { themeToCssVariables } from '../core/theme/cssVariables'\nimport { ChatLog } from '../ui/chat/ChatLog/ChatLog'\nimport { Dialog } from '../ui/primitives/Dialog/Dialog'\nimport { AccessVerificationForm } from '../ui/shell/AccessVerificationForm/AccessVerificationForm'\nimport { DoneScreen } from '../ui/shell/DoneScreen/DoneScreen'\nimport { Header } from '../ui/shell/Header/Header'\nimport { PreparingScreen } from '../ui/shell/PreparingScreen/PreparingScreen'\nimport { ProgressBar } from '../ui/shell/ProgressBar/ProgressBar'\nimport { WelcomeScreen } from '../ui/shell/WelcomeScreen/WelcomeScreen'\nimport { WidgetRoot } from '../ui/shell/WidgetRoot/WidgetRoot'\nimport { AnswerInput } from './AnswerInput'\nimport {\n activeVideoCardId,\n buildQuestionCards,\n currentInputKind,\n currentMaxVideoSeconds,\n currentQuestionId,\n currentTextRules,\n isTextInputActive,\n mapBubblesToChatItems,\n} from './bubbleViewModel'\nimport { buildStrings } from './strings'\nimport { useBeforeUnload } from './useBeforeUnload'\n\nexport type ChatbotEventHandler = <E extends ChatbotEventName>(\n event: E,\n payload: ChatbotEventMap[E],\n) => void\n\nexport type SapiaChatbotProps = {\n env: Env\n region: Region\n appId: string\n assessmentId: string\n /** Overrides the env-derived API origin (mainly for env \"local\"). */\n apiOrigin?: string\n theme?: Theme\n showHeader?: boolean\n /** Interview language override (e.g. \"fr\"); defaults to the browser language. */\n language?: string\n /** Receives every widget event; or pass an emitter via createChatbot. */\n onEvent?: ChatbotEventHandler\n /** @internal used by embed/createChatbot to share its emitter. */\n emitter?: ChatbotEventEmitter\n /** @internal streaming transport override (mock SSE for the demo / tests). */\n fetchImpl?: typeof fetch\n}\n\n/** True when the OS requests reduced motion — streaming then reveals text instantly. */\nconst prefersReducedMotion = (): boolean =>\n typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches\n\nexport const SapiaChatbot = ({\n env,\n region,\n appId,\n assessmentId,\n apiOrigin,\n theme,\n showHeader = true,\n language,\n onEvent,\n emitter,\n fetchImpl,\n}: SapiaChatbotProps) => {\n // One engine/store per mounted widget; recreated only if the assessment changes.\n const [instance] = useState(() => {\n const client = new ChatbotApiClient({ env, region, appId, apiOrigin, fetchImpl })\n const store = createInterviewStore()\n const events = emitter ?? new ChatbotEventEmitter()\n const resolvedLanguage = resolveLanguage(\n language,\n typeof navigator !== 'undefined' ? navigator.language : undefined,\n )\n const engine = new InterviewEngine({\n client,\n store,\n emitter: events,\n assessmentId,\n language: resolvedLanguage,\n welcomeGate: true,\n // Reveal instantly (no per-char cadence) when the OS requests reduced motion.\n streamRevealMs: prefersReducedMotion() ? 0 : undefined,\n })\n return { store, engine, events }\n })\n\n const onEventRef = useRef(onEvent)\n onEventRef.current = onEvent\n\n useEffect(() => {\n const unsubscribes = Object.values(CHATBOT_EVENTS).map((event) =>\n instance.events.on(event, (payload) => onEventRef.current?.(event, payload)),\n )\n return () => unsubscribes.forEach((unsubscribe) => unsubscribe())\n }, [instance])\n\n const startedRef = useRef(false)\n useEffect(() => {\n if (startedRef.current) return\n startedRef.current = true\n void instance.engine.begin()\n }, [instance])\n\n const phase = useStore(instance.store, (state) => state.phase)\n const bubbles = useStore(instance.store, (state) => state.bubbles)\n const typing = useStore(instance.store, (state) => state.typing)\n const streamingBubbleId = useStore(instance.store, (state) => state.streamingBubbleId)\n const sendingAnswer = useStore(instance.store, (state) => state.sendingAnswer)\n const numOfNormalQuestion = useStore(instance.store, (state) => state.numOfNormalQuestion)\n const numOfNormalAnswer = useStore(instance.store, (state) => state.numOfNormalAnswer)\n\n const candidateCountryCode = useStore(instance.store, (state) => state.candidateCountryCode)\n const editingQuestionId = useStore(instance.store, (state) => state.editingQuestionId)\n const translations = useStore(instance.store, (state) => state.translations)\n const storeLanguage = useStore(instance.store, (state) => state.language)\n const branding = useStore(instance.store, (state) => state.branding)\n const candidateName = useStore(instance.store, (state) => state.candidateName)\n const roleTitle = useStore(instance.store, (state) => state.roleTitle)\n const emailHint = useStore(instance.store, (state) => state.emailHint)\n const accessEmailMismatch = useStore(instance.store, (state) => state.accessEmailMismatch)\n const verifyingAccess = useStore(instance.store, (state) => state.verifyingAccess)\n const showAgcWarning = useStore(instance.store, (state) => state.showAgcWarning)\n const agcAttempt = useStore(instance.store, (state) => state.agcAttempt)\n\n const strings = useMemo(\n () => buildStrings(createTranslator(translations, FALLBACK_TRANSLATIONS)),\n [translations],\n )\n const direction = directionForLanguage(storeLanguage ?? 'en-US')\n\n const questionCards = useMemo(\n () =>\n buildQuestionCards(\n bubbles,\n numOfNormalQuestion,\n {\n counter: strings.questionCounter,\n singleChoice: strings.singleChoiceLabel,\n videoBadge: strings.videoBadge,\n },\n editingQuestionId,\n ),\n [bubbles, numOfNormalQuestion, strings, editingQuestionId],\n )\n const questionNumber = Math.min(numOfNormalAnswer + 1, numOfNormalQuestion)\n const progressLabel =\n numOfNormalQuestion > 0 && (questionCards.size > 0 || numOfNormalAnswer > 0)\n ? strings.questionCounter(questionNumber, numOfNormalQuestion)\n : strings.gettingStarted\n const company = branding?.title\n const headerTitle =\n roleTitle && company ? strings.roleWithCompany(roleTitle, company) : (company ?? strings.headerTitle)\n const chatItems = useMemo(\n () => mapBubblesToChatItems(bubbles, questionCards, streamingBubbleId),\n [bubbles, questionCards, streamingBubbleId],\n )\n const videoCardId = useMemo(\n () => activeVideoCardId(bubbles, editingQuestionId),\n [bubbles, editingQuestionId],\n )\n const textRules = useMemo(\n () => currentTextRules(bubbles, editingQuestionId),\n [bubbles, editingQuestionId],\n )\n const inputKind = useMemo(\n () => currentInputKind(bubbles, editingQuestionId),\n [bubbles, editingQuestionId],\n )\n const maxVideoSeconds = useMemo(\n () => currentMaxVideoSeconds(bubbles, editingQuestionId),\n [bubbles, editingQuestionId],\n )\n // Remount the input per question so per-question UI state (e.g. the video\n // recorder) resets cleanly between consecutive same-type questions.\n const inputKey = currentQuestionId(bubbles, editingQuestionId) ?? 'none'\n // The bottom input is active for the current FTQ/video question, or for one\n // under edit; inline-type edits (MCQ/dropdown/slider) re-use the bubble.\n const inputActive =\n phase === 'active' &&\n !typing &&\n !sendingAnswer &&\n (isTextInputActive(bubbles, editingQuestionId) || inputKind === 'video')\n\n // The active video recorder renders inside its question card (not the bottom\n // input bar). Other inputs stay docked at the bottom.\n const videoInCard = phase === 'active' && inputKind === 'video' && Boolean(videoCardId)\n const answerInput =\n phase === 'active' ? (\n <AnswerInput\n key={inputKey}\n engine={instance.engine}\n kind={inputKind}\n disabled={!inputActive}\n textRules={textRules}\n strings={strings}\n candidateCountryCode={candidateCountryCode}\n region={region}\n maxVideoSeconds={maxVideoSeconds}\n editing={Boolean(editingQuestionId)}\n cancelEditLabel={strings.cancelEditLabel}\n onPaste={() => instance.engine.reportPaste()}\n />\n ) : null\n\n // Effective theme = branding from the API, overridden per-field by host setTheme.\n // Warn before leaving while an answer/video upload is in flight.\n useBeforeUnload(sendingAnswer)\n\n const themeVariables = useMemo(\n () => themeToCssVariables(mergeThemes(brandingToTheme(branding), theme)),\n [branding, theme],\n )\n\n return (\n <WidgetRoot themeVariables={themeVariables} dir={direction}>\n {showHeader && phase === 'active' ? (\n <Header\n title={headerTitle}\n subtitle={strings.headerSubtitle}\n logoUrl={branding?.logoUrl}\n progressLabel={progressLabel}\n />\n ) : null}\n {phase === 'active' ? (\n <ProgressBar\n value={numOfNormalAnswer}\n max={numOfNormalQuestion}\n label={strings.progressLabel}\n />\n ) : null}\n {phase === 'starting' || phase === 'idle' || phase === 'verifying' ? (\n <PreparingScreen label={strings.preparingLabel} />\n ) : null}\n {phase === 'welcome' ? (\n <WelcomeScreen\n logoUrl={branding?.logoUrl}\n onNext={() => void instance.engine.confirmWelcome()}\n labels={{\n eyebrow: strings.welcomeEyebrow,\n greeting: strings.welcomeGreeting(candidateName),\n intro: strings.welcomeIntro(roleTitle, company),\n copyLinkResume: strings.welcomeCopyResume,\n copied: strings.copiedLabel,\n next: strings.welcomeNext,\n }}\n />\n ) : null}\n {phase === 'ended' ? (\n <DoneScreen\n labels={{\n title: strings.doneTitle(candidateName),\n subtitle: strings.doneSubtitle(branding?.title),\n nextLabel: strings.doneNextLabel,\n steps: strings.doneSteps,\n ratingPrompt: strings.doneRatingPrompt,\n }}\n />\n ) : null}\n {phase === 'access-required' ? (\n <AccessVerificationForm\n emailHint={emailHint}\n mismatch={accessEmailMismatch}\n submitting={verifyingAccess}\n labels={{\n title: strings.accessTitle,\n description: strings.accessDescription,\n inputLabel: strings.accessInputLabel,\n placeholder: strings.accessPlaceholder,\n submit: strings.accessSubmit,\n mismatchError: strings.accessMismatch,\n }}\n onSubmit={(email) => void instance.engine.verifyAccessEmail(email)}\n />\n ) : null}\n {phase === 'failed' ? (\n <p role=\"alert\" className=\"sc:p-4 sc:text-sm sc:text-red-600\">\n {strings.startFailedMessage}\n </p>\n ) : null}\n {phase === 'active' ? (\n <ChatLog\n items={chatItems}\n typing={typing}\n typingLabel={strings.typingLabel}\n typingReadingLabel={strings.typingReading}\n typingThinkingLabel={strings.typingThinking}\n bubbleLabels={{\n retry: strings.retryLabel,\n optionsGroup: strings.optionsGroupLabel,\n edit: strings.editLabel,\n cancelEdit: strings.cancelEditLabel,\n speakerLabel: strings.speakerInterviewer,\n }}\n sliderLabels={{\n label: strings.sliderLabel,\n hint: strings.sliderHint,\n submitLabel: strings.submitRatingLabel,\n }}\n dropdownLabels={{\n searchPlaceholder: strings.dropdownSearchPlaceholder,\n searchLabel: strings.dropdownSearchLabel,\n }}\n mediaLabels={{\n uploadProgress: strings.videoUploadProgress,\n uploadFailed: strings.videoUploadFailed,\n retryUpload: strings.videoRetryUpload,\n playVideo: strings.videoPlay,\n videoAnswer: strings.videoAnswer,\n embeddedVideo: strings.embeddedVideoLabel,\n }}\n onRetry={() => void instance.engine.retryLastAnswer()}\n onSelectOption={(optionId) => void instance.engine.submitOptionAnswer(optionId)}\n onSubmitSlider={(score) => void instance.engine.submitSliderAnswer(score)}\n onEdit={(questionId) => instance.engine.enterEditMode(questionId)}\n onCancelEdit={() => instance.engine.cancelEditMode()}\n onRetryVideo={() => void instance.engine.retryVideoAnswer()}\n onResolveVideoUrl={(questionId, extension) =>\n instance.engine.getVideoPlaybackUrl(questionId, extension)\n }\n cardFooter={videoInCard ? answerInput : undefined}\n cardFooterItemId={videoInCard ? videoCardId : undefined}\n />\n ) : null}\n {phase === 'active' && !videoInCard ? answerInput : null}\n {showAgcWarning ? (\n <Dialog\n open\n title={strings.agcTitle}\n actions={[\n { label: strings.agcEdit, onClick: () => instance.engine.dismissAgcWarning() },\n {\n label: strings.agcContinue,\n variant: 'ghost',\n onClick: () => void instance.engine.continueAfterAgcWarning(),\n },\n ]}\n onClose={() => instance.engine.dismissAgcWarning()}\n >\n {strings.agcMessage(agcAttempt ?? 0)}\n </Dialog>\n ) : null}\n </WidgetRoot>\n )\n}\n","/** Default DOM id createChatbot mounts into when no target is given. */\nexport const DEFAULT_CONTAINER_ID = 'sapia-chatbot'\n","import { createRoot, type Root } from 'react-dom/client'\nimport type { Env, Region } from '../api/config'\nimport { ChatbotEventEmitter, type ChatbotEventName, type ChatbotEventMap } from '../core/events'\nimport type { Theme } from '../core/theme/types'\nimport { SapiaChatbot } from '../react/SapiaChatbot'\nimport { DEFAULT_CONTAINER_ID } from './constants'\n\nexport type CreateChatbotOptions = {\n env: Env\n region: Region\n appId: string\n assessmentId: string\n apiOrigin?: string\n theme?: Theme\n showHeader?: boolean\n /** Interview language override (e.g. \"fr\"); defaults to the browser language. */\n language?: string\n}\n\nexport type Chatbot = {\n mount: (target?: string | HTMLElement) => void\n unmount: () => void\n setTheme: (theme: Theme) => void\n on: <E extends ChatbotEventName>(\n event: E,\n handler: (payload: ChatbotEventMap[E]) => void,\n ) => () => void\n}\n\nconst resolveContainer = (target?: string | HTMLElement): HTMLElement => {\n if (target instanceof HTMLElement) return target\n const selector = target ?? `#${DEFAULT_CONTAINER_ID}`\n const element = document.querySelector<HTMLElement>(selector)\n if (!element) {\n throw new Error(`Sapia chatbot container not found for selector \"${selector}\"`)\n }\n return element\n}\n\n/** Imperative entry point for non-React hosts (and the UMD build). */\nexport const createChatbot = (options: CreateChatbotOptions): Chatbot => {\n const emitter = new ChatbotEventEmitter()\n let root: Root | null = null\n let theme = options.theme\n\n const render = () => {\n root?.render(<SapiaChatbot {...options} theme={theme} emitter={emitter} />)\n }\n\n return {\n mount(target) {\n root = createRoot(resolveContainer(target))\n render()\n },\n unmount() {\n root?.unmount()\n root = null\n },\n setTheme(nextTheme) {\n theme = nextTheme\n render()\n },\n on: (event, handler) => emitter.on(event, handler),\n }\n}\n","// Backwards-compatible surface for legacy `phapp-fi-widget` (PHChatBot) hosts.\n//\n// This is the ONLY module permitted to use the legacy `predictivehire`/PH\n// naming — every other file in the package uses the `sapia` naming. It maps the\n// legacy imperative class 1:1 onto the new `createChatbot()` so ATS hosts\n// migrate by version bump, not code rewrite. See docs/MIGRATION.md.\n\nimport { CHATBOT_EVENTS, type ChatbotEventMap, type ChatbotEventName } from '../core/events'\nimport type { Theme as SapiaTheme, ThemeSection } from '../core/theme/types'\nimport type { Env, Region } from '../api/config'\nimport { createChatbot, type Chatbot } from './createChatbot'\n\n/** Legacy mount target id (was `predictivehire`'s `CHATBOT_CONTAINER_ID`). */\nexport const CHATBOT_CONTAINER_ID = 'sapiaChatBot'\n\nconst CONTAINER_RETRY_TIMES = 2\nconst CONTAINER_RETRY_INTERVAL_MS = 500\n\nconst MISSING_IDENTIFIER_MESSAGE =\n 'PHChatBot: assessmentId is required (cohortId / jobRequisitionShortcode / applicationShortcode generic links are served by the standalone SPA, not the embeddable widget).'\n\n/** Legacy callback names (mapped 1:1 onto the new typed event names). */\nexport enum PHChatBotCallbackFunction {\n FI_ASSESSMENT_ANSWER_SAVED = 'FI_ASSESSMENT_ANSWER_SAVED',\n FI_ASSESSMENT_ANSWER_EDITED = 'FI_ASSESSMENT_ANSWER_EDITED',\n FI_ASSESSMENT_STARTED = 'FI_ASSESSMENT_STARTED',\n FI_ASSESSMENT_ENDED = 'FI_ASSESSMENT_ENDED',\n FI_ASSESSMENT_DUPLICATED = 'FI_ASSESSMENT_DUPLICATED',\n CHATBOT_ERROR = 'CHATBOT_ERROR',\n CHATBOT_LOG = 'CHATBOT_LOG',\n}\n\nexport type FIAssessmentDuplicatedCallbackPayload = {\n duplicatedWithAssessmentLink?: string\n}\n\nexport type PHChatBotCallback = {\n [PHChatBotCallbackFunction.FI_ASSESSMENT_ANSWER_SAVED]?: (payload?: unknown) => void\n [PHChatBotCallbackFunction.FI_ASSESSMENT_ANSWER_EDITED]?: (payload?: unknown) => void\n [PHChatBotCallbackFunction.FI_ASSESSMENT_STARTED]?: (payload?: unknown) => void\n [PHChatBotCallbackFunction.FI_ASSESSMENT_ENDED]?: (payload?: unknown) => void\n [PHChatBotCallbackFunction.FI_ASSESSMENT_DUPLICATED]?: (\n payload?: FIAssessmentDuplicatedCallbackPayload,\n ) => void\n [PHChatBotCallbackFunction.CHATBOT_ERROR]?: (payload?: unknown) => void\n [PHChatBotCallbackFunction.CHATBOT_LOG]?: (payload?: unknown) => void\n}\n\n/** Legacy per-section theme element (linkColor had no v3 mapping, dropped). */\nexport type ThemeElement = {\n backgroundColor?: string\n fontColor?: string\n linkColor?: string\n}\n\n/**\n * Legacy theme shape. v3 themes only the header/question/response/button\n * sections; the legacy hint/selectedItem/listItem/progressBar sections have no\n * v3 equivalent and are ignored (documented in docs/MIGRATION.md).\n */\nexport type PHChatBotTheme = {\n header?: ThemeElement\n hint?: ThemeElement\n question?: ThemeElement\n response?: ThemeElement\n selectedItem?: ThemeElement\n listItem?: ThemeElement\n button?: ThemeElement\n progressBar?: ThemeElement\n}\n\nconst toSection = (element?: ThemeElement): ThemeSection | undefined =>\n element ? { backgroundColor: element.backgroundColor, fontColor: element.fontColor } : undefined\n\n/** Map the legacy theme onto the v3 Theme, dropping unsupported sections. */\nconst convertLegacyTheme = (theme: PHChatBotTheme): SapiaTheme => ({\n header: toSection(theme.header),\n question: toSection(theme.question),\n response: toSection(theme.response),\n button: toSection(theme.button),\n})\n\n/** Maps each legacy callback slot to the new event it should fire from. */\nconst EVENT_TO_CALLBACK: Record<ChatbotEventName, PHChatBotCallbackFunction> = {\n [CHATBOT_EVENTS.ANSWER_SAVED]: PHChatBotCallbackFunction.FI_ASSESSMENT_ANSWER_SAVED,\n [CHATBOT_EVENTS.ANSWER_EDITED]: PHChatBotCallbackFunction.FI_ASSESSMENT_ANSWER_EDITED,\n [CHATBOT_EVENTS.ASSESSMENT_STARTED]: PHChatBotCallbackFunction.FI_ASSESSMENT_STARTED,\n [CHATBOT_EVENTS.ASSESSMENT_ENDED]: PHChatBotCallbackFunction.FI_ASSESSMENT_ENDED,\n [CHATBOT_EVENTS.ASSESSMENT_DUPLICATED]: PHChatBotCallbackFunction.FI_ASSESSMENT_DUPLICATED,\n [CHATBOT_EVENTS.ERROR]: PHChatBotCallbackFunction.CHATBOT_ERROR,\n [CHATBOT_EVENTS.LOG]: PHChatBotCallbackFunction.CHATBOT_LOG,\n}\n\n/**\n * Retry-resolve a container the host may render slightly after construction —\n * ported from the legacy `getContainer` retry loop in `predictivehire.tsx`.\n */\nexport const getContainer = async (\n cb: () => HTMLElement | null,\n retryTimes = CONTAINER_RETRY_TIMES,\n intervalMs = CONTAINER_RETRY_INTERVAL_MS,\n): Promise<HTMLElement | null> => {\n let remaining = retryTimes\n let element = cb()\n while (!element && remaining > 0) {\n remaining -= 1\n await new Promise((resolve) => setTimeout(resolve, intervalMs))\n element = cb()\n }\n return element\n}\n\nexport type PHChatBotOptions = {\n env: Env\n region: Region\n appId: string\n assessmentId?: string\n cohortId?: string\n jobRequisitionShortcode?: string\n applicationShortcode?: string\n showHeader?: boolean\n /** Accepted for source compatibility; the widget does not order assessments. */\n isInternalUser?: boolean\n apiOrigin?: string\n}\n\n/**\n * Drop-in replacement for the legacy `PHChatBot` class. Thin wrapper over\n * `createChatbot` — see docs/MIGRATION.md for the field-by-field mapping.\n */\nexport class PHChatBot {\n private readonly options: PHChatBotOptions\n private callbacks: PHChatBotCallback = {}\n private theme: PHChatBotTheme = {}\n private chatbot: Chatbot | null = null\n\n constructor(options: PHChatBotOptions) {\n if (!options.assessmentId) {\n console.error(MISSING_IDENTIFIER_MESSAGE)\n }\n this.options = options\n }\n\n addCallbackHandler(callbacks: PHChatBotCallback): void {\n // Handlers are read live at dispatch time, so calling this after\n // attachChatBot still takes effect (legacy parity).\n this.callbacks = { ...this.callbacks, ...callbacks }\n }\n\n setTheme({ theme }: { theme: PHChatBotTheme }): void {\n this.theme = { ...theme }\n this.chatbot?.setTheme(convertLegacyTheme(this.theme))\n }\n\n async attachChatBot(): Promise<void> {\n if (!this.options.assessmentId) return\n\n const container = await getContainer(() => document.getElementById(CHATBOT_CONTAINER_ID))\n if (!container) {\n console.error(`PHChatBot: container #${CHATBOT_CONTAINER_ID} not found`)\n return\n }\n\n this.chatbot = createChatbot({\n env: this.options.env,\n region: this.options.region,\n appId: this.options.appId,\n assessmentId: this.options.assessmentId,\n apiOrigin: this.options.apiOrigin,\n showHeader: this.options.showHeader ?? false,\n theme: convertLegacyTheme(this.theme),\n })\n\n for (const event of Object.values(CHATBOT_EVENTS)) {\n this.chatbot.on(event, (payload) => this.dispatch(event, payload))\n }\n\n this.chatbot.mount(container)\n }\n\n stopCallingApiWhenUnmount(): void {\n this.chatbot?.unmount()\n this.chatbot = null\n }\n\n private dispatch<E extends ChatbotEventName>(event: E, payload: ChatbotEventMap[E]): void {\n const handler = this.callbacks[EVENT_TO_CALLBACK[event]]\n if (!handler) return\n if (event === CHATBOT_EVENTS.ASSESSMENT_DUPLICATED) {\n const duplicated = payload as ChatbotEventMap[typeof CHATBOT_EVENTS.ASSESSMENT_DUPLICATED]\n ;(handler as PHChatBotCallback[PHChatBotCallbackFunction.FI_ASSESSMENT_DUPLICATED])?.({\n duplicatedWithAssessmentLink: duplicated.duplicatedWithAssessmentLink,\n })\n return\n }\n // Every non-duplicated legacy callback takes the raw payload; the union of\n // their signatures defeats narrowing, so forward through the common shape.\n ;(handler as (payload?: unknown) => void)(payload)\n }\n}\n"],"x_google_ignoreList":[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60],"mappings":"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"}
|