@redacto.io/consent-sdk-js 1.0.0-beta.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/redacto.d.mts +33 -3
- package/dist/redacto.d.ts +33 -3
- package/dist/redacto.global.js +2 -2
- package/dist/redacto.global.js.map +1 -1
- package/dist/redacto.js +349 -96
- package/dist/redacto.mjs +349 -96
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/state.ts","../src/core/dom.ts","../src/core/media-query.ts","../../../node_modules/.pnpm/jwt-decode@4.0.0/node_modules/jwt-decode/build/esm/index.js","../src/core/jwt-decode.ts","../src/services/cache.ts","../src/api/index.ts","../src/api/notice-consent-status.ts","../src/styles/inject.ts","../src/styles/modal.ts","../src/modal/purposes.ts","../src/modal/language-selector.ts","../src/modal/keyboard.ts","../src/services/storage.ts","../src/constants.ts","../src/modal/tts.ts","../src/modal/age-verification.ts","../src/modal/guardian-form.ts","../src/modal/verification-screen.ts","../src/modal/colors.ts","../src/modal/index.ts","../src/styles/inline.ts","../src/inline/purposes.ts","../src/inline/index.ts","../src/modal/digilocker-callback.ts"],"sourcesContent":["import { ModalController } from \"./modal\";\nimport { InlineController } from \"./inline\";\nimport { handleDigilockerCallback } from \"./modal/digilocker-callback\";\nimport type { ModalOptions, InlineOptions, DigiLockerCallbackOptions } from \"./types\";\n\nlet activeModal: ModalController | null = null;\nlet activeInline: InlineController | null = null;\n\n/**\n * Initialize a modal consent dialog.\n * Renders a full-screen overlay with the consent form.\n */\nfunction init(options: ModalOptions): void {\n // Destroy any existing instance\n destroy();\n\n activeModal = new ModalController(options);\n activeModal.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Initialize an inline consent form.\n * Renders consent purposes inside a target container element.\n */\nfunction inline(options: InlineOptions): void {\n // Destroy any existing inline instance\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n\n activeInline = new InlineController(options);\n activeInline.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Destroy all active consent instances.\n */\nfunction destroy(): void {\n if (activeModal) {\n activeModal.destroy();\n activeModal = null;\n }\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n}\n\n/**\n * Handle DigiLocker callback (for guardian verification redirect flow).\n * Call this on the DigiLocker callback page.\n */\nfunction digilockerCallback(options: DigiLockerCallbackOptions): void {\n handleDigilockerCallback(options);\n}\n\nconst RedactoConsent = {\n init,\n inline,\n destroy,\n digilockerCallback,\n version: \"0.1.0\",\n};\n\nexport default RedactoConsent;\nexport { init, inline, destroy, digilockerCallback };\nexport type { ModalOptions, InlineOptions, DigiLockerCallbackOptions };\nexport type { Settings } from \"./api/types\";\n","/**\n * Simple observable store — replaces React useState.\n * Shallow-merges updates and notifies subscribers.\n */\n\nexport type Listener<T> = (state: T, prevState: T) => void;\n\nexport class Store<T extends Record<string, any>> {\n private state: T;\n private listeners: Set<Listener<T>> = new Set();\n\n constructor(initialState: T) {\n this.state = { ...initialState };\n }\n\n getState(): Readonly<T> {\n return this.state;\n }\n\n setState(partial: Partial<T>): void {\n const prevState = this.state;\n this.state = { ...this.state, ...partial };\n this.listeners.forEach((listener) => listener(this.state, prevState));\n }\n\n subscribe(listener: Listener<T>): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n destroy(): void {\n this.listeners.clear();\n }\n}\n","/**\n * DOM creation helpers — replaces JSX.\n */\n\ntype Attrs = Record<string, any>;\n\n/**\n * Create an HTML element with attributes, styles, events, and children.\n *\n * Attribute keys:\n * - \"style\" → merged into element.style\n * - \"className\" → element.className\n * - \"on...\" → addEventListener (e.g. onClick → \"click\")\n * - \"dataset\" → Object.assign(element.dataset, value)\n * - anything else → setAttribute\n */\nexport function el(\n tag: string,\n attrs?: Attrs | null,\n ...children: (Node | string | null | undefined | false)[]\n): HTMLElement {\n const element = document.createElement(tag);\n if (attrs) applyAttrs(element, attrs);\n appendChildren(element, children);\n return element;\n}\n\n/**\n * Create an SVG element.\n */\nexport function svg(\n tag: string,\n attrs?: Attrs | null,\n ...children: (Node | string | null | undefined | false)[]\n): SVGElement {\n const element = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n tag\n );\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n if (key === \"style\" && typeof value === \"object\") {\n applyStyles(element as unknown as HTMLElement, value);\n } else {\n element.setAttribute(key, String(value));\n }\n }\n }\n appendChildren(element as unknown as HTMLElement, children);\n return element;\n}\n\nfunction applyAttrs(element: HTMLElement, attrs: Attrs): void {\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n\n if (key === \"style\" && typeof value === \"object\") {\n applyStyles(element, value);\n } else if (key === \"className\") {\n element.className = value;\n } else if (key === \"dataset\" && typeof value === \"object\") {\n Object.assign(element.dataset, value);\n } else if (key.startsWith(\"on\") && typeof value === \"function\") {\n const event = key.slice(2).toLowerCase();\n element.addEventListener(event, value);\n } else if (key === \"checked\" || key === \"disabled\" || key === \"readOnly\") {\n (element as any)[key] = value;\n } else {\n element.setAttribute(key, String(value));\n }\n }\n}\n\n/**\n * CSS properties that take a unitless number, mirroring React's CSSProperty\n * list. For these we MUST NOT append \"px\" — doing so produces invalid CSS\n * (e.g. `font-weight: 400px`) and the browser falls back to the user-agent\n * default (which is what made <h3> purpose descriptions render as bold).\n */\nconst UNITLESS_PROPS = new Set([\n \"animationIterationCount\",\n \"aspectRatio\",\n \"borderImageOutset\",\n \"borderImageSlice\",\n \"borderImageWidth\",\n \"boxFlex\",\n \"boxFlexGroup\",\n \"boxOrdinalGroup\",\n \"columnCount\",\n \"columns\",\n \"flex\",\n \"flexGrow\",\n \"flexPositive\",\n \"flexShrink\",\n \"flexNegative\",\n \"flexOrder\",\n \"fontWeight\",\n \"gridArea\",\n \"gridRow\",\n \"gridRowEnd\",\n \"gridRowSpan\",\n \"gridRowStart\",\n \"gridColumn\",\n \"gridColumnEnd\",\n \"gridColumnSpan\",\n \"gridColumnStart\",\n \"lineClamp\",\n \"lineHeight\",\n \"opacity\",\n \"order\",\n \"orphans\",\n \"scale\",\n \"tabSize\",\n \"widows\",\n \"zIndex\",\n \"zoom\",\n]);\n\n/**\n * Apply a camelCase style object to an element.\n *\n * Numeric values are interpreted as pixels (matching React's behavior) EXCEPT\n * for the unitless properties listed above, which are passed through as-is.\n */\nexport function applyStyles(\n element: HTMLElement,\n styles: Record<string, any>\n): void {\n for (const [key, value] of Object.entries(styles)) {\n if (value == null) continue;\n const stringValue =\n typeof value === \"number\" && !UNITLESS_PROPS.has(key)\n ? `${value}px`\n : String(value);\n (element.style as any)[key] = stringValue;\n }\n}\n\nfunction appendChildren(\n parent: HTMLElement,\n children: (Node | string | null | undefined | false)[]\n): void {\n for (const child of children) {\n if (child == null || child === false) continue;\n if (typeof child === \"string\") {\n parent.appendChild(document.createTextNode(child));\n } else {\n parent.appendChild(child);\n }\n }\n}\n\n/**\n * Remove all children from an element.\n */\nexport function clearElement(element: HTMLElement): void {\n while (element.firstChild) {\n element.removeChild(element.firstChild);\n }\n}\n","/**\n * matchMedia wrapper with subscribe — replaces useMediaQuery hook.\n */\n\nexport type MediaQuerySubscription = {\n matches: boolean;\n subscribe: (cb: (matches: boolean) => void) => void;\n destroy: () => void;\n};\n\nexport function createMediaQuery(query: string): MediaQuerySubscription {\n const mql = window.matchMedia(query);\n let currentMatches = mql.matches;\n const listeners: Set<(matches: boolean) => void> = new Set();\n\n const handler = (e: MediaQueryListEvent) => {\n currentMatches = e.matches;\n listeners.forEach((cb) => cb(currentMatches));\n };\n\n mql.addEventListener(\"change\", handler);\n\n return {\n get matches() {\n return currentMatches;\n },\n subscribe(cb: (matches: boolean) => void) {\n listeners.add(cb);\n },\n destroy() {\n mql.removeEventListener(\"change\", handler);\n listeners.clear();\n },\n };\n}\n","export class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }));\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n }\n catch (err) {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);\n }\n try {\n return JSON.parse(decoded);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);\n }\n}\n","import { jwtDecode } from \"jwt-decode\";\nimport type { RedactoJwtPayload } from \"../api/types\";\n\n/**\n * Decode JWT with error handling — returns null on failure.\n */\nexport function decodeTokenSafely(token: string): RedactoJwtPayload | null {\n try {\n return jwtDecode(token) as RedactoJwtPayload;\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return null;\n }\n}\n","const apiCache = new Map<string, { data: any; timestamp: number; ttl: number }>();\nconst CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport function getCachedData(key: string): any | null {\n const cached = apiCache.get(key);\n if (cached && Date.now() - cached.timestamp < cached.ttl) {\n return cached.data;\n }\n if (cached) {\n apiCache.delete(key);\n }\n return null;\n}\n\nexport function setCachedData(key: string, data: any, ttl = CACHE_TTL): void {\n apiCache.set(key, { data, timestamp: Date.now(), ttl });\n}\n\nexport function clearApiCache(): void {\n apiCache.clear();\n}\n","import { decodeTokenSafely } from \"../core/jwt-decode\";\nimport { clearApiCache, getCachedData, setCachedData } from \"../services/cache\";\nimport type {\n ConsentContent,\n ConsentEventPayload,\n FetchConsentContentParams,\n FetchConsentContentPublicParams,\n FetchTTSAudioUrlsParams,\n InitiateGuardianVerificationParams,\n InitiateGuardianVerificationResponse,\n SubmitConsentEventParams,\n SubmitConsentEventPublicParams,\n TTSAudioUrlsResponse,\n VerifyGuardianStatusParams,\n VerifyGuardianStatusResponse,\n} from \"./types\";\n\nconst BASE_URL = \"https://api.redacto.io/consent\";\nconst BASE_URL_PUBLIC = \"https://api.redacto.tech/consent\";\n\n// ─── Modal: fetch notice (authenticated, JWT-decoded) ───\n\nexport const fetchConsentContent = async ({\n noticeId,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n validate_against = \"all\",\n include_fully_consented_data = false,\n signal,\n}: FetchConsentContentParams & { signal?: AbortSignal }): Promise<ConsentContent> => {\n if (!noticeId || !accessToken || !validate_against) {\n throw new Error(\"noticeId and accessToken are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || \"\"}-${include_fully_consented_data}`;\n\n if (validate_against === \"all\" && !specific_uuid) {\n const cached = getCachedData(cacheKey);\n if (cached) return cached;\n }\n\n const url = new URL(`${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeId}`);\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n url.searchParams.append(\"validate_against\", validate_against);\n if (include_fully_consented_data) url.searchParams.append(\"include_fully_consented_data\", \"true\");\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Accept-Language\": language,\n },\n signal,\n });\n\n if (!response.ok) {\n let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;\n if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice not found\";\n else if (response.status === 409) errorMessage = \"User has already provided consent\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const data: ConsentContent = await response.json();\n\n if (validate_against === \"all\" && !specific_uuid) {\n setCachedData(cacheKey, data);\n }\n\n return data;\n};\n\n// ─── Inline: fetch notice (public, no auth) ───\n\nexport const fetchConsentContentPublic = async ({\n org_uuid,\n workspace_uuid,\n notice_uuid,\n baseUrl,\n language = \"en\",\n specific_uuid,\n}: FetchConsentContentPublicParams): Promise<ConsentContent> => {\n const apiBaseUrl = baseUrl || BASE_URL_PUBLIC;\n\n const url = new URL(\n `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices/get-notice/${notice_uuid}`\n );\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (response.status === 401) {\n const error = new Error(\"Unauthorized\") as Error & { status?: number };\n error.status = 401;\n throw error;\n }\n if (response.status === 409) {\n const error = new Error(\"User has already provided consent\") as Error & { status?: number };\n error.status = 409;\n throw error;\n }\n if (!response.ok) {\n throw new Error(`Failed to fetch consent content: ${response.statusText}`);\n }\n\n return await response.json();\n};\n\n// ─── Modal: submit consent (JWT-decoded) ───\n\nexport const submitConsentEvent = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n guardianVerificationReference,\n selfDeclaredAdult,\n signal,\n}: SubmitConsentEventParams & { signal?: AbortSignal }): Promise<void> => {\n if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {\n throw new Error(\"noticeUuid, accessToken, and purposes array are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working.\n const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL;\n\n const validatedPurposes = purposes.map((purpose) => {\n if (!purpose.uuid) throw new Error(\"Invalid purpose data: missing uuid\");\n\n const dataElements = (purpose.data_elements || [])\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n });\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: validatedPurposes,\n select_all_mandatory: false,\n source: \"WEB\",\n declined: Boolean(declined),\n meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : undefined,\n guardian_verification_reference: guardianVerificationReference,\n self_declared_adult: selfDeclaredAdult,\n };\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/submit-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Invalid request data\";\n } catch {\n errorMessage = \"Invalid request data\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice not found\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n clearApiCache();\n};\n\n// ─── Inline: submit consent (direct org/workspace) ───\n\nexport const submitConsentEventPublic = async ({\n org_uuid,\n workspace_uuid,\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n}: SubmitConsentEventPublicParams): Promise<void> => {\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working.\n const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL_PUBLIC;\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: purposes.map((purpose) => {\n if (!purpose.uuid) throw new Error(\"Invalid purpose data: missing uuid\");\n\n const dataElements = purpose.data_elements\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n }),\n select_all_mandatory: false,\n source: \"WEB\",\n declined,\n meta_data,\n };\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n }\n );\n\n if (!response.ok) {\n let errorData;\n try {\n errorData = await response.json();\n } catch {\n errorData = { message: response.statusText };\n }\n\n if (response.status === 409) {\n const error = new Error(\n errorData.detail?.message || errorData.message || \"User has already provided consent\"\n ) as Error & { status?: number; code?: number };\n error.status = 409;\n error.code = errorData.code || 409;\n throw error;\n }\n\n const error = new Error(\n errorData.detail?.message || errorData.message || `Failed to submit consent event: ${response.statusText}`\n ) as Error & { status?: number; code?: number };\n error.status = response.status;\n error.code = errorData.code;\n throw error;\n }\n};\n\n// ─── TTS Audio ───\n\nexport const fetchTTSAudioUrls = async ({\n accessToken,\n baseUrl,\n noticeUuid,\n language,\n signal,\n}: FetchTTSAudioUrlsParams & { signal?: AbortSignal }): Promise<TTSAudioUrlsResponse> => {\n if (!accessToken || !noticeUuid || !language) {\n throw new Error(\"accessToken, noticeUuid, and language are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n const url = `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeUuid}/audio/${language}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n signal,\n });\n\n if (!response.ok) {\n let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;\n if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice or audio not found\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return await response.json();\n};\n\n// ─── Guardian Verification ───\n\nexport const initiateGuardianVerification = async ({\n accessToken,\n baseUrl,\n guardianName,\n guardianContact,\n guardianRelationship,\n frontendCallbackUrl,\n metadata,\n signal,\n}: InitiateGuardianVerificationParams): Promise<InitiateGuardianVerificationResponse> => {\n if (!accessToken) throw new Error(\"accessToken is required\");\n if (!guardianName?.trim()) throw new Error(\"Guardian name is required\");\n if (!guardianContact?.trim()) throw new Error(\"Guardian contact is required\");\n if (!guardianRelationship?.trim()) throw new Error(\"Guardian relationship is required\");\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const payload: Record<string, any> = {\n guardian_name: guardianName.trim(),\n guardian_contact: guardianContact.trim(),\n guardian_relationship: guardianRelationship.trim(),\n };\n if (frontendCallbackUrl) payload.frontend_callback_url = frontendCallbackUrl;\n if (metadata) payload.metadata = metadata;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/initiate-verification`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Invalid request data\";\n } catch {\n errorMessage = \"Invalid request data\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 404) errorMessage = \"Organization or workspace not found\";\n else if (response.status === 422) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Validation error: Please check your input\";\n } catch {\n errorMessage = \"Validation error: Please check your input\";\n }\n } else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n if (detail.already_verified) {\n return {\n success: true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: true,\n verification_reference: detail.verification_reference,\n };\n }\n\n if (!detail.session_token || !detail.digilocker_redirect_url) {\n throw new Error(\"Invalid response: missing session_token or digilocker_redirect_url\");\n }\n\n return {\n success: detail.success ?? true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: false,\n session_token: detail.session_token,\n digilocker_redirect_url: detail.digilocker_redirect_url,\n expires_at: detail.expires_at,\n };\n};\n\nexport const verifyGuardianStatus = async ({\n accessToken,\n baseUrl,\n sessionToken,\n signal,\n}: VerifyGuardianStatusParams): Promise<VerifyGuardianStatusResponse> => {\n if (!accessToken || !sessionToken) {\n throw new Error(\"accessToken and sessionToken are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/verify-status`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ session_token: sessionToken }),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.detail?.message || \"Invalid session token\";\n } catch {\n errorMessage = \"Invalid session token\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 404)\n errorMessage = \"Verification session not found or expired. Please restart the verification process.\";\n else if (response.status === 410)\n errorMessage = \"Verification session has expired. Please restart the verification process.\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n return {\n status: detail.status ?? \"in_progress\",\n guardian_info_uuid: detail.guardian_info_uuid ?? null,\n verification_reference: detail.verification_reference ?? null,\n guardian_details: detail.guardian_details ?? null,\n error: detail.error ?? null,\n error_code: detail.error_code ?? null,\n can_retry: detail.can_retry ?? true,\n };\n};\n","import { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ConsentContent,\n DataElementSelection,\n FetchNoticeConsentStatusForScopeParams,\n FetchNoticeConsentStatusParams,\n LedgerConsentOverlay,\n NoticeConsentStatusResponse,\n PurposeSelection,\n} from \"./types\";\n\n/**\n * Go-ledger notice `check-consent` read.\n *\n * Post-cutover, consent records live in the Go ledger, so Python's notice\n * validation (which powered the 409 CONSENT_ALREADY_PROVIDED and the\n * `purpose_selections` / `reconsent_required` overlay) reads an empty consent\n * DB. When a `ledgerBaseUrl` is configured, the modal and the inline embed ask\n * the ledger directly instead.\n *\n * Every failure mode (no ledger configured, undecodable token, non-OK\n * response, network/abort/parse error) degrades to `null` so callers fall\n * back to the legacy Python-driven flow.\n */\n\n/**\n * Fetch the principal's current consent status for a notice from the Go\n * ledger (`check-consent`), with org/workspace supplied explicitly. The\n * principal resolves from the bearer token server-side, so the body is empty.\n * Returns null on any failure so the caller can fall back to the legacy flow.\n */\nexport const fetchNoticeConsentStatusForScope = async ({\n accessToken,\n ledgerBaseUrl,\n organisationUuid,\n workspaceUuid,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusForScopeParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {\n return null;\n }\n\n try {\n const response = await fetch(\n `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: \"{}\",\n signal,\n }\n );\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as\n | NoticeConsentStatusResponse\n | { detail?: NoticeConsentStatusResponse };\n // The ledger returns the response directly; tolerate a {detail} envelope too.\n const body =\n data && typeof data === \"object\" && \"detail\" in data && data.detail\n ? data.detail\n : (data as NoticeConsentStatusResponse);\n\n if (!body || !Array.isArray(body.purposes)) return null;\n return body;\n } catch {\n // Network / abort / parse failure — degrade to the legacy Python flow.\n return null;\n }\n};\n\n/**\n * Same read, resolving org/workspace by decoding the JWT (the modal's tokens\n * carry them). Returns null on any failure.\n */\nexport const fetchNoticeConsentStatus = async ({\n accessToken,\n ledgerBaseUrl,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !noticeUuid) return null;\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) return null;\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) return null;\n\n return fetchNoticeConsentStatusForScope({\n accessToken,\n ledgerBaseUrl,\n organisationUuid: ORG,\n workspaceUuid: WS,\n noticeUuid,\n signal,\n });\n};\n\n/**\n * Whether the principal has already fully consented to this notice with no\n * reconsent needed — the ledger equivalent of Python's 409\n * `CONSENT_ALREADY_PROVIDED`. Requires an active consent record with every\n * mandatory purpose still ACTIVE.\n */\nexport const isNoticeFullyConsented = (status: NoticeConsentStatusResponse): boolean =>\n status.consented && status.all_mandatory_active;\n\n/**\n * Translate the ledger's notice consent status into the\n * `{ purpose_selections, reconsent_required }` shape the modal already\n * consumes, so prior-consent pre-fill and reconsent categorization work off\n * the ledger. Returns null for a first-time principal (no consent record —\n * every purpose INACTIVE), preserving the normal first-time consent flow.\n *\n * `needs_reconsent` is derived from `status` (anything not ACTIVE needs\n * reconsent: expired / withdrawn / declined / inactive). NOTE: notice-version\n * reconsent is NOT covered — the ledger's check-consent has no version\n * awareness yet, so a republished-notice version bump won't re-prompt until\n * that lands on the ledger (tracked fast-follow).\n */\nexport const buildLedgerConsentOverlay = (\n status: NoticeConsentStatusResponse,\n configPurposes: ConsentContent[\"detail\"][\"active_config\"][\"purposes\"]\n): LedgerConsentOverlay | null => {\n const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));\n const hasHistory = status.purposes.some((p) => (p.status || \"INACTIVE\") !== \"INACTIVE\");\n if (!hasHistory) return null;\n\n const purpose_selections: Record<string, PurposeSelection> = {};\n for (const cp of configPurposes) {\n const lp = byUuid.get(cp.uuid);\n const purposeStatus = lp?.status || \"INACTIVE\";\n const selectedByUuid = new Map((lp?.data_elements || []).map((de) => [de.uuid, de.selected]));\n const data_elements: Record<string, DataElementSelection> = {};\n for (const de of cp.data_elements) {\n data_elements[de.uuid] = {\n selected: selectedByUuid.get(de.uuid) ?? false,\n enabled: de.enabled,\n required: de.required,\n };\n }\n purpose_selections[cp.uuid] = {\n selected: lp?.selected ?? false,\n status: purposeStatus,\n needs_reconsent: purposeStatus !== \"ACTIVE\",\n data_elements,\n };\n }\n\n const reconsent_required = configPurposes.some(\n (cp) => (purpose_selections[cp.uuid]?.status || \"INACTIVE\") !== \"ACTIVE\"\n );\n return { reconsent_required, purpose_selections };\n};\n","const STYLE_ID = \"redacto-consent-checkbox-styles\";\n\nconst STYLE_CONTENT = `\n /* Redacto Consent SDK Checkbox Styles */\n .redacto-checkbox-large {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 20px !important;\n width: 20px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-small {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 16px !important;\n width: 16px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-large:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-small:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-large:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 4px !important;\n height: 8px !important;\n border: solid white !important;\n border-width: 0 2px 2px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-small:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 3px !important;\n height: 6px !important;\n border: solid white !important;\n border-width: 0 1.5px 1.5px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-large:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n .redacto-checkbox-small:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n /* TTS Highlight Styles */\n .redacto-tts-highlight {\n position: relative !important;\n transition: background-color 0.3s ease, outline 0.3s ease !important;\n }\n\n h2.redacto-tts-highlight,\n h3.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n span.redacto-tts-highlight,\n a.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n p.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n button.redacto-tts-highlight {\n outline: 3px solid #FFF9C4 !important;\n outline-offset: 2px !important;\n }\n\n /* Overlay fade-in */\n @keyframes overlayFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n /* Spinner animation */\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* DigiLocker callback retry button hover */\n .redacto-dl-retry-btn:hover {\n background-color: #2563eb !important;\n }\n `;\n\n/**\n * Inject the checkbox / TTS / animation stylesheet into the given root.\n *\n * - When called with a `Document`, the style tag is placed in `document.head`.\n * - When called with a `ShadowRoot`, the style tag is placed inside the shadow\n * so it only applies within that shadow tree (full CSS isolation from the\n * host page).\n *\n * No-ops if the stylesheet is already present in the target root.\n */\nexport const injectCheckboxStyles = (\n root: Document | ShadowRoot\n): void => {\n if (typeof document === \"undefined\") return;\n\n // Skip if already injected into this root.\n const existing =\n root instanceof Document\n ? root.getElementById(STYLE_ID)\n : root.querySelector(`#${STYLE_ID}`);\n if (existing) return;\n\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = STYLE_CONTENT;\n\n if (root instanceof Document) {\n root.head.appendChild(style);\n } else {\n root.appendChild(style);\n }\n};\n","export const styles = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 999,\n animation: \"overlayFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1)\",\n pointerEvents: \"all\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n modal: {\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"700px\",\n borderRadius: \"8px\",\n backgroundColor: \"#ffffff\",\n boxShadow: \"4px 0px 4px 0px #00000040\",\n border: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n maxHeight: \"90vh\",\n zIndex: 1000,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n fontFamily: \"inherit\",\n },\n\n content: {\n margin: \"22px\",\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n overflow: \"hidden\",\n minHeight: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topLeft: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: \"1 1 0\",\n minWidth: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n logo: {\n height: \"32px\",\n width: \"auto\",\n maxWidth: \"140px\",\n objectFit: \"contain\",\n flexShrink: 0,\n margin: 0,\n padding: 0,\n display: \"block\",\n },\n\n title: {\n fontSize: \"18px\",\n fontWeight: 700,\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#101828\",\n flex: \"1 1 auto\",\n minWidth: 0,\n wordBreak: \"normal\",\n overflowWrap: \"anywhere\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n topRight: {\n borderRadius: \"8px\",\n padding: \"3px 9px\",\n border: \"1px solid #d0d5dd\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#344054\",\n gap: \"5px\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n cursor: \"pointer\",\n backgroundColor: \"#ffffff\",\n },\n\n middleSection: {\n margin: \"0px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"12px\",\n flexGrow: 1,\n overflowY: \"auto\",\n minHeight: 0,\n paddingRight: \"15px\",\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n privacyText: {\n fontSize: \"16px\",\n fontWeight: 400,\n lineHeight: \"150%\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n link: {\n color: \"#4f87ff\",\n textDecoration: \"none\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n subTitle: {\n fontWeight: 600,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionsContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"10px\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n bottomSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n gap: \"29px\",\n paddingTop: \"15px\",\n borderTop: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n button: {\n width: \"100%\",\n borderRadius: \"8px\",\n padding: \"9px 45px\",\n fontWeight: 400,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n cursor: \"pointer\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"center\",\n },\n\n acceptButton: {\n backgroundColor: \"#4f87ff\",\n border: \"none\",\n color: \"#ffffff\",\n },\n\n cancelButton: {\n border: \"1px solid #d0d5dd\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n },\n\n languageSelectorContainer: {\n position: \"relative\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n languageDropdown: {\n position: \"absolute\",\n top: \"100%\",\n right: 0,\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 2px 4px rgba(0, 0, 0, 0.1)\",\n zIndex: 10,\n width: \"max-content\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n marginTop: \"4px\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n languageItem: {\n padding: \"8px 12px\",\n cursor: \"pointer\",\n fontSize: \"12px\",\n color: \"#344054\",\n backgroundColor: \"#ffffff\",\n borderBottom: \"1px solid #e5e7eb\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n selectedLanguageItem: {\n backgroundColor: \"#f3f4f6\",\n fontWeight: 600,\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\n\nexport type ModalPurposeRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>;\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderModalPurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections?: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n isAlreadyConsented: boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string) => void;\n onPurposeCollapse: (purposeUuid: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string) => void;\n }\n): ModalPurposeRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n initialDataElementSelections = {},\n settings,\n isMobile,\n isAlreadyConsented,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#323B4B\";\n const textColor = settings?.textColor || \"#344054\";\n const font = settings?.font || \"inherit\";\n\n const container = el(\"div\", { style: styles.optionsContainer });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n\n // Chevron\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: headingColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[purpose.uuid] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(purpose.uuid, chevron);\n\n const chevronContainer = el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", justifyContent: \"center\", marginLeft: \"5px\" } },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n id: `purpose-name-${purpose.uuid}`,\n style: {\n ...styles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n titleElements.set(purpose.uuid, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n id: `purpose-description-${purpose.uuid}`,\n style: {\n ...styles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n fontFamily: font,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(purpose.uuid, descEl);\n\n const textContainer = el(\"div\", { style: styles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: styles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[purpose.uuid]),\n \"aria-controls\": `purpose-${purpose.uuid}`,\n \"aria-label\": `${collapsedPurposes[purpose.uuid] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(purpose.uuid, collapseBtn);\n\n // Purpose checkbox or green checkmark\n let rightElement: HTMLElement;\n if (!isAlreadyConsented) {\n const purposeCheckbox = el(\"input\", {\n className: \"redacto-checkbox-large\",\n type: \"checkbox\",\n checked: selectedPurposes[purpose.uuid] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(purpose.uuid, purposeCheckbox);\n rightElement = purposeCheckbox;\n } else {\n rightElement = createGreenCheckmark(\n 20,\n `Already consented to ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`\n );\n applyStyles(rightElement, { marginLeft: \"12px\" });\n }\n\n const optionRow = el(\"div\", { style: styles.optionItem }, collapseBtn, rightElement);\n\n // Data elements\n const deContainer = el(\"div\", {\n id: `purpose-${purpose.uuid}`,\n style: styles.dataElementsContainer,\n });\n\n if (purpose.data_elements?.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n id: `data-element-${purpose.uuid}-${dataElement.uuid}`,\n style: {\n ...styles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n fontFamily: font,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (dataElement.required) {\n const asterisk = el(\"span\", { style: { color: \"red\", marginLeft: \"4px\" }, \"aria-label\": \"required\" });\n asterisk.textContent = \"*\";\n labelSpan.appendChild(asterisk);\n }\n\n let deRightElement: HTMLElement;\n if (!isAlreadyConsented) {\n const deCheckbox = el(\"input\", {\n className: \"redacto-checkbox-small\",\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${dataElement.required ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n deRightElement = deCheckbox;\n } else {\n const wasSelected = initialDataElementSelections[combinedId] || false;\n if (wasSelected) {\n deRightElement = createGreenCheckmark(\n 16,\n `Consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`\n );\n } else {\n deRightElement = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"16px\",\n height: \"16px\",\n borderRadius: \"50%\",\n border: \"2px solid #d0d5dd\",\n backgroundColor: \"transparent\",\n },\n \"aria-label\": `Not consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`,\n });\n }\n }\n\n const deRow = el(\"div\", { style: styles.dataElementItem }, labelSpan, deRightElement);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(purpose.uuid, deContainer);\n deContainer.style.display = !collapsedPurposes[purpose.uuid] && purpose.data_elements?.length > 0 ? \"flex\" : \"none\";\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n\nfunction createGreenCheckmark(size: number, ariaLabel: string): HTMLElement {\n const svgSize = size === 20 ? 12 : 10;\n const strokeWidth = size === 20 ? \"2\" : \"1.5\";\n const pathD = size === 20 ? \"M4 6L5.5 7.5L8.5 4.5\" : \"M3 5L4.5 6.5L7.5 3.5\";\n\n const checkSvg = svg(\n \"svg\",\n {\n width: String(svgSize),\n height: String(svgSize),\n viewBox: `0 0 ${svgSize} ${svgSize}`,\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: pathD,\n stroke: \"white\",\n \"stroke-width\": strokeWidth,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n return el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: `${size}px`,\n height: `${size}px`,\n borderRadius: \"50%\",\n backgroundColor: \"#10B981\",\n },\n \"aria-label\": ariaLabel,\n }, checkSvg);\n}\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\n\nconst LANGUAGE_NATIVE_LABELS: Record<string, string> = {\n English: \"English\",\n Assamese: \"অসমীয়া (Assamese)\",\n Bengali: \"বাংলা (Bengali)\",\n Bodo: \"बड़ो (Bodo)\",\n Dogri: \"डोगरी (Dogri)\",\n \"Goan Konkani\": \"कोंकणी (Goan Konkani)\",\n Gujarati: \"ગુજરાતી (Gujarati)\",\n Hindi: \"हिन्दी (Hindi)\",\n Kannada: \"ಕನ್ನಡ (Kannada)\",\n Kashmiri: \"كٲشُر (Kashmiri)\",\n Maithili: \"मैथिली (Maithili)\",\n Malayalam: \"മലയാളം (Malayalam)\",\n Manipuri: \"ꯃꯩꯇꯩꯂꯣꯟ (Manipuri)\",\n Marathi: \"मराठी (Marathi)\",\n Nepali: \"नेपाली (Nepali)\",\n Odia: \"ଓଡ଼ିଆ (Odia)\",\n Punjabi: \"ਪੰਜਾਬੀ (Punjabi)\",\n Sanskrit: \"संस्कृतम् (Sanskrit)\",\n Santali: \"ᱥᱟᱱᱛᱟᱲᱤ (Santali)\",\n Sindhi: \"سنڌي (Sindhi)\",\n Tamil: \"தமிழ் (Tamil)\",\n Telugu: \"తెలుగు (Telugu)\",\n Urdu: \"اردو (Urdu)\",\n};\n\nconst toNativeLabel = (name: string): string => LANGUAGE_NATIVE_LABELS[name] ?? name;\n\nexport type LanguageSelectorRefs = {\n container: HTMLElement;\n button: HTMLElement;\n dropdown: HTMLElement;\n buttonText: HTMLElement;\n};\n\nexport function renderLanguageSelector(options: {\n languages: string[];\n selectedLanguage: string;\n settings?: Partial<Settings>;\n onSelect: (lang: string) => void;\n /**\n * Where the dropdown panel itself is appended. We append it as a sibling of\n * the modal (rather than inside `container`) so it can escape the modal's\n * `transform: translate(...)` stacking context. Pass the shadow root when\n * the modal is rendered inside a shadow boundary; otherwise pass\n * `document.body`.\n */\n dropdownContainer: HTMLElement | ShadowRoot;\n}): LanguageSelectorRefs {\n const { languages, selectedLanguage, settings, onSelect, dropdownContainer } = options;\n\n let isOpen = false;\n\n const buttonText = el(\"span\");\n buttonText.textContent = toNativeLabel(selectedLanguage);\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"8\",\n height: \"5\",\n viewBox: \"0 0 8 5\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n svg(\"path\", {\n d: \"M1 1L4 4L7 1\",\n stroke: settings?.button?.language?.textColor || \"#344054\",\n \"stroke-width\": \"1.5\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n const buttonStyle: Record<string, any> = { ...styles.topRight };\n if (settings?.button?.language) {\n buttonStyle.backgroundColor = settings.button.language.backgroundColor;\n buttonStyle.color = settings.button.language.textColor;\n }\n\n const button = el(\"div\", {\n style: buttonStyle,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": \"false\",\n \"aria-label\": `Language selector, current: ${toNativeLabel(selectedLanguage)}`,\n onClick: () => toggleDropdown(),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggleDropdown();\n } else if (e.key === \"Escape\") {\n closeDropdown();\n }\n },\n }, buttonText, chevronSvg);\n\n // Dropdown — uses position:fixed to escape modal's transform stacking context\n const dropdown = el(\"div\", {\n style: {\n position: \"fixed\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 4px 12px rgba(0, 0, 0, 0.15)\",\n zIndex: 2147483647, // max int — always on top\n minWidth: \"140px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n display: \"none\",\n },\n role: \"listbox\",\n \"aria-label\": \"Select language\",\n });\n\n for (const lang of languages) {\n const isSelected = lang === selectedLanguage;\n const itemStyle = isSelected\n ? { ...styles.languageItem, ...styles.selectedLanguageItem }\n : { ...styles.languageItem };\n\n if (settings?.button?.language) {\n if (isSelected && settings.button.language.selectedBackgroundColor) {\n itemStyle.backgroundColor = settings.button.language.selectedBackgroundColor;\n }\n if (isSelected && settings.button.language.selectedTextColor) {\n itemStyle.color = settings.button.language.selectedTextColor;\n }\n }\n\n const item = el(\"div\", {\n style: itemStyle,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n onClick: () => {\n onSelect(lang);\n closeDropdown();\n },\n onMouseenter: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = \"#f3f4f6\";\n },\n onMouseleave: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = isSelected ? \"#f3f4f6\" : \"#ffffff\";\n },\n });\n item.textContent = toNativeLabel(lang);\n dropdown.appendChild(item);\n }\n\n // Container only holds the button — dropdown is appended to its container\n // (shadow root in the modal flow, body for non-shadow callers) so it can\n // escape the modal's transform stacking context.\n const container = el(\"div\", { style: styles.languageSelectorContainer }, button);\n\n dropdownContainer.appendChild(dropdown);\n\n function positionDropdown() {\n const rect = button.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 4}px`;\n dropdown.style.right = `${window.innerWidth - rect.right}px`;\n dropdown.style.left = \"auto\";\n }\n\n // Click outside handler. When the modal is inside a shadow root the click\n // event's `target` is retargeted to the shadow host for listeners on the\n // document. `composedPath()` returns the real path through the shadow tree\n // so we can correctly detect whether the click originated inside the\n // selector or its dropdown.\n const clickOutsideHandler = (e: Event) => {\n const path = (e as Event & { composedPath?: () => EventTarget[] }).composedPath?.() ?? [];\n if (path.includes(container) || path.includes(dropdown)) return;\n\n // Fallback for environments without composedPath()\n if (path.length === 0) {\n const target = e.target as Node;\n if (container.contains(target) || dropdown.contains(target)) return;\n }\n closeDropdown();\n };\n\n // Reposition on scroll/resize while open\n const repositionHandler = () => {\n if (isOpen) positionDropdown();\n };\n\n function toggleDropdown() {\n isOpen ? closeDropdown() : openDropdown();\n }\n\n function openDropdown() {\n isOpen = true;\n positionDropdown();\n dropdown.style.display = \"block\";\n button.setAttribute(\"aria-expanded\", \"true\");\n setTimeout(() => {\n document.addEventListener(\"click\", clickOutsideHandler);\n }, 0);\n window.addEventListener(\"scroll\", repositionHandler, true);\n window.addEventListener(\"resize\", repositionHandler);\n }\n\n function closeDropdown() {\n isOpen = false;\n dropdown.style.display = \"none\";\n button.setAttribute(\"aria-expanded\", \"false\");\n document.removeEventListener(\"click\", clickOutsideHandler);\n window.removeEventListener(\"scroll\", repositionHandler, true);\n window.removeEventListener(\"resize\", repositionHandler);\n }\n\n return { container, button, dropdown, buttonText };\n}\n","/**\n * Focus trap + keyboard navigation for the modal.\n */\n\nexport type KeyboardTrapCleanup = () => void;\n\nexport function setupKeyboardTrap(\n modalEl: HTMLElement,\n onEscape: () => void\n): KeyboardTrapCleanup {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onEscape();\n return;\n }\n\n if (e.key === \"Tab\") {\n const focusableElements = modalEl.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusable = Array.from(focusableElements).filter(\n (el) => !el.hasAttribute(\"disabled\") && el.offsetParent !== null\n );\n\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n // When the modal lives inside a shadow root, document.activeElement\n // returns the shadow host rather than the actually focused element.\n // Read activeElement from the modal's own root for a correct answer.\n const root = modalEl.getRootNode() as Document | ShadowRoot;\n const active =\n (root as ShadowRoot).activeElement ?? document.activeElement;\n\n if (e.shiftKey) {\n if (active === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n\n document.addEventListener(\"keydown\", handler);\n\n // Auto-focus first focusable element\n requestAnimationFrame(() => {\n const firstFocusable = modalEl.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n firstFocusable?.focus();\n });\n\n return () => {\n document.removeEventListener(\"keydown\", handler);\n };\n}\n","import type { PersistedConsentState } from \"../api/types\";\n\nconst STORAGE_KEY = \"redacto_consent_sdk_state\";\nconst STATE_EXPIRY_MS = 30 * 60 * 1000; // 30 minutes\n\nconst isBrowser = (): boolean => {\n return typeof window !== \"undefined\" && typeof window.sessionStorage !== \"undefined\";\n};\n\nexport const saveConsentState = (state: PersistedConsentState): void => {\n if (!isBrowser()) {\n console.warn(\"SessionStorage not available - state not persisted\");\n return;\n }\n\n try {\n const stateWithTimestamp = {\n ...state,\n timestamp: new Date().toISOString(),\n };\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));\n } catch (error) {\n console.error(\"Failed to save consent state:\", error);\n }\n};\n\nexport const getConsentState = (): PersistedConsentState | null => {\n if (!isBrowser()) return null;\n\n try {\n const savedState = sessionStorage.getItem(STORAGE_KEY);\n if (!savedState) return null;\n\n const parsed: PersistedConsentState = JSON.parse(savedState);\n\n const stateAge = Date.now() - new Date(parsed.timestamp).getTime();\n if (stateAge > STATE_EXPIRY_MS) {\n clearConsentState();\n return null;\n }\n\n return parsed;\n } catch (error) {\n console.error(\"Failed to get consent state:\", error);\n return null;\n }\n};\n\nexport const clearConsentState = (): void => {\n if (!isBrowser()) return;\n\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch (error) {\n console.error(\"Failed to clear consent state:\", error);\n }\n};\n\nexport const updateConsentState = (updates: Partial<PersistedConsentState>): void => {\n const currentState = getConsentState();\n if (currentState) {\n saveConsentState({\n ...currentState,\n ...updates,\n timestamp: new Date().toISOString(),\n });\n }\n};\n\nexport const hasPendingVerification = (): boolean => {\n const state = getConsentState();\n return state !== null && state.flowState === \"digilocker-pending\";\n};\n\nexport const getVerificationResult = (): \"pending\" | \"verified\" | \"failed\" | \"in_progress\" | \"expired\" | null => {\n const state = getConsentState();\n return state?.verificationResult ?? null;\n};\n\nexport const getVerificationReference = (): string | null => {\n const state = getConsentState();\n return state?.verificationReference ?? null;\n};\n","import type { DpoInfoAudioKey } from \"./api/types\";\n\nexport const DPO_AUDIO_ELEMENT_MAP: ReadonlyArray<{\n audioKey: DpoInfoAudioKey;\n elementId: string;\n}> = [\n { audioKey: \"grievance_text_audio_url\", elementId: \"dpo-grievance-text\" },\n { audioKey: \"grievance_anchor_text_audio_url\", elementId: \"dpo-grievance-link\" },\n { audioKey: \"grievance_email_connector_text_audio_url\", elementId: \"dpo-grievance-email-connector\" },\n { audioKey: \"grievance_email_audio_url\", elementId: \"dpo-grievance-email\" },\n { audioKey: \"dp_board_text_audio_url\", elementId: \"dpo-dp-board-text\" },\n { audioKey: \"dp_board_anchor_text_audio_url\", elementId: \"dpo-dp-board-link\" },\n { audioKey: \"dpo_text_audio_url\", elementId: \"dpo-dpo-text\" },\n { audioKey: \"dpo_anchor_text_audio_url\", elementId: \"dpo-dpo-link\" },\n] as const;\n","import { fetchTTSAudioUrls } from \"../api\";\nimport { DPO_AUDIO_ELEMENT_MAP } from \"../constants\";\nimport type { ActiveConfig, TTSAudioUrlsResponse } from \"../api/types\";\n\nexport class TTSManager {\n private audioUrls: TTSAudioUrlsResponse[\"detail\"] | null = null;\n private audioSequence: string[] = [];\n private elementIdSequence: string[] = [];\n private currentAudio: HTMLAudioElement | null = null;\n private currentIndex = 0;\n private _isPlaying = false;\n private _isPaused = false;\n private _isAvailable = false;\n private highlightedElementId: string | null = null;\n private abortController: AbortController | null = null;\n private onStateChange: () => void;\n private root: Document | ShadowRoot;\n\n /**\n * @param onStateChange Invoked whenever playback state changes so the host\n * can refresh its UI (e.g. swap the play/pause icon).\n * @param root The root in which to look up highlightable elements by id.\n * When the modal is rendered inside a shadow root, pass that shadow root\n * so queries stay scoped to the SDK's tree (and don't accidentally hit\n * element ids that the host page also defines).\n */\n constructor(onStateChange: () => void, root: Document | ShadowRoot) {\n this.onStateChange = onStateChange;\n this.root = root;\n }\n\n get isPlaying(): boolean { return this._isPlaying; }\n get isPaused(): boolean { return this._isPaused; }\n get isAvailable(): boolean { return this._isAvailable; }\n\n async fetchAudioUrls(params: {\n accessToken: string;\n baseUrl?: string;\n noticeUuid: string;\n language: string;\n content: ActiveConfig;\n }): Promise<void> {\n // Reset availability + sequences SYNCHRONOUSLY before notifying. The\n // language can change while a previous language's URLs are still loaded;\n // if we don't clear here, a click on the speaker icon (or the in-flight\n // stop()) would either keep the icon showing or replay the previous\n // language's audio. We then fire a single onStateChange() so the UI hides\n // the icon while the new language's audio is being fetched.\n this.stopInternal();\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n try {\n const response = await fetchTTSAudioUrls({\n accessToken: params.accessToken,\n baseUrl: params.baseUrl,\n noticeUuid: params.noticeUuid,\n language: params.language,\n signal: this.abortController.signal,\n });\n\n this.audioUrls = response.detail;\n this.buildSequences(params.content);\n // Only mark TTS as available if the backend actually returned playable\n // audio for this language. Some languages (e.g. Santali) come back with\n // a 200 but empty / partial fields — surfacing the speaker icon in that\n // case would let users click it and replay the previous language.\n this._isAvailable = this.audioSequence.length > 0;\n this.onStateChange();\n } catch (error) {\n if ((error as Error).name !== \"AbortError\") {\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n }\n }\n }\n\n private buildSequences(content: ActiveConfig): void {\n if (!this.audioUrls) return;\n const urls = this.audioUrls;\n\n const audioSeq: string[] = [];\n const elementSeq: string[] = [];\n\n const push = (url: string | undefined, elementId: string) => {\n if (url) {\n audioSeq.push(url);\n elementSeq.push(elementId);\n }\n };\n\n // 1. Notice banner heading\n push(urls.notice_banner_heading_audio_url, \"privacy-notice-title\");\n // 2. Notice text\n push(urls.notice_text_audio_url, \"privacy-notice-text\");\n // 3. Privacy policy prefix text\n push(urls.privacy_policy_prefix_text_audio_url, \"privacy-policy-text\");\n // 4. Privacy policy anchor text\n push(urls.privacy_policy_anchor_text_audio_url, \"privacy-policy-link\");\n // 5. Purpose section heading\n push(urls.purpose_section_heading_audio_url, \"purpose-section-heading\");\n\n // 6. For each purpose: name, description, data elements\n for (const purpose of content.purposes) {\n const purposeAudio = urls.purposes_audio?.[purpose.uuid];\n if (purposeAudio) {\n push(purposeAudio.name_audio_url, `purpose-name-${purpose.uuid}`);\n push(purposeAudio.description_audio_url, `purpose-description-${purpose.uuid}`);\n }\n\n for (const de of purpose.data_elements) {\n const deAudio = urls.data_elements_audio?.[de.uuid];\n if (deAudio) {\n push(deAudio.name_audio_url, `data-element-${purpose.uuid}-${de.uuid}`);\n }\n }\n }\n\n // 7. Additional text\n push(urls.additional_text_audio_url, \"additional-text\");\n // 8. Privacy center anchor text\n push(urls.privacy_center_anchor_text_audio_url, \"privacy-center-link\");\n\n // 9. DPO info audio\n if (urls.dpo_info_audio) {\n for (const mapping of DPO_AUDIO_ELEMENT_MAP) {\n const audioUrl = urls.dpo_info_audio[mapping.audioKey];\n push(audioUrl, mapping.elementId);\n }\n }\n\n // 10. Confirm / Decline buttons\n push(urls.confirm_button_text_audio_url, \"confirm-button-text\");\n push(urls.decline_button_text_audio_url, \"decline-button-text\");\n\n this.audioSequence = audioSeq;\n this.elementIdSequence = elementSeq;\n }\n\n toggle(): void {\n this._isPlaying ? this.pause() : this.play();\n }\n\n play(): void {\n if (this.audioSequence.length === 0) return;\n\n if (this._isPaused && this.currentAudio) {\n this.currentAudio.play()\n .then(() => {\n this._isPlaying = true;\n this._isPaused = false;\n this.onStateChange();\n })\n .catch(() => {});\n } else {\n const startIndex = this._isPlaying ? this.currentIndex : 0;\n this.playNextAudio(startIndex);\n }\n }\n\n pause(): void {\n if (this.currentAudio && this._isPlaying) {\n this.currentAudio.pause();\n this._isPlaying = false;\n this._isPaused = true;\n this.onStateChange();\n }\n }\n\n stop(): void {\n this.stopInternal();\n this.onStateChange();\n }\n\n /**\n * Internal stop used by code paths (like fetchAudioUrls) that will fire\n * their own onStateChange after composing a richer state update — we don't\n * want the intermediate notification to flicker the UI based on a half-set\n * state (e.g. _isAvailable still true from the previous language).\n */\n private stopInternal(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio.currentTime = 0;\n this.currentAudio = null;\n }\n this._isPlaying = false;\n this._isPaused = false;\n this.currentIndex = 0;\n this.removeHighlights();\n this.highlightedElementId = null;\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.stop();\n }\n\n private playNextAudio(index: number): void {\n if (index >= this.audioSequence.length) {\n this.stop();\n return;\n }\n\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio = null;\n }\n\n const audio = new Audio(this.audioSequence[index]);\n this.currentAudio = audio;\n this.currentIndex = index;\n this._isPlaying = true;\n this._isPaused = false;\n\n // Highlight\n const elementId = this.elementIdSequence[index];\n if (elementId) {\n this.highlightElement(elementId);\n }\n\n audio.onended = () => this.playNextAudio(index + 1);\n audio.onerror = () => {\n console.warn(`Failed to load audio at index ${index}`);\n this.playNextAudio(index + 1);\n };\n\n audio.play().catch((error) => {\n console.warn(`Failed to play audio at index ${index}:`, error);\n this._isPlaying = false;\n this.onStateChange();\n });\n\n this.onStateChange();\n }\n\n private highlightElement(elementId: string): void {\n this.removeHighlights();\n this.highlightedElementId = elementId;\n\n setTimeout(() => {\n // ShadowRoot has getElementById in modern browsers; fall back to\n // querySelector with CSS.escape for safety.\n const element =\n \"getElementById\" in this.root\n ? (this.root as Document | ShadowRoot & { getElementById(id: string): HTMLElement | null }).getElementById(elementId)\n : (this.root as ShadowRoot).querySelector<HTMLElement>(`#${CSS.escape(elementId)}`);\n if (element) {\n element.classList.add(\"redacto-tts-highlight\");\n\n const rect = element.getBoundingClientRect();\n const isVisible =\n rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth;\n\n if (!isVisible) {\n element.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }\n }\n }, 50);\n }\n\n private removeHighlights(): void {\n this.root.querySelectorAll(\".redacto-tts-highlight\").forEach((el) => {\n el.classList.remove(\"redacto-tts-highlight\");\n });\n }\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type AgeVerificationRefs = {\n container: HTMLElement;\n};\n\nexport function renderAgeVerification(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n onYes: () => void;\n onNo: () => void;\n onClose: () => void;\n}): AgeVerificationRefs {\n const { settings, colors, isMobile, logoUrl, onYes, onNo, onClose } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n\n // ─── Top Section (matches React: logo+title left, X button right) ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Redacto Logo\" });\n\n const title = el(\"h2\", {\n id: \"age-verification-title\",\n style: {\n ...styles.title,\n fontSize: isMobile ? \"16px\" : \"18px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Age Verification Required\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n\n const closeBtn = el(\"button\", {\n style: {\n background: \"none\",\n border: \"none\",\n color: headingColor,\n cursor: \"pointer\",\n padding: isMobile ? \"2px\" : \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Close modal\",\n onClick: onClose,\n });\n const closeSvg = svg(\n \"svg\",\n {\n width: isMobile ? \"18\" : \"20\",\n height: isMobile ? \"18\" : \"20\",\n viewBox: \"0 0 20 20\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: \"M15 5L5 15M5 5L15 15\",\n stroke: \"currentColor\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n closeBtn.appendChild(closeSvg);\n\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft, closeBtn);\n\n // ─── Middle Section ───\n const description = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"16px\",\n },\n });\n description.textContent = \"To proceed with this consent form, we need to verify your age.\";\n\n const question = el(\"p\", {\n style: {\n ...styles.subTitle,\n color: textColor,\n fontFamily: font,\n marginBottom: \"24px\",\n textAlign: \"left\",\n },\n });\n question.textContent = \"Are you 18 years of age or older?\";\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, color: textColor, fontFamily: font },\n }, description, question);\n\n // ─── Bottom Section (Yes first, No second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const yesBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Confirm that I am 18 years of age or older\",\n onClick: onYes,\n });\n yesBtn.textContent = \"Yes, I am 18 or older\";\n\n const noBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Indicate that I am under 18 years of age\",\n onClick: onNo,\n });\n noBtn.textContent = \"No, I am under 18\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, color: textColor, fontFamily: font },\n }, yesBtn, noBtn);\n\n // ─── Assemble (wrapped in content div like modal) ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nconst RELATIONSHIP_OPTIONS = [\n { value: \"Father\", label: \"Father\" },\n { value: \"Mother\", label: \"Mother\" },\n { value: \"Legal Guardian\", label: \"Legal Guardian\" },\n { value: \"Grandparent\", label: \"Grandparent\" },\n];\n\nexport type GuardianFormData = {\n guardianName: string;\n guardianContact: string;\n guardianRelationship: string;\n};\n\nexport type GuardianFormRefs = {\n container: HTMLElement;\n nameInput: HTMLInputElement;\n contactInput: HTMLInputElement;\n relationshipDisplay: HTMLElement;\n nameError: HTMLElement;\n contactError: HTMLElement;\n relationshipError: HTMLElement;\n submitBtn: HTMLButtonElement;\n generalError: HTMLElement;\n};\n\nexport function renderGuardianForm(options: {\n formData: GuardianFormData;\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isSubmitting: boolean;\n onSubmit: () => void;\n onCancel: () => void;\n onFieldChange: (field: keyof GuardianFormData, value: string) => void;\n}): GuardianFormRefs {\n const { formData, settings, colors, isMobile, logoUrl, isSubmitting, onSubmit, onCancel, onFieldChange } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const borderColor = colors.declineBorder;\n const bgColor = settings?.backgroundColor || \"#ffffff\";\n const radius = colors.borderRadius;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n const inputStyle: Record<string, any> = {\n width: \"100%\",\n padding: \"10px 12px\",\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n fontSize: \"13px\",\n fontFamily: font,\n color: textColor,\n backgroundColor: bgColor,\n marginBottom: \"2px\",\n boxSizing: \"border-box\",\n outline: \"none\",\n };\n\n const errorStyle: Record<string, any> = {\n color: \"#DC2626\",\n fontSize: \"11px\",\n marginTop: \"4px\",\n marginBottom: \"0px\",\n display: \"none\",\n };\n\n const labelStyle: Record<string, any> = {\n fontSize: \"13px\",\n fontWeight: 500,\n color: textColor,\n fontFamily: font,\n marginBottom: \"4px\",\n display: \"block\",\n };\n\n const hintStyle: Record<string, any> = {\n fontSize: \"11px\",\n color: \"#667085\",\n marginTop: \"2px\",\n marginBottom: \"0px\",\n lineHeight: \"1.4\",\n };\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"guardian-form-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const subtitle = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: \"13px\",\n lineHeight: \"1.5\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"12px\",\n },\n });\n subtitle.textContent = \"Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed.\";\n\n // Info banner with SVG icon\n const infoIcon = svg(\n \"svg\",\n {\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#2563EB\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"circle\", { cx: \"12\", cy: \"12\", r: \"10\" }),\n svg(\"line\", { x1: \"12\", y1: \"16\", x2: \"12\", y2: \"12\" }),\n svg(\"line\", { x1: \"12\", y1: \"8\", x2: \"12.01\", y2: \"8\" })\n );\n (infoIcon as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-top:1px\";\n\n const infoText = el(\"span\");\n infoText.textContent = \"The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document.\";\n\n const infoBanner = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"8px\",\n padding: \"10px 12px\",\n backgroundColor: \"#EFF6FF\",\n border: \"1px solid #BFDBFE\",\n borderRadius: radius,\n marginBottom: \"16px\",\n fontSize: \"12px\",\n lineHeight: \"1.5\",\n color: \"#1E40AF\",\n },\n }, infoIcon, infoText);\n\n // ─── Name field ───\n const nameLabel = el(\"label\", { for: \"guardianName\", style: labelStyle });\n nameLabel.innerHTML = `Guardian's Full Name <span style=\"color:#DC2626\">*</span>`;\n\n const nameInput = el(\"input\", {\n id: \"guardianName\",\n type: \"text\",\n style: inputStyle,\n value: formData.guardianName,\n placeholder: \"e.g. Rajesh Kumar\",\n autoComplete: \"name\",\n \"aria-describedby\": \"guardianName-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianName\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const nameHint = el(\"p\", { id: \"guardianName-hint\", style: hintStyle });\n nameHint.textContent = \"Enter the full name as per government ID (Aadhaar, PAN, etc.)\";\n\n const nameError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const nameGroup = el(\"div\", null, nameLabel, nameInput, nameHint, nameError);\n\n // ─── Contact field ───\n const contactLabel = el(\"label\", { for: \"guardianContact\", style: labelStyle });\n contactLabel.innerHTML = `Guardian's Phone Number <span style=\"color:#DC2626\">*</span>`;\n\n const contactInput = el(\"input\", {\n id: \"guardianContact\",\n type: \"tel\",\n inputMode: \"tel\",\n style: inputStyle,\n value: formData.guardianContact,\n placeholder: \"e.g. 9876543210\",\n autoComplete: \"tel\",\n \"aria-describedby\": \"guardianContact-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianContact\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const contactHint = el(\"p\", { id: \"guardianContact-hint\", style: hintStyle });\n contactHint.textContent = \"Mobile number linked to guardian's Aadhaar\";\n\n const contactError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const contactGroup = el(\"div\", null, contactLabel, contactInput, contactHint, contactError);\n\n // ─── Relationship dropdown ───\n const relLabel = el(\"label\", { id: \"guardianRelationship-label\", style: labelStyle });\n relLabel.innerHTML = `Relationship <span style=\"color:#DC2626\">*</span>`;\n\n const selectedLabel = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)?.label;\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#667085\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"6 9 12 15 18 9\" })\n );\n (chevronSvg as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-left:8px;transition:transform 0.2s\";\n\n const selectedSpan = el(\"span\", {\n style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" },\n });\n selectedSpan.textContent = selectedLabel || \"Select relationship\";\n\n const relationshipDisplay = el(\"div\", {\n role: \"combobox\",\n \"aria-expanded\": \"false\",\n \"aria-haspopup\": \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n tabIndex: \"0\",\n style: {\n ...inputStyle,\n color: selectedLabel ? textColor : \"#9CA3AF\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n userSelect: \"none\",\n transition: \"border-color 0.15s, box-shadow 0.15s\",\n },\n }, selectedSpan, chevronSvg);\n\n // Dropdown list\n const dropdownList = el(\"div\", {\n id: \"guardianRelationship-listbox\",\n role: \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n style: {\n position: \"absolute\",\n top: \"calc(100% + 4px)\",\n left: 0,\n right: 0,\n backgroundColor: bgColor,\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\",\n zIndex: 50,\n overflow: \"hidden\",\n padding: \"4px 0\",\n maxHeight: \"220px\",\n overflowY: \"auto\",\n display: \"none\",\n },\n });\n\n for (let i = 0; i < RELATIONSHIP_OPTIONS.length; i++) {\n const option = RELATIONSHIP_OPTIONS[i];\n const isSelected = formData.guardianRelationship === option.value;\n\n const optionEl = el(\"div\", {\n id: `guardianRelationship-option-${i}`,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n style: {\n padding: \"9px 12px\",\n fontSize: \"13px\",\n fontFamily: font,\n color: isSelected ? accentColor : textColor,\n backgroundColor: \"transparent\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n transition: \"background-color 0.1s\",\n },\n onClick: () => {\n onFieldChange(\"guardianRelationship\", option.value);\n selectedSpan.textContent = option.label;\n relationshipDisplay.style.color = textColor;\n doClose();\n },\n onMouseenter: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"#F3F4F6\"; },\n onMouseleave: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"transparent\"; },\n });\n\n const label = el(\"span\");\n label.textContent = option.label;\n optionEl.appendChild(label);\n\n if (isSelected) {\n const checkSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: accentColor, \"stroke-width\": \"2.5\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n (checkSvg as unknown as HTMLElement).style.flexShrink = \"0\";\n optionEl.appendChild(checkSvg);\n }\n\n dropdownList.appendChild(optionEl);\n }\n\n let dropdownOpen = false;\n\n const relContainer = el(\"div\", { style: { position: \"relative\" } });\n\n const handleClickOutside = (e: Event) => {\n if (!relContainer.contains(e.target as Node)) {\n doClose();\n }\n };\n\n function doOpen() {\n dropdownOpen = true;\n dropdownList.style.display = \"block\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"true\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(180deg)\";\n relationshipDisplay.style.borderColor = accentColor;\n relationshipDisplay.style.boxShadow = `0 0 0 1px ${accentColor}`;\n\n // Determine direction: open upward if not enough space below\n const rect = relContainer.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const dropdownHeight = 220;\n const shouldOpenUpward = spaceBelow < dropdownHeight && rect.top > dropdownHeight;\n\n if (shouldOpenUpward) {\n dropdownList.style.top = \"auto\";\n dropdownList.style.bottom = \"calc(100% + 4px)\";\n dropdownList.style.boxShadow = \"0 -4px 12px rgba(0,0,0,0.1), 0 -1px 3px rgba(0,0,0,0.06)\";\n } else {\n dropdownList.style.top = \"calc(100% + 4px)\";\n dropdownList.style.bottom = \"auto\";\n dropdownList.style.boxShadow = \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\";\n }\n\n // Scroll the dropdown into view\n requestAnimationFrame(() => {\n dropdownList.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n });\n\n // Listen for clicks outside (next tick so current click doesn't trigger it)\n setTimeout(() => document.addEventListener(\"mousedown\", handleClickOutside), 0);\n }\n\n function doClose() {\n dropdownOpen = false;\n dropdownList.style.display = \"none\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"false\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(0deg)\";\n relationshipDisplay.style.borderColor = borderColor;\n relationshipDisplay.style.boxShadow = \"none\";\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n\n relationshipDisplay.addEventListener(\"click\", () => {\n dropdownOpen ? doClose() : doOpen();\n });\n\n relationshipDisplay.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!dropdownOpen) doOpen();\n } else if (e.key === \"Escape\" || e.key === \"Tab\") {\n doClose();\n }\n });\n\n const relationshipError = el(\"div\", { style: errorStyle, role: \"alert\" });\n\n relContainer.appendChild(relLabel);\n relContainer.appendChild(relationshipDisplay);\n relContainer.appendChild(dropdownList);\n relContainer.appendChild(relationshipError);\n\n // General error\n const generalError = el(\"div\", {\n role: \"alert\",\n style: {\n color: \"#DC2626\",\n fontSize: \"13px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n display: \"none\",\n },\n });\n\n const fieldsContainer = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"14px\" },\n }, nameGroup, contactGroup, relContainer);\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, overflow: \"visible\", color: textColor, fontFamily: font },\n }, subtitle, infoBanner, fieldsContainer, generalError);\n\n // ─── Bottom Section (Verify first, Cancel second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const submitBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n disabled: isSubmitting,\n \"aria-label\": isSubmitting ? \"Verifying guardian identity\" : \"Proceed to guardian verification\",\n onClick: onSubmit,\n }) as HTMLButtonElement;\n submitBtn.textContent = isSubmitting ? \"Verifying...\" : \"Verify via DigiLocker\";\n\n const cancelBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Cancel\",\n onClick: onCancel,\n });\n cancelBtn.textContent = \"Cancel\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, paddingTop: \"12px\", color: textColor, fontFamily: font },\n }, submitBtn, cancelBtn);\n\n // ─── Assemble ───\n const container = el(\"div\", { style: { ...styles.content, overflow: \"visible\" } }, topSection, middleSection, bottomSection);\n\n return {\n container,\n nameInput,\n contactInput,\n relationshipDisplay,\n nameError,\n contactError,\n relationshipError,\n submitBtn,\n generalError,\n };\n}\n\nexport function validateGuardianForm(data: GuardianFormData): Record<string, string> {\n const errors: Record<string, string> = {};\n if (!data.guardianName.trim()) errors.guardianName = \"Guardian name is required\";\n if (!data.guardianContact.trim()) errors.guardianContact = \"Guardian contact is required\";\n if (!data.guardianRelationship.trim()) errors.guardianRelationship = \"Relationship to guardian is required\";\n return errors;\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings, GuardianVerificationErrorCode } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type VerificationScreenRefs = {\n container: HTMLElement;\n};\n\nexport function getVerificationErrorMessage(\n errorCode: string | null,\n fallbackError: string | null\n): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"The guardian must be 18 years or older. Please provide details of a different guardian.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker verification could not be completed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"DigiLocker did not return an authorization code. Please try again.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please try again.\";\n default:\n return fallbackError || \"Verification failed. Please try again.\";\n }\n}\n\nexport function renderVerificationScreen(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isInitiating: boolean;\n isPolling: boolean;\n isComplete: boolean;\n isAutoTransitioning?: boolean;\n error: string | null;\n errorCode: string | null;\n canRetry: boolean;\n onContinue: () => void;\n onBack: (clearName?: boolean) => void;\n}): VerificationScreenRefs {\n const {\n settings, colors, isMobile, logoUrl,\n isInitiating, isPolling, isComplete, isAutoTransitioning,\n error, errorCode, canRetry,\n onContinue, onBack,\n } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"verification-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const middleSection = el(\"div\", {\n style: {\n ...styles.middleSection,\n color: textColor,\n fontFamily: font,\n textAlign: \"center\",\n },\n });\n\n if (isComplete && !error) {\n // Success state: green checkmark circle\n const successCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#D1FAE5\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n });\n const checkSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#059669\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n successCircle.appendChild(checkSvg);\n\n const successText = el(\"p\", {\n style: {\n color: headingColor,\n fontFamily: font,\n fontSize: \"16px\",\n fontWeight: 600,\n lineHeight: \"1.5\",\n marginTop: \"12px\",\n marginBottom: \"24px\",\n },\n });\n successText.textContent = \"Verification Completed\";\n\n const wrapper = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flex: \"1\",\n },\n }, successCircle, successText);\n middleSection.appendChild(wrapper);\n\n } else if ((isInitiating || isPolling) && !error) {\n // Polling state: spinner + status message\n const spinner = el(\"div\", {\n style: {\n width: \"48px\",\n height: \"48px\",\n border: \"4px solid #e5e7eb\",\n borderTopColor: accentColor,\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n margin: \"24px auto\",\n },\n });\n\n const statusMsg = el(\"div\", {\n style: {\n color: \"#059669\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #A7F3D0\",\n backgroundColor: \"#D1FAE5\",\n textAlign: \"center\",\n },\n });\n statusMsg.textContent = isInitiating\n ? \"Opening DigiLocker in a new tab...\"\n : \"Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete.\";\n\n middleSection.appendChild(spinner);\n middleSection.appendChild(statusMsg);\n }\n\n if (error) {\n // Error state: red X circle + error text\n const errorCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#fee2e2\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n margin: \"24px auto\",\n },\n });\n const xSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#dc2626\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"line\", { x1: \"18\", y1: \"6\", x2: \"6\", y2: \"18\" }),\n svg(\"line\", { x1: \"6\", y1: \"6\", x2: \"18\", y2: \"18\" })\n );\n errorCircle.appendChild(xSvg);\n\n const failedText = el(\"p\", {\n style: {\n ...styles.privacyText,\n color: textColor,\n fontFamily: font,\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n marginBottom: \"12px\",\n },\n });\n failedText.textContent = \"Verification failed\";\n\n const errorBox = el(\"div\", {\n style: {\n color: \"#DC2626\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n },\n });\n errorBox.textContent = error;\n\n middleSection.appendChild(errorCircle);\n middleSection.appendChild(failedText);\n middleSection.appendChild(errorBox);\n }\n\n // ─── Bottom Section ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const bottomSection = el(\"div\", {\n style: {\n ...styles.bottomSection,\n paddingTop: \"12px\",\n display: \"flex\",\n gap: \"12px\",\n justifyContent: \"center\",\n color: textColor,\n fontFamily: font,\n },\n });\n\n const acceptBtnStyle = {\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n };\n const declineBtnStyle = {\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n };\n\n // Hide bottom section during auto-transition\n if (!isAutoTransitioning) {\n if (isComplete && !error) {\n const continueBtn = el(\"button\", {\n style: { ...btnBase, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": \"Continue to consent form\",\n onClick: onContinue,\n });\n continueBtn.textContent = \"Continue\";\n bottomSection.appendChild(continueBtn);\n } else if (error && canRetry) {\n const retryBtn = el(\"button\", {\n style: { ...btnBase, ...styles.acceptButton, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": errorCode === \"GUARDIAN_UNDER_18\" ? \"Change guardian details\" : \"Try verification again\",\n onClick: () => onBack(errorCode === \"GUARDIAN_UNDER_18\"),\n });\n retryBtn.textContent = errorCode === \"GUARDIAN_UNDER_18\" ? \"Change Guardian\" : \"Try Again\";\n bottomSection.appendChild(retryBtn);\n } else if (error) {\n const goBackBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Go back\",\n onClick: () => onBack(false),\n });\n goBackBtn.textContent = \"Go Back\";\n bottomSection.appendChild(goBackBtn);\n } else {\n // Polling state — show cancel\n const cancelBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Cancel verification\",\n onClick: () => onBack(false),\n });\n cancelBtn.textContent = \"Cancel\";\n bottomSection.appendChild(cancelBtn);\n }\n }\n\n // ─── Assemble ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import type { ActiveConfig, Settings } from \"../api/types\";\n\nexport type ResolvedColors = {\n acceptBg: string;\n acceptText: string;\n declineBg: string;\n declineText: string;\n declineBorder: string;\n link: string;\n heading: string;\n text: string;\n font: string;\n borderRadius: string;\n primaryColor: string;\n secondaryColor: string;\n};\n\n/**\n * Resolves colors using the React SDK's fallback chain:\n * settings → API active_config → hardcoded default\n */\nexport function resolveColors(\n settings: Partial<Settings> | undefined,\n activeConfig: ActiveConfig | null | undefined\n): ResolvedColors {\n const primaryColor = activeConfig?.primary_color || \"#4f87ff\";\n const secondaryColor = activeConfig?.secondary_color || \"#4f87ff\";\n\n return {\n acceptBg: settings?.button?.accept?.backgroundColor || primaryColor,\n acceptText: settings?.button?.accept?.textColor || \"#ffffff\",\n declineBg: settings?.button?.decline?.backgroundColor || \"#ffffff\",\n declineText: settings?.button?.decline?.textColor || \"#000000\",\n declineBorder: settings?.borderColor || \"#d0d5dd\",\n link: settings?.link || secondaryColor,\n heading: settings?.headingColor || \"#323B4B\",\n text: settings?.textColor || \"#344054\",\n font: settings?.font || \"inherit\",\n borderRadius: settings?.borderRadius || \"8px\",\n primaryColor,\n secondaryColor,\n };\n}\n","import { Store } from \"../core/state\";\nimport { el, svg, clearElement } from \"../core/dom\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport {\n fetchConsentContent,\n submitConsentEvent,\n fetchTTSAudioUrls,\n initiateGuardianVerification,\n verifyGuardianStatus,\n} from \"../api\";\nimport {\n buildLedgerConsentOverlay,\n fetchNoticeConsentStatus,\n} from \"../api/notice-consent-status\";\nimport { clearApiCache } from \"../services/cache\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { styles } from \"../styles/modal\";\nimport { renderModalPurposes, type ModalPurposeRefs } from \"./purposes\";\nimport { renderLanguageSelector, type LanguageSelectorRefs } from \"./language-selector\";\nimport { setupKeyboardTrap, type KeyboardTrapCleanup } from \"./keyboard\";\nimport {\n saveConsentState,\n getConsentState,\n clearConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport { TTSManager } from \"./tts\";\nimport { renderAgeVerification } from \"./age-verification\";\nimport {\n renderGuardianForm,\n validateGuardianForm,\n type GuardianFormData,\n type GuardianFormRefs,\n} from \"./guardian-form\";\nimport {\n renderVerificationScreen,\n getVerificationErrorMessage,\n} from \"./verification-screen\";\nimport { resolveColors } from \"./colors\";\nimport type { ModalOptions } from \"../types\";\nimport type {\n ActiveConfig,\n ConsentContent,\n PurposeItemData,\n PurposeSelection,\n Settings,\n TranslationObject,\n} from \"../api/types\";\n\ntype ModalState = {\n isLoading: boolean;\n isSubmitting: boolean;\n isSubmittingAccept: boolean;\n isSubmittingDecline: boolean;\n content: ConsentContent | null;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n isFullyConsentedReviewMode: boolean;\n selectedLanguage: string;\n errorMessage: string | null;\n fetchError: Error | null;\n needsConsentPurposes: PurposeItemData[];\n alreadyConsentedPurposes: PurposeItemData[];\n // Age/Guardian flow\n isMinorFlow: boolean;\n selfDeclaredAdult: boolean;\n showAgeVerification: boolean;\n showGuardianForm: boolean;\n showVerificationScreen: boolean;\n verificationReference: string | null;\n isVerificationComplete: boolean;\n isInitiatingVerification: boolean;\n isPollingStatus: boolean;\n verificationError: string | null;\n verificationErrorCode: string | null;\n canRetryVerification: boolean;\n guardianFormData: GuardianFormData;\n};\n\nexport class ModalController {\n private store: Store<ModalState>;\n private options: ModalOptions;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private previousBodyOverflow: string | null = null;\n private previousHtmlOverflow: string | null = null;\n private overlayEl: HTMLElement | null = null;\n private modalEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: ModalPurposeRefs | null = null;\n private alreadyConsentedPurposeRefs: ModalPurposeRefs | null = null;\n private langSelectorRefs: LanguageSelectorRefs | null = null;\n private keyboardCleanup: KeyboardTrapCleanup | null = null;\n private abortController: AbortController | null = null;\n private unsubscribe: (() => void) | null = null;\n private ttsManager: TTSManager | null = null;\n private guardianFormRefs: GuardianFormRefs | null = null;\n private statusPollTimeout: ReturnType<typeof setTimeout> | null = null;\n private popupCheckInterval: ReturnType<typeof setInterval> | null = null;\n private verificationPopup: Window | null = null;\n private verificationSessionToken: string | null = null;\n private visibilityChangeHandler: (() => void) | null = null;\n\n // DOM refs for targeted updates\n private acceptBtn: HTMLButtonElement | null = null;\n private declineBtn: HTMLButtonElement | null = null;\n private middleSection: HTMLElement | null = null;\n private errorEl: HTMLElement | null = null;\n private noticeTitleEl: HTMLElement | null = null;\n private noticeTextEl: HTMLElement | null = null;\n private purposeHeadingEl: HTMLElement | null = null;\n private additionalTextEl: HTMLElement | null = null;\n private privacyPolicyLinkEl: HTMLAnchorElement | null = null;\n private privacyCenterLinkEl: HTMLAnchorElement | null = null;\n private ttsButton: HTMLElement | null = null;\n\n constructor(options: ModalOptions) {\n this.options = options;\n this.store = new Store<ModalState>({\n isLoading: true,\n isSubmitting: false,\n isSubmittingAccept: false,\n isSubmittingDecline: false,\n content: null,\n selectedPurposes: {},\n selectedDataElements: {},\n initialDataElementSelections: {},\n collapsedPurposes: {},\n hasAlreadyConsented: false,\n isFullyConsentedReviewMode: false,\n selectedLanguage: options.language || \"en\",\n errorMessage: null,\n fetchError: null,\n needsConsentPurposes: [],\n alreadyConsentedPurposes: [],\n isMinorFlow: false,\n selfDeclaredAdult: false,\n showAgeVerification: false,\n showGuardianForm: false,\n showVerificationScreen: false,\n verificationReference: null,\n isVerificationComplete: false,\n isInitiatingVerification: false,\n isPollingStatus: false,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n // TTSManager is instantiated lazily in renderOverlayWithLoading() once the\n // shadow root exists, so it can scope its DOM queries inside the shadow.\n }\n\n async init(): Promise<void> {\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderOverlayWithLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.keyboardCleanup?.();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.ttsManager?.destroy();\n this.stopPolling();\n this.store.destroy();\n\n // Removing the shadow host nukes the entire shadow tree (overlay, modal,\n // language dropdown, injected stylesheet) in a single operation.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n\n // Restore the host page's scroll lock to whatever it was before we opened.\n if (this.previousBodyOverflow !== null) {\n document.body.style.overflow = this.previousBodyOverflow;\n this.previousBodyOverflow = null;\n }\n if (this.previousHtmlOverflow !== null) {\n document.documentElement.style.overflow = this.previousHtmlOverflow;\n this.previousHtmlOverflow = null;\n }\n\n this.hostEl = null;\n this.shadowRoot = null;\n this.overlayEl = null;\n this.modalEl = null;\n this.purposeRefs = null;\n this.langSelectorRefs = null;\n }\n\n // ─── Private ───\n\n private async fetchNotice(): Promise<void> {\n this.abortController = new AbortController();\n this.store.setState({ isLoading: true, fetchError: null });\n\n try {\n const data = await fetchConsentContent({\n noticeId: this.options.noticeId,\n accessToken: this.options.accessToken,\n refreshToken: this.options.refreshToken,\n baseUrl: this.options.baseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n validate_against: this.options.validateAgainst || \"all\",\n include_fully_consented_data: this.options.includeFullyConsentedData,\n signal: this.abortController.signal,\n });\n\n const activeConfig = data.detail.active_config;\n\n // Overlay the prior-consent / reconsent state from the Go ledger's\n // check-consent. Consents live in the ledger post-cutover, so Python's\n // notice-validation overlay is empty; the notice text/config still comes\n // from Python (above). Falls back to the Python-provided values when the\n // ledger is unavailable, and is skipped for the magic-link flow\n // (applicationId), which pre-fills from a specific event.\n let purposeSelections = data.detail.purpose_selections;\n let reconsentRequired = data.detail.reconsent_required;\n let ledgerOverlayApplied = false;\n if (this.options.ledgerBaseUrl && !this.options.applicationId) {\n const ledgerStatus = await fetchNoticeConsentStatus({\n accessToken: this.options.accessToken,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: this.options.noticeId,\n signal: this.abortController.signal,\n });\n if (ledgerStatus) {\n const overlay = buildLedgerConsentOverlay(ledgerStatus, activeConfig.purposes);\n reconsentRequired = overlay?.reconsent_required ?? false;\n purposeSelections = overlay?.purpose_selections;\n ledgerOverlayApplied = Boolean(overlay);\n }\n }\n\n // Initialize state\n const initialCollapsed: Record<string, boolean> = {};\n const initialPurposes: Record<string, boolean> = {};\n const initialElements: Record<string, boolean> = {};\n const initialDataElementSelections: Record<string, boolean> = {};\n\n // Categorize purposes for reconsent. With a ledger overlay, categorize\n // whenever prior consent exists (even without reconsent needed) so a\n // fully-consented principal gets the already-consented presentation /\n // review mode instead of a fresh consent flow — the ledger-mode\n // equivalent of Python's 409-driven short-circuit.\n let needsConsentPurposes: PurposeItemData[] = [];\n let alreadyConsentedPurposes: PurposeItemData[] = [];\n let isFullyConsentedReviewMode = false;\n\n if (purposeSelections && (reconsentRequired || ledgerOverlayApplied)) {\n for (const purpose of activeConfig.purposes) {\n const selection = purposeSelections[purpose.uuid];\n initialCollapsed[purpose.uuid] = true;\n\n if (selection && selection.selected && !selection.needs_reconsent) {\n alreadyConsentedPurposes.push(purpose);\n initialPurposes[purpose.uuid] = true;\n for (const de of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${de.uuid}`;\n const deSelection = selection.data_elements?.[de.uuid];\n const wasSelected = deSelection?.selected || false;\n initialElements[combinedId] = wasSelected;\n initialDataElementSelections[combinedId] = wasSelected;\n }\n } else {\n needsConsentPurposes.push(purpose);\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n }\n } else {\n needsConsentPurposes = activeConfig.purposes;\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n }\n\n // Check if all purposes are already consented (review mode)\n if (\n this.options.includeFullyConsentedData &&\n needsConsentPurposes.length === 0 &&\n alreadyConsentedPurposes.length > 0\n ) {\n isFullyConsentedReviewMode = true;\n }\n\n // Determine language\n let selectedLanguage = this.options.language || \"en\";\n if (activeConfig.default_language) {\n selectedLanguage = activeConfig.default_language;\n }\n\n // Check if minor flow is required, and restore in-progress verification\n // state from a previous session (e.g. user closed the SDK or returned\n // from a DigiLocker redirect mid-flow). Without this restoration, the\n // notice would be shown directly and guardian verification skipped.\n let isMinorFlow = false;\n let showAgeVerification = false;\n let restoreState: Partial<ModalState> = {};\n let pollingTokenToResume: string | null = null;\n if (data.detail.is_minor) {\n isMinorFlow = true;\n const persistedState = getConsentState();\n\n // Discard persisted state from a different notice\n if (persistedState?.noticeId && persistedState.noticeId !== this.options.noticeId) {\n clearConsentState();\n } else if (\n persistedState?.flowState === \"digilocker-pending\" &&\n persistedState.sessionToken\n ) {\n // User is mid-verification — resume the verification screen and polling\n restoreState = {\n showVerificationScreen: true,\n isPollingStatus: true,\n };\n pollingTokenToResume = persistedState.sessionToken;\n } else if (\n persistedState?.verificationResult === \"verified\" &&\n persistedState.verificationReference\n ) {\n // Verification completed during a redirect — show success state\n restoreState = {\n showVerificationScreen: true,\n isVerificationComplete: true,\n verificationReference: persistedState.verificationReference,\n };\n clearConsentState();\n } else if (\n persistedState?.verificationResult === \"failed\" ||\n persistedState?.verificationResult === \"expired\"\n ) {\n // Verification failed/expired during a redirect — show error\n restoreState = {\n showVerificationScreen: true,\n verificationError:\n persistedState.verificationResult === \"expired\"\n ? \"Verification session has expired. Please try again.\"\n : \"Verification failed. Please try again.\",\n canRetryVerification: true,\n };\n clearConsentState();\n } else {\n // No in-progress verification — start with age verification\n showAgeVerification = true;\n }\n }\n\n this.store.setState({\n content: data,\n isLoading: false,\n selectedLanguage,\n collapsedPurposes: initialCollapsed,\n selectedPurposes: initialPurposes,\n selectedDataElements: initialElements,\n initialDataElementSelections,\n needsConsentPurposes,\n alreadyConsentedPurposes,\n isFullyConsentedReviewMode,\n isMinorFlow,\n showAgeVerification,\n ...restoreState,\n });\n\n // Resume polling after state has been applied so the verification screen\n // is visible while polling runs.\n if (pollingTokenToResume) {\n this.startStatusPolling(pollingTokenToResume);\n }\n } catch (err: unknown) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private handleStateChange(state: ModalState, prevState: ModalState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n return;\n }\n\n // Already consented → close\n if (state.hasAlreadyConsented && !prevState.hasAlreadyConsented) {\n this.destroy();\n return;\n }\n\n // Fetch error → show error\n if (state.fetchError && !prevState.fetchError) {\n this.renderError(state.fetchError.message);\n return;\n }\n\n // Screen transitions (age → guardian → verification → consent)\n if (state.showAgeVerification !== prevState.showAgeVerification ||\n state.showGuardianForm !== prevState.showGuardianForm ||\n state.showVerificationScreen !== prevState.showVerificationScreen) {\n this.rebuildUI();\n return;\n }\n\n // Verification screen state changes\n if (state.showVerificationScreen && (\n state.isVerificationComplete !== prevState.isVerificationComplete ||\n state.verificationError !== prevState.verificationError ||\n state.isPollingStatus !== prevState.isPollingStatus ||\n state.isInitiatingVerification !== prevState.isInitiatingVerification)) {\n this.rebuildUI();\n return;\n }\n\n // Checkbox changes\n if (\n state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements\n ) {\n this.updateCheckboxes(state);\n }\n\n // Collapse changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n\n // Submitting state\n if (state.isSubmittingAccept !== prevState.isSubmittingAccept ||\n state.isSubmittingDecline !== prevState.isSubmittingDecline) {\n this.updateButtonStates(state);\n }\n }\n\n private renderOverlayWithLoading(): void {\n // Mount a single host <div> on document.body and attach an open shadow\n // root. All overlay, modal, and stylesheet content lives inside the shadow\n // so the host page's CSS cannot bleed in (and vice versa). This is what\n // makes the SDK render identically across customer sites and WordPress\n // installs that ship aggressive global stylesheets / accessibility plugins.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent\", \"\");\n // Lock the host to a zero-size, fixed-position box so it cannot perturb a\n // flex / grid body layout. We deliberately DO NOT reset inherited text\n // properties (font-family, color, line-height) — those flow through the\n // shadow boundary so the modal picks up the host page's font, matching\n // how the React SDK renders.\n this.hostEl.style.position = \"fixed\";\n this.hostEl.style.top = \"0\";\n this.hostEl.style.left = \"0\";\n this.hostEl.style.width = \"0\";\n this.hostEl.style.height = \"0\";\n this.hostEl.style.zIndex = \"2147483646\";\n document.body.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n\n // Lock background scroll on the host page while the modal is open. We\n // capture the previous values so destroy() can restore exactly what was\n // there (including the empty string, which means \"use stylesheet rule\").\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n\n // Inject SDK stylesheet into the shadow root (not document.head).\n injectCheckboxStyles(this.shadowRoot);\n\n // Lazy-instantiate TTSManager now that we have a root for it to query.\n this.ttsManager = new TTSManager(\n () => this.updateTTSButton(),\n this.shadowRoot\n );\n\n const blockUI = this.options.blockUI !== false;\n\n if (blockUI) {\n this.overlayEl = el(\"div\", {\n style: styles.overlay,\n role: \"presentation\",\n });\n this.shadowRoot.appendChild(this.overlayEl);\n }\n\n const settingsObj = this.options.settings;\n const modalStyle = { ...styles.modal } as Record<string, any>;\n if (settingsObj?.backgroundColor) modalStyle.backgroundColor = settingsObj.backgroundColor;\n if (settingsObj?.borderRadius) modalStyle.borderRadius = settingsObj.borderRadius;\n if (settingsObj?.borderColor) modalStyle.border = `1px solid ${settingsObj.borderColor}`;\n if (settingsObj?.font) modalStyle.fontFamily = settingsObj.font;\n if (this.mediaQuery.matches) {\n modalStyle.width = \"90%\";\n modalStyle.maxWidth = \"90%\";\n }\n\n this.modalEl = el(\"div\", {\n style: modalStyle,\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"aria-label\": \"Privacy consent\",\n });\n\n // Loading content\n const loadingEl = el(\n \"div\",\n { style: styles.loadingContainer },\n el(\"div\", { style: styles.loadingSpinner }),\n el(\"p\", { style: { ...styles.privacyText, color: settingsObj?.textColor || \"#344054\" } }, \"Loading...\")\n );\n\n const contentEl = el(\"div\", { style: styles.content }, loadingEl);\n this.modalEl.appendChild(contentEl);\n this.shadowRoot.appendChild(this.modalEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.modalEl) return;\n\n const activeConfig = state.content.detail.active_config;\n const settingsObj = this.options.settings;\n const isMobile = this.mediaQuery.matches;\n const colors = resolveColors(settingsObj, activeConfig);\n\n // ─── Age Verification Screen ───\n if (state.showAgeVerification) {\n clearElement(this.modalEl);\n const ageRefs = renderAgeVerification({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n onYes: () => this.handleAgeVerificationYes(),\n onNo: () => this.handleAgeVerificationNo(),\n onClose: () => this.handleDecline(),\n });\n this.modalEl.appendChild(ageRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Guardian Form Screen ───\n if (state.showGuardianForm) {\n clearElement(this.modalEl);\n this.guardianFormRefs = renderGuardianForm({\n formData: state.guardianFormData,\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isSubmitting: state.isInitiatingVerification,\n onSubmit: () => this.handleGuardianFormSubmit(),\n onCancel: () => this.handleDecline(),\n onFieldChange: (field, value) => {\n const s = this.store.getState();\n this.store.setState({\n guardianFormData: { ...s.guardianFormData, [field]: value },\n });\n },\n });\n this.modalEl.appendChild(this.guardianFormRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Verification Screen ───\n if (state.showVerificationScreen) {\n clearElement(this.modalEl);\n const verRefs = renderVerificationScreen({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isInitiating: state.isInitiatingVerification,\n isPolling: state.isPollingStatus,\n isComplete: state.isVerificationComplete,\n error: state.verificationError,\n errorCode: state.verificationErrorCode,\n canRetry: state.canRetryVerification,\n onContinue: () => this.handleVerificationContinue(),\n onBack: (clearName?: boolean) => {\n if (clearName) {\n this.handleChangeGuardian();\n } else if (state.verificationError && state.canRetryVerification) {\n this.handleVerificationRetry();\n } else {\n this.handleDecline();\n }\n },\n });\n this.modalEl.appendChild(verRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => {});\n return;\n }\n\n // Clear modal content\n clearElement(this.modalEl);\n\n const headingColor = settingsObj?.headingColor || \"#101828\";\n const textColor = colors.text;\n const linkColor = colors.link;\n const font = colors.font;\n\n // ─── Top Section ───\n const logoImg = activeConfig.logo_url\n ? el(\"img\", {\n src: activeConfig.logo_url,\n style: {\n ...styles.logo,\n maxWidth: isMobile ? \"96px\" : \"140px\",\n maxHeight: isMobile ? \"28px\" : \"32px\",\n },\n alt: \"Logo\",\n })\n : null;\n\n this.noticeTitleEl = el(\"span\", {\n id: \"privacy-notice-title\",\n style: { ...styles.title, color: headingColor, fontFamily: font, fontSize: isMobile ? \"16px\" : \"18px\" },\n });\n this.noticeTitleEl.textContent = this.getTranslatedText(\"notice_banner_heading\", activeConfig.notice_banner_heading);\n\n // Clean up previous language dropdown (since rebuildUI re-creates it).\n // The dropdown lives inside the shadow root (sibling of the modal) so we\n // remove it from there.\n if (\n this.langSelectorRefs?.dropdown &&\n this.shadowRoot &&\n this.langSelectorRefs.dropdown.parentNode === this.shadowRoot\n ) {\n this.shadowRoot.removeChild(this.langSelectorRefs.dropdown);\n }\n\n // Language selector\n const supportedLangs = Object.keys(activeConfig.supported_languages_and_translations || {});\n const allLanguages = [activeConfig.default_language || \"English\", ...supportedLangs.filter((l) => l !== activeConfig.default_language)];\n\n this.langSelectorRefs = renderLanguageSelector({\n languages: allLanguages,\n selectedLanguage: state.selectedLanguage,\n settings: settingsObj,\n onSelect: (lang) => this.handleLanguageSelect(lang),\n dropdownContainer: this.shadowRoot!,\n });\n\n // TTS button with SVG speaker icon (matches React)\n const ttsStrokeColor = settingsObj?.button?.language?.textColor || \"currentColor\";\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: ttsStrokeColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n\n this.ttsButton = el(\"button\", {\n style: {\n ...styles.topRight,\n display: \"none\",\n padding: \"3px 9px\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Start audio playback\",\n title: \"Start Talkback\",\n onClick: () => this.ttsManager?.toggle(),\n });\n this.ttsButton.appendChild(speakerSvg);\n\n // Fetch TTS audio (the API uses \"English\" for English, not \"en\")\n this.ttsManager?.fetchAudioUrls({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n noticeUuid: activeConfig.notice_uuid,\n language: this.getLanguageCode(state.selectedLanguage),\n content: activeConfig,\n });\n\n // TTS button on LEFT, language selector on RIGHT (matches React)\n const topRight = el(\"div\", {\n style: { display: \"flex\", alignItems: \"center\", gap: \"8px\", flexShrink: 0 },\n }, this.ttsButton, this.langSelectorRefs.container);\n\n let topSection: HTMLElement;\n if (isMobile) {\n // Mobile: logo + controls share row 1; title takes full row 2.\n const headerRow = el(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n width: \"100%\",\n },\n },\n ...(logoImg ? [logoImg] : []),\n el(\n \"div\",\n { style: { marginLeft: \"auto\", display: \"flex\", alignItems: \"center\" } },\n topRight\n )\n );\n topSection = el(\n \"div\",\n {\n style: {\n ...styles.topSection,\n flexDirection: \"column\",\n alignItems: \"stretch\",\n flexWrap: \"nowrap\",\n },\n },\n headerRow,\n this.noticeTitleEl\n );\n } else {\n const topLeft = el(\"div\", { style: styles.topLeft }, logoImg, this.noticeTitleEl);\n topSection = el(\"div\", { style: styles.topSection }, topLeft, topRight);\n }\n\n // ─── Middle Section ───\n this.middleSection = el(\"div\", { style: styles.middleSection });\n\n const baseTextStyle = { ...styles.privacyText, color: textColor, fontFamily: font, fontSize: isMobile ? \"14px\" : \"16px\" };\n\n // Notice text + Privacy policy in ONE <p> (matches React: single <p> with <br>)\n const noticeTextSpan = el(\"span\", { id: \"privacy-notice-text\" });\n noticeTextSpan.textContent = this.getTranslatedText(\"notice_text\", activeConfig.notice_text);\n\n const policyPrefixText = this.getTranslatedText(\"privacy_policy_prefix_text\", activeConfig.privacy_policy_prefix_text);\n const policyAnchorText = this.getTranslatedText(\"privacy_policy_anchor_text\", activeConfig.privacy_policy_anchor_text);\n\n this.privacyPolicyLinkEl = el(\"a\", {\n id: \"privacy-policy-link\",\n href: activeConfig.privacy_policy_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n \"aria-label\": \"Privacy Policy (opens in new tab)\",\n }) as HTMLAnchorElement;\n this.privacyPolicyLinkEl.textContent = policyAnchorText;\n\n const policySpan = el(\"span\", { id: \"privacy-policy-text\" },\n `${policyPrefixText} `,\n this.privacyPolicyLinkEl\n );\n\n const noticeAndPolicyP = el(\"p\", { style: baseTextStyle },\n noticeTextSpan,\n el(\"br\"),\n policySpan\n );\n\n // Purpose section heading\n this.purposeHeadingEl = el(\"h2\", {\n id: \"purpose-section-heading\",\n style: { ...styles.subTitle, color: headingColor, fontFamily: font },\n });\n this.purposeHeadingEl.textContent = this.getTranslatedText(\"purpose_section_heading\", activeConfig.purpose_section_heading);\n\n this.middleSection.appendChild(noticeAndPolicyP);\n this.middleSection.appendChild(this.purposeHeadingEl);\n\n // Render purposes (needs consent)\n if (state.needsConsentPurposes.length > 0) {\n this.purposeRefs = renderModalPurposes(state.needsConsentPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: false,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (euuid, puuid) => this.handleDataElementCheckboxChange(euuid, puuid),\n });\n this.middleSection.appendChild(this.purposeRefs.container);\n }\n\n // Render already-consented purposes\n if (state.alreadyConsentedPurposes.length > 0) {\n this.alreadyConsentedPurposeRefs = renderModalPurposes(state.alreadyConsentedPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n initialDataElementSelections: state.initialDataElementSelections,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: true,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: () => {},\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: () => {},\n });\n this.middleSection.appendChild(this.alreadyConsentedPurposeRefs.container);\n }\n\n // Additional text + Privacy Center + DPO Info in ONE block (matches React layout)\n if (activeConfig.privacy_center_url || activeConfig.dpo_info) {\n const footerDiv = el(\"div\", {\n style: {\n ...baseTextStyle,\n fontSize: isMobile ? \"13px\" : \"14px\",\n lineHeight: \"1.4\",\n borderTop: \"1px solid rgba(152, 162, 179, 0.3)\",\n paddingTop: \"12px\",\n marginTop: \"12px\",\n },\n });\n\n const footerP = el(\"p\", { style: { margin: \"0\", opacity: \"0.6\" } });\n\n // Privacy Center section: \"additional_text Privacy Center.\"\n if (activeConfig.privacy_center_url) {\n if (activeConfig.additional_text) {\n const addlSpan = el(\"span\", { id: \"additional-text\" });\n addlSpan.textContent = this.getTranslatedText(\"additional_text\", activeConfig.additional_text);\n footerP.appendChild(addlSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n }\n\n const pcAnchorText = this.getTranslatedText(\"privacy_center_anchor_text\", activeConfig.privacy_center_anchor_text || \"Privacy Center\");\n this.privacyCenterLinkEl = el(\"a\", {\n id: \"privacy-center-link\",\n href: activeConfig.privacy_center_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n }) as HTMLAnchorElement;\n this.privacyCenterLinkEl.textContent = pcAnchorText;\n footerP.appendChild(this.privacyCenterLinkEl);\n footerP.appendChild(document.createTextNode(\".\"));\n }\n\n // DPO Info section (all inline with <br> separators, matching React)\n if (activeConfig.dpo_info) {\n const dpo = activeConfig.dpo_info;\n\n if (activeConfig.privacy_center_url) {\n footerP.appendChild(el(\"br\"));\n }\n\n // Grievance line\n if (dpo.grievance_text) {\n const gText = el(\"span\", { id: \"dpo-grievance-text\" });\n gText.textContent = this.getTranslatedDpoText(\"grievance_text\", dpo.grievance_text);\n footerP.appendChild(gText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.grievance_url) {\n const gLink = el(\"a\", {\n id: \"dpo-grievance-link\",\n href: dpo.grievance_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n gLink.textContent = this.getTranslatedDpoText(\"grievance_anchor_text\", dpo.grievance_anchor_text);\n footerP.appendChild(gLink);\n }\n\n if (dpo.grievance_email) {\n footerP.appendChild(document.createTextNode(\" \"));\n const connectorSpan = el(\"span\", { id: \"dpo-grievance-email-connector\" });\n connectorSpan.textContent = this.getTranslatedDpoText(\n \"grievance_email_connector_text\",\n dpo.grievance_email_connector_text || \"or email to\"\n );\n footerP.appendChild(connectorSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n const emailLink = el(\"a\", {\n id: \"dpo-grievance-email\",\n href: `mailto:${dpo.grievance_email}`,\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n emailLink.textContent = dpo.grievance_email;\n footerP.appendChild(emailLink);\n }\n }\n\n // DP Board line\n if (dpo.dp_board_text) {\n footerP.appendChild(el(\"br\"));\n const dpText = el(\"span\", { id: \"dpo-dp-board-text\" });\n dpText.textContent = this.getTranslatedDpoText(\"dp_board_text\", dpo.dp_board_text);\n footerP.appendChild(dpText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dp_board_url) {\n const dpLink = el(\"a\", {\n id: \"dpo-dp-board-link\",\n href: dpo.dp_board_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpLink.textContent = this.getTranslatedDpoText(\"dp_board_anchor_text\", dpo.dp_board_anchor_text);\n footerP.appendChild(dpLink);\n }\n }\n\n // DPO line\n if (dpo.dpo_text) {\n footerP.appendChild(el(\"br\"));\n const dpoTextSpan = el(\"span\", { id: \"dpo-dpo-text\" });\n dpoTextSpan.textContent = this.getTranslatedDpoText(\"dpo_text\", dpo.dpo_text);\n footerP.appendChild(dpoTextSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dpo_url) {\n const dpoLink = el(\"a\", {\n id: \"dpo-dpo-link\",\n href: dpo.dpo_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpoLink.textContent = this.getTranslatedDpoText(\"dpo_anchor_text\", dpo.dpo_anchor_text);\n footerP.appendChild(dpoLink);\n }\n }\n }\n\n footerDiv.appendChild(footerP);\n this.middleSection.appendChild(footerDiv);\n }\n\n // Error message\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: \"none\",\n },\n });\n\n // ─── Bottom Section: Accept FIRST, then Decline (matches React) ───\n const acceptBtnText = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\"confirm_button_text\", activeConfig.confirm_button_text);\n\n const acceptStyle: Record<string, any> = {\n ...styles.button,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n this.acceptBtn = el(\"button\", {\n id: \"confirm-button-text\",\n style: acceptStyle,\n type: \"button\",\n onClick: () => this.handleAccept(),\n }) as HTMLButtonElement;\n this.acceptBtn.textContent = acceptBtnText;\n\n const declineBtnText = this.getTranslatedText(\"decline_button_text\", activeConfig.decline_button_text);\n const declineStyle: Record<string, any> = {\n ...styles.button,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n this.declineBtn = el(\"button\", {\n id: \"decline-button-text\",\n style: declineStyle,\n type: \"button\",\n onClick: () => this.handleDecline(),\n }) as HTMLButtonElement;\n\n if (!state.isFullyConsentedReviewMode) {\n this.declineBtn.textContent = declineBtnText;\n }\n\n const bottomSection = el(\"div\", { style: styles.bottomSection });\n if (!state.isFullyConsentedReviewMode) {\n // React order: Accept first, Decline second\n bottomSection.appendChild(this.acceptBtn);\n bottomSection.appendChild(this.declineBtn);\n } else {\n bottomSection.appendChild(this.acceptBtn);\n }\n\n // Assemble modal\n const contentWrapper = el(\n \"div\",\n { style: styles.content },\n topSection,\n this.errorEl,\n this.middleSection,\n bottomSection\n );\n\n this.modalEl.appendChild(contentWrapper);\n\n // Set initial accept button disabled state\n this.updateAcceptButtonState(state);\n\n // Setup keyboard trap\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n }\n\n private getLanguageCode(displayLanguage: string): string {\n const content = this.store.getState().content?.detail.active_config;\n if (!content) return \"English\";\n\n // English maps to \"English\" for audio API\n if (displayLanguage === \"English\" || displayLanguage === \"en\" || displayLanguage === \"EN\") {\n return \"English\";\n }\n\n // If display language exists in translations, use it directly\n if (content.supported_languages_and_translations?.[displayLanguage]) {\n return displayLanguage;\n }\n\n // Fallback to default language or English\n return content.default_language === \"en\" || content.default_language === \"EN\"\n ? \"English\"\n : content.default_language || \"English\";\n }\n\n private getTranslatedDpoText(key: string, defaultText: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") return defaultText;\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang];\n if (!translationMap?.dpo_info) return defaultText;\n\n const value = (translationMap.dpo_info as any)[key];\n return typeof value === \"string\" && value ? value : defaultText;\n }\n\n private renderError(message: string): void {\n if (!this.modalEl) return;\n\n clearElement(this.modalEl);\n\n const errorContent = el(\n \"div\",\n { style: { ...styles.content, alignItems: \"center\", justifyContent: \"center\" } },\n el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n },\n }, message)\n );\n\n this.modalEl.appendChild(errorContent);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private handleLanguageSelect(lang: string): void {\n this.store.setState({ selectedLanguage: lang });\n // Rebuild UI to update all translations\n this.rebuildUI();\n }\n\n private togglePurposeCollapse(purposeUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [purposeUuid]: !state.collapsedPurposes[purposeUuid],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const newPurposeState = !state.selectedPurposes[purposeUuid];\n const updatedElements = { ...state.selectedDataElements };\n for (const de of purpose.data_elements) {\n updatedElements[`${purposeUuid}-${de.uuid}`] = newPurposeState;\n }\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: newPurposeState },\n selectedDataElements: updatedElements,\n });\n }\n\n private handleDataElementCheckboxChange(elementUuid: string, purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const combinedId = `${purposeUuid}-${elementUuid}`;\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: !state.selectedDataElements[combinedId],\n };\n\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n let shouldCheckPurpose: boolean;\n\n if (requiredElements.length > 0) {\n shouldCheckPurpose = requiredElements.every(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n } else {\n shouldCheckPurpose = purpose.data_elements.some(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n }\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: shouldCheckPurpose },\n });\n }\n\n private async handleAccept(): Promise<void> {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Review mode — just close\n if (state.isFullyConsentedReviewMode) {\n this.options.onAccept();\n this.destroy();\n return;\n }\n\n // Block submission for minors who have not completed guardian verification\n if (state.isMinorFlow && !state.verificationReference && !state.selfDeclaredAdult) {\n this.store.setState({\n errorMessage: \"Guardian verification is required before consent can be submitted.\",\n });\n return;\n }\n\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n this.abortController = new AbortController();\n this.store.setState({ isSubmitting: true, isSubmittingAccept: true, errorMessage: null });\n\n try {\n const purposes = content.purposes.map((purpose) => {\n const dataElements = purpose.data_elements\n .filter((de) => de.enabled)\n .map((de) => ({\n uuid: de.uuid,\n name: de.name,\n enabled: de.enabled,\n required: de.required,\n selected: state.selectedDataElements[`${purpose.uuid}-${de.uuid}`] || false,\n }));\n\n return {\n uuid: purpose.uuid,\n name: purpose.name,\n description: purpose.description,\n selected: state.selectedPurposes[purpose.uuid] || false,\n data_elements: dataElements,\n };\n });\n\n await submitConsentEvent({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: state.content!.detail.uuid,\n purposes,\n declined: false,\n meta_data: this.options.applicationId ? { specific_uuid: this.options.applicationId } : undefined,\n guardianVerificationReference: state.verificationReference || undefined,\n selfDeclaredAdult: state.selfDeclaredAdult || undefined,\n signal: this.abortController.signal,\n });\n\n this.options.onAccept();\n this.destroy();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n const message = error.status === 409\n ? \"You have already provided consent.\"\n : error.status && error.status >= 500\n ? \"Server error: Please try again later.\"\n : error.message || \"Failed to submit consent.\";\n this.store.setState({ errorMessage: message, isSubmitting: false, isSubmittingAccept: false });\n this.options.onError?.(error);\n }\n }\n\n private handleDecline(): void {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Stop any in-flight verification polling and clear the persisted\n // DigiLocker session so the next open starts the flow from scratch\n // (age verification → guardian form → verification screen).\n this.stopPolling();\n clearConsentState();\n\n this.options.onDecline();\n this.destroy();\n }\n\n private updateCheckboxes(state: ModalState): void {\n if (this.purposeRefs) {\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n // Update accept button disabled state\n this.updateAcceptButtonState(state);\n }\n\n private areAllRequiredChecked(state: ModalState): boolean {\n const content = state.content?.detail.active_config;\n if (!content?.purposes?.length) return false;\n\n return content.purposes.every((purpose) => {\n const requiredElements = purpose.data_elements.filter((de) => de.required && de.enabled);\n if (requiredElements.length === 0) return true;\n return requiredElements.every(\n (de) => state.selectedDataElements[`${purpose.uuid}-${de.uuid}`]\n );\n });\n }\n\n private updateAcceptButtonState(state: ModalState): void {\n if (!this.acceptBtn || state.isFullyConsentedReviewMode) return;\n\n const allRequiredChecked = this.areAllRequiredChecked(state);\n const disabled = !allRequiredChecked || state.isSubmittingAccept || state.isSubmittingDecline;\n\n this.acceptBtn.disabled = disabled;\n this.acceptBtn.style.opacity = disabled ? \"0.5\" : \"1\";\n this.acceptBtn.style.cursor = disabled ? \"not-allowed\" : \"pointer\";\n }\n\n private updateCollapseState(state: ModalState): void {\n const updateRefs = (refs: ModalPurposeRefs | null) => {\n if (!refs) return;\n for (const [purposeUuid, container] of refs.dataElementContainers) {\n const content = state.content?.detail.active_config;\n const purpose = content?.purposes.find((p) => p.uuid === purposeUuid);\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = refs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed ? \"rotate(90deg)\" : \"rotate(0deg)\";\n }\n\n const collapseBtn = refs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n };\n\n updateRefs(this.purposeRefs);\n updateRefs(this.alreadyConsentedPurposeRefs);\n }\n\n private updateErrorMessage(state: ModalState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n // ─── Age Verification Handlers ───\n\n private handleAgeVerificationYes(): void {\n this.store.setState({\n isMinorFlow: false,\n selfDeclaredAdult: true,\n showAgeVerification: false,\n });\n }\n\n private handleAgeVerificationNo(): void {\n this.store.setState({\n showAgeVerification: false,\n showGuardianForm: true,\n });\n }\n\n // ─── Guardian Form Handlers ───\n\n private async handleGuardianFormSubmit(): Promise<void> {\n const state = this.store.getState();\n const errors = validateGuardianForm(state.guardianFormData);\n if (Object.keys(errors).length > 0) {\n if (this.guardianFormRefs) {\n if (errors.guardianName) {\n this.guardianFormRefs.nameError.textContent = errors.guardianName;\n this.guardianFormRefs.nameError.style.display = \"block\";\n }\n if (errors.guardianContact) {\n this.guardianFormRefs.contactError.textContent = errors.guardianContact;\n this.guardianFormRefs.contactError.style.display = \"block\";\n }\n if (errors.guardianRelationship) {\n this.guardianFormRefs.relationshipError.textContent = errors.guardianRelationship;\n this.guardianFormRefs.relationshipError.style.display = \"block\";\n }\n }\n return;\n }\n\n this.store.setState({ isInitiatingVerification: true });\n\n const digilockerMode = this.options.digilockerMode || \"redirect\";\n const callbackUrl = digilockerMode === \"popup\"\n ? new URL(this.options.digilockerCallbackUrl || \"/digilocker-callback\", window.location.origin).href\n : undefined;\n\n try {\n const response = await initiateGuardianVerification({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n guardianName: state.guardianFormData.guardianName,\n guardianContact: state.guardianFormData.guardianContact,\n guardianRelationship: state.guardianFormData.guardianRelationship,\n frontendCallbackUrl: callbackUrl,\n });\n\n if (response.already_verified && response.verification_reference) {\n this.store.setState({\n verificationReference: response.verification_reference,\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: false,\n isVerificationComplete: true,\n });\n // Auto-transition to consent form after 1s\n setTimeout(() => {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }, 1000);\n return;\n }\n\n // Save state for redirect flow\n saveConsentState({\n flowState: \"digilocker-pending\",\n sessionToken: response.session_token,\n guardianInfoUuid: response.guardian_info_uuid,\n selectedPurposes: state.selectedPurposes,\n selectedDataElements: state.selectedDataElements,\n timestamp: new Date().toISOString(),\n originalUrl: window.location.href,\n noticeId: this.options.noticeId,\n baseUrl: this.options.baseUrl,\n });\n\n // Show verification screen with \"Opening DigiLocker...\" state\n this.store.setState({\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: true,\n isPollingStatus: false,\n });\n\n if (digilockerMode === \"popup\" && response.digilocker_redirect_url) {\n const popup = window.open(\n response.digilocker_redirect_url,\n \"digilocker_verification\",\n \"width=600,height=700,scrollbars=yes,resizable=yes\"\n );\n if (popup) {\n this.verificationPopup = popup;\n this.startPopupMonitoring(popup);\n } else {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Popup blocked. Please allow popups for this site.\",\n canRetryVerification: true,\n });\n return;\n }\n } else if (response.digilocker_redirect_url) {\n const openedWindow = window.open(response.digilocker_redirect_url, \"_blank\");\n if (!openedWindow) {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Unable to open DigiLocker. Please allow popups.\",\n canRetryVerification: true,\n });\n return;\n }\n try { openedWindow.opener = null; } catch {}\n }\n\n // Switch to polling state (spinner + \"Please complete verification...\" message)\n this.store.setState({\n isInitiatingVerification: false,\n isPollingStatus: true,\n });\n this.startStatusPolling(response.session_token!);\n } catch (error) {\n this.store.setState({ isInitiatingVerification: false });\n const err = error as Error & { status?: number };\n if (this.guardianFormRefs) {\n this.guardianFormRefs.generalError.textContent = err.message || \"Failed to initiate verification.\";\n this.guardianFormRefs.generalError.style.display = \"block\";\n }\n }\n }\n\n // ─── Verification Polling ───\n\n private startStatusPolling(token: string): void {\n this.verificationSessionToken = token;\n let attempts = 0;\n let consecutiveErrors = 0;\n let paused = false;\n const MAX_ATTEMPTS = 40;\n const MAX_CONSECUTIVE_ERRORS = 3;\n const POLL_INTERVAL = 3000;\n\n const poll = async () => {\n if (paused) return;\n attempts++;\n\n if (attempts > MAX_ATTEMPTS) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification is taking longer than expected. Please try again.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n try {\n const response = await verifyGuardianStatus({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n sessionToken: token,\n });\n\n consecutiveErrors = 0;\n\n if (response.status === \"verified\") {\n this.stopPolling();\n const ref = response.verification_reference || response.guardian_details?.verification_reference;\n if (!ref) {\n this.store.setState({\n verificationError: \"Verification completed but no reference received. Please try again.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n this.store.setState({\n verificationReference: ref,\n isVerificationComplete: true,\n isPollingStatus: false,\n });\n clearConsentState();\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n this.stopPolling();\n this.store.setState({\n verificationError: getVerificationErrorMessage(response.error_code, response.error),\n verificationErrorCode: response.error_code,\n canRetryVerification: response.can_retry,\n isPollingStatus: false,\n });\n return;\n }\n\n if (!paused) {\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n } catch (error) {\n const err = error as Error & { status?: number };\n if (err.status === 404 || err.status === 410) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification session not found or expired.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n consecutiveErrors++;\n if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {\n this.stopPolling();\n this.store.setState({\n verificationError: err.message || \"Unable to check verification status.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n };\n\n // Pause when tab hidden, resume on return\n this.visibilityChangeHandler = () => {\n if (document.hidden) {\n paused = true;\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n } else {\n paused = false;\n poll();\n }\n };\n document.addEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n\n private stopPolling(): void {\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n if (this.visibilityChangeHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n this.verificationPopup?.close();\n this.verificationPopup = null;\n }\n\n private startPopupMonitoring(popup: Window): void {\n this.popupCheckInterval = setInterval(() => {\n if (popup.closed) {\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n }\n }, 500);\n }\n\n // ─── Verification Screen Handlers ───\n\n private handleVerificationContinue(): void {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }\n\n private handleVerificationRetry(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n });\n }\n\n private handleChangeGuardian(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n }\n\n // ─── TTS ───\n\n private updateTTSButton(): void {\n if (!this.ttsButton || !this.ttsManager) return;\n\n // When the current language has no TTS audio (e.g. Santali in some\n // configs), hide the speaker icon entirely. Without this branch the\n // button would keep whatever display value it had from the previous\n // language and clicking it would replay the previous language's audio.\n if (!this.ttsManager.isAvailable) {\n this.ttsButton.style.display = \"none\";\n return;\n }\n\n this.ttsButton.style.display = \"flex\";\n\n // Swap SVG: speaker icon vs pause icon\n clearElement(this.ttsButton);\n const strokeColor = this.options.settings?.button?.language?.textColor || \"currentColor\";\n\n if (this.ttsManager.isPlaying) {\n // Pause icon\n const pauseSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\" }),\n svg(\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\" })\n );\n this.ttsButton.appendChild(pauseSvg);\n this.ttsButton.setAttribute(\"aria-label\", \"Pause audio playback\");\n this.ttsButton.setAttribute(\"title\", \"Pause Talkback\");\n } else {\n // Speaker icon\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n this.ttsButton.appendChild(speakerSvg);\n this.ttsButton.setAttribute(\"aria-label\", this.ttsManager.isPaused ? \"Resume audio playback\" : \"Start audio playback\");\n this.ttsButton.setAttribute(\"title\", this.ttsManager.isPaused ? \"Resume Talkback\" : \"Start Talkback\");\n }\n }\n\n private updateButtonStates(state: ModalState): void {\n if (this.acceptBtn) {\n if (state.isSubmittingAccept) {\n this.acceptBtn.textContent = \"Submitting...\";\n this.acceptBtn.disabled = true;\n this.acceptBtn.style.opacity = \"0.7\";\n this.acceptBtn.style.cursor = \"not-allowed\";\n } else {\n const content = state.content?.detail.active_config;\n this.acceptBtn.textContent = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\"confirm_button_text\", content?.confirm_button_text || \"Accept\");\n this.acceptBtn.disabled = false;\n this.acceptBtn.style.opacity = \"1\";\n this.acceptBtn.style.cursor = \"pointer\";\n }\n }\n\n if (this.declineBtn) {\n this.declineBtn.disabled = state.isSubmitting;\n this.declineBtn.style.opacity = state.isSubmitting ? \"0.7\" : \"1\";\n this.declineBtn.style.cursor = state.isSubmitting ? \"not-allowed\" : \"pointer\";\n }\n }\n}\n","export const inlineStyles = {\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { inlineStyles } from \"../styles/inline\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\n\nexport type PurposeRenderRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>; // purposeUuid or \"purposeUuid-elementUuid\"\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderInlinePurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string) => void;\n onPurposeCollapse: (purposeUuid: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string) => void;\n }\n): PurposeRenderRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n settings,\n isMobile,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = settings?.textColor || \"#344054\";\n\n const container = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" },\n });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n\n // Chevron SVG\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: settings?.headingColor || \"#323B4B\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[purpose.uuid] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(purpose.uuid, chevron);\n\n const chevronContainer = el(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n marginLeft: \"5px\",\n },\n },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n style: {\n ...inlineStyles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n },\n });\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n titleElements.set(purpose.uuid, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n style: {\n ...inlineStyles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(purpose.uuid, descEl);\n\n const textContainer = el(\"div\", { style: inlineStyles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: inlineStyles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[purpose.uuid]),\n \"aria-controls\": `purpose-${purpose.uuid}`,\n \"aria-label\": `${collapsedPurposes[purpose.uuid] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(purpose.uuid, collapseBtn);\n\n // Purpose checkbox\n const purposeCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedPurposes[purpose.uuid] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(purpose.uuid, purposeCheckbox);\n\n const optionRow = el(\"div\", { style: inlineStyles.optionItem }, collapseBtn, purposeCheckbox);\n\n // Data elements container\n const deContainer = el(\"div\", {\n id: `purpose-${purpose.uuid}`,\n style: inlineStyles.dataElementsContainer,\n });\n\n if (purpose.data_elements && purpose.data_elements.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n style: {\n ...inlineStyles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (dataElement.required) {\n const asterisk = el(\"span\", {\n style: { color: \"red\", marginLeft: \"4px\" },\n \"aria-label\": \"required\",\n });\n asterisk.textContent = \"*\";\n labelSpan.appendChild(asterisk);\n }\n\n const deCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${dataElement.required ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n\n const deRow = el(\"div\", { style: inlineStyles.dataElementItem }, labelSpan, deCheckbox);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(purpose.uuid, deContainer);\n\n // Show/hide data elements based on collapse state\n if (!collapsedPurposes[purpose.uuid] && purpose.data_elements?.length > 0) {\n deContainer.style.display = \"flex\";\n } else {\n deContainer.style.display = \"none\";\n }\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n","import { Store } from \"../core/state\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport { el, applyStyles, clearElement } from \"../core/dom\";\nimport { fetchConsentContentPublic, submitConsentEventPublic } from \"../api\";\nimport {\n fetchNoticeConsentStatusForScope,\n isNoticeFullyConsented,\n} from \"../api/notice-consent-status\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { inlineStyles } from \"../styles/inline\";\nimport { renderInlinePurposes, type PurposeRenderRefs } from \"./purposes\";\nimport type { InlineOptions } from \"../types\";\nimport type { ActiveConfig, TranslationObject } from \"../api/types\";\n\ntype InlineState = {\n content: ActiveConfig | null;\n isLoading: boolean;\n isSubmitting: boolean;\n selectedLanguage: string;\n collapsedPurposes: Record<string, boolean>;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n // Blocks auto-submit while the Go ledger check-consent read is in flight,\n // so an already-consented principal is not re-submitted post-cutover.\n isCheckingConsent: boolean;\n fetchError: Error | null;\n errorMessage: string | null;\n};\n\nexport class InlineController {\n private store: Store<InlineState>;\n private options: InlineOptions;\n private targetEl: HTMLElement | null = null;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private rootEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: PurposeRenderRefs | null = null;\n private errorEl: HTMLElement | null = null;\n private hasSubmitted = false;\n private hasCheckedLedgerConsent = false;\n private unsubscribe: (() => void) | null = null;\n\n constructor(options: InlineOptions) {\n this.options = options;\n this.store = new Store<InlineState>({\n content: null,\n isLoading: true,\n isSubmitting: false,\n selectedLanguage: options.language || \"en\",\n collapsedPurposes: {},\n selectedPurposes: {},\n selectedDataElements: {},\n hasAlreadyConsented: false,\n isCheckingConsent: false,\n fetchError: null,\n errorMessage: null,\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n }\n\n async init(): Promise<void> {\n // Resolve target element\n if (typeof this.options.target === \"string\") {\n this.targetEl = document.querySelector(this.options.target);\n if (!this.targetEl) {\n throw new Error(`Target element not found: ${this.options.target}`);\n }\n } else {\n this.targetEl = this.options.target;\n }\n\n // Mount the inline form inside an open shadow root attached to a host\n // <div> within the user's target container. This matches the modal's\n // isolation strategy so host-page CSS cannot bleed into the inline form\n // either.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent-inline\", \"\");\n // Block-level, but no `all: initial` — we want font / color / line-height\n // to inherit from the user's page so the inline form blends in like the\n // React SDK does.\n this.hostEl.style.display = \"block\";\n this.targetEl.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n injectCheckboxStyles(this.shadowRoot);\n\n // Subscribe to state changes\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n // Subscribe to media query changes\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.store.destroy();\n // Removing the host div tears down the shadow tree (and the rootEl\n // inside it) in one step.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n this.hostEl = null;\n this.shadowRoot = null;\n this.rootEl = null;\n this.purposeRefs = null;\n }\n\n updateToken(accessToken: string): void {\n this.options = { ...this.options, accessToken };\n // A late-arriving token is the first chance to run the ledger\n // check-consent read; it gates auto-submit synchronously before trying.\n if (this.shouldCheckLedgerConsent()) {\n void this.checkLedgerConsent();\n return;\n }\n this.tryAutoSubmit();\n }\n\n // ─── Private ───\n\n private async fetchNotice(): Promise<void> {\n this.store.setState({ isLoading: true, fetchError: null });\n try {\n const data = await fetchConsentContentPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n notice_uuid: this.options.notice_uuid,\n baseUrl: this.options.baseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n });\n\n const activeConfig = data.detail.active_config;\n const initialCollapsed: Record<string, boolean> = {};\n const initialPurposes: Record<string, boolean> = {};\n const initialElements: Record<string, boolean> = {};\n\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n\n // Post-cutover, consent records live in the Go ledger, so Python's\n // get-notice no longer 409s for an already-consented principal. Kick off\n // the ledger check BEFORE the content state lands: its synchronous\n // prologue raises isCheckingConsent, so the content state change below\n // cannot auto-submit until the read settles.\n void this.checkLedgerConsent();\n\n this.store.setState({\n content: activeConfig,\n isLoading: false,\n selectedLanguage: activeConfig.default_language || this.options.language || \"en\",\n collapsedPurposes: initialCollapsed,\n selectedPurposes: initialPurposes,\n selectedDataElements: initialElements,\n });\n } catch (err: unknown) {\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept?.();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private shouldCheckLedgerConsent(): boolean {\n return (\n Boolean(this.options.ledgerBaseUrl) &&\n !this.options.applicationId &&\n Boolean(this.options.accessToken) &&\n !this.hasCheckedLedgerConsent\n );\n }\n\n // Ask the Go ledger whether this principal has already fully consented —\n // the ledger equivalent of the legacy Python 409. Skipped without a ledger\n // (the 409 path governs) and for the magic-link applicationId flow. Any\n // failure returns null and falls through to the normal flow.\n private async checkLedgerConsent(): Promise<void> {\n if (!this.shouldCheckLedgerConsent()) return;\n this.hasCheckedLedgerConsent = true;\n this.store.setState({ isCheckingConsent: true });\n try {\n const status = await fetchNoticeConsentStatusForScope({\n accessToken: this.options.accessToken!,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n organisationUuid: this.options.org_uuid,\n workspaceUuid: this.options.workspace_uuid,\n noticeUuid: this.options.notice_uuid,\n });\n if (status && isNoticeFullyConsented(status)) {\n this.store.setState({ hasAlreadyConsented: true });\n this.options.onAccept?.();\n }\n } finally {\n this.store.setState({ isCheckingConsent: false });\n // Re-run auto-submit now that the gate is down (no-op when already\n // consented or requirements are unmet).\n this.tryAutoSubmit();\n }\n }\n\n private handleStateChange(state: InlineState, prevState: InlineState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n }\n\n // Already consented or fetch error → hide\n if (state.hasAlreadyConsented || state.fetchError) {\n if (this.rootEl && this.shadowRoot && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n this.rootEl = null;\n }\n return;\n }\n\n // Checkbox state changes → update checkboxes\n if (state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements) {\n this.updateCheckboxes(state);\n this.notifyValidation(state);\n this.tryAutoSubmit();\n }\n\n // Collapse state changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message changes\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n }\n\n private renderLoading(): void {\n if (!this.shadowRoot) return;\n\n const textColor = this.options.settings?.textColor || \"#344054\";\n\n this.rootEl = el(\n \"div\",\n { style: inlineStyles.loadingContainer },\n el(\"div\", { style: inlineStyles.loadingSpinner }),\n el(\"p\", { style: { fontSize: \"16px\", fontWeight: 400, color: textColor } }, \"Loading...\")\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.shadowRoot) return;\n\n // Remove existing root\n if (this.rootEl && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n }\n\n // Build error message element\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: state.errorMessage ? \"block\" : \"none\",\n },\n });\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n }\n\n // Build purposes\n this.purposeRefs = renderInlinePurposes(state.content.purposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n settings: this.options.settings,\n isMobile: this.mediaQuery.matches,\n getTranslatedText: (key, defaultText, itemId) =>\n this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (elementUuid, purposeUuid) =>\n this.handleDataElementCheckboxChange(elementUuid, purposeUuid),\n });\n\n this.rootEl = el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" } },\n this.errorEl,\n this.purposeRefs.container\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n this.notifyValidation(state);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private togglePurposeCollapse(purposeUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [purposeUuid]: !state.collapsedPurposes[purposeUuid],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const newPurposeState = !state.selectedPurposes[purposeUuid];\n\n const updatedElements = { ...state.selectedDataElements };\n for (const de of purpose.data_elements) {\n updatedElements[`${purposeUuid}-${de.uuid}`] = newPurposeState;\n }\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: newPurposeState },\n selectedDataElements: updatedElements,\n });\n }\n\n private handleDataElementCheckboxChange(elementUuid: string, purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const combinedId = `${purposeUuid}-${elementUuid}`;\n const newElementState = !state.selectedDataElements[combinedId];\n\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: newElementState,\n };\n\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n let shouldCheckPurpose: boolean;\n\n if (requiredElements.length > 0) {\n shouldCheckPurpose = requiredElements.every(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n } else {\n shouldCheckPurpose = purpose.data_elements.some(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n }\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: shouldCheckPurpose },\n });\n }\n\n private updateCheckboxes(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n\n private updateCollapseState(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [purposeUuid, container] of this.purposeRefs.dataElementContainers) {\n const content = this.store.getState().content;\n const purpose = content?.purposes.find((p) => p.uuid === purposeUuid);\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = this.purposeRefs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\";\n }\n\n const collapseBtn = this.purposeRefs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n }\n\n private updateErrorMessage(state: InlineState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n private areAllRequiredElementsChecked(): boolean {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return false;\n\n return content.purposes.every((purpose) => {\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n return requiredElements.every(\n (el) => state.selectedDataElements[`${purpose.uuid}-${el.uuid}`]\n );\n });\n }\n\n private notifyValidation(state: InlineState): void {\n const isValid = this.areAllRequiredElementsChecked();\n this.options.onValidationChange?.(isValid);\n }\n\n private async tryAutoSubmit(): Promise<void> {\n const state = this.store.getState();\n const accessToken = this.options.accessToken;\n\n if (\n accessToken &&\n state.content &&\n this.areAllRequiredElementsChecked() &&\n !state.isSubmitting &&\n !state.isCheckingConsent &&\n !state.hasAlreadyConsented &&\n !this.hasSubmitted\n ) {\n this.hasSubmitted = true;\n try {\n await this.handleSubmit(accessToken);\n } catch (err) {\n this.hasSubmitted = false;\n this.options.onError?.(err as Error);\n }\n }\n }\n\n private async handleSubmit(tokenToUse: string): Promise<void> {\n const state = this.store.getState();\n const content = state.content;\n if (!tokenToUse || !content) {\n this.store.setState({ errorMessage: \"Unable to submit consent. Please try again.\" });\n throw new Error(\"Access token or content not available\");\n }\n\n try {\n this.store.setState({ isSubmitting: true, errorMessage: null });\n\n await submitConsentEventPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n accessToken: tokenToUse,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: content.notice_uuid,\n purposes: content.purposes.map((purpose) => {\n const hasSelectedRequired = purpose.data_elements.some(\n (el) =>\n el.required && (state.selectedDataElements[`${purpose.uuid}-${el.uuid}`] || false)\n );\n const hasSelectedAny = purpose.data_elements.some(\n (el) => state.selectedDataElements[`${purpose.uuid}-${el.uuid}`] || false\n );\n const purposeSelected =\n state.selectedPurposes[purpose.uuid] || hasSelectedRequired || hasSelectedAny;\n\n return {\n ...purpose,\n selected: purposeSelected,\n data_elements: purpose.data_elements.map((element) => ({\n ...element,\n selected: state.selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false,\n })),\n };\n }),\n declined: false,\n meta_data: this.options.applicationId\n ? { specific_uuid: this.options.applicationId }\n : undefined,\n });\n\n this.options.onAccept?.();\n this.hasSubmitted = false;\n } catch (error) {\n const err = error as Error & { status?: number };\n const message =\n err.status === 500\n ? \"An error occurred while submitting your consent. Please try again later.\"\n : err.message || \"Failed to submit consent. Please try again.\";\n this.store.setState({ errorMessage: message });\n this.hasSubmitted = false;\n throw error;\n } finally {\n this.store.setState({ isSubmitting: false });\n }\n }\n}\n","import { el } from \"../core/dom\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { verifyGuardianStatus } from \"../api\";\nimport {\n getConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport type { DigiLockerCallbackOptions } from \"../types\";\nimport type { GuardianVerificationErrorCode } from \"../api/types\";\n\nfunction getErrorMessage(errorCode?: GuardianVerificationErrorCode | string | null): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"Guardian verification failed: The guardian must be 18 years or older.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please restart the verification process.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker authentication failed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"Missing authorization code from DigiLocker. Please try again.\";\n default:\n return \"Verification failed. Please try again.\";\n }\n}\n\nexport function handleDigilockerCallback(options: DigiLockerCallbackOptions): void {\n // The DigiLocker callback page is a standalone screen, not embedded in a\n // host site, so styles can safely live in document.head here.\n injectCheckboxStyles(document);\n\n const params = new URLSearchParams(window.location.search);\n const sessionToken = params.get(\"session_token\");\n const urlStatus = params.get(\"status\") as \"verified\" | \"failed\" | \"expired\" | null;\n const verificationReference = params.get(\"verification_reference\");\n const errorCode = params.get(\"error_code\") as GuardianVerificationErrorCode | null;\n\n const persistedState = getConsentState();\n const originalUrl = persistedState?.originalUrl || \"/\";\n const storedBaseUrl = persistedState?.baseUrl;\n const storedSessionToken = persistedState?.sessionToken;\n const activeSessionToken = sessionToken || storedSessionToken;\n const apiBaseUrl = options.baseUrl || storedBaseUrl;\n\n // Check if in iframe\n let isInIframe = false;\n try {\n isInIframe = window.self !== window.top;\n } catch {\n isInIframe = true;\n }\n\n // Render status UI\n const container = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"200px\",\n padding: \"32px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n });\n\n const statusEl = el(\"p\", {\n style: { fontSize: \"16px\", fontWeight: 600, color: \"#101828\", textAlign: \"center\" },\n });\n statusEl.textContent = \"Processing verification...\";\n\n const spinnerEl = el(\"div\", {\n style: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"16px\",\n },\n });\n\n container.appendChild(spinnerEl);\n container.appendChild(statusEl);\n document.body.appendChild(container);\n\n const redirectToOriginal = (\n result: \"verified\" | \"failed\" | \"expired\",\n ref?: string\n ) => {\n updateConsentState({\n verificationResult: result,\n verificationReference: ref,\n flowState: result === \"verified\" ? \"consent-form\" : \"error\",\n });\n\n statusEl.textContent = result === \"verified\"\n ? \"Verification successful! Redirecting...\"\n : \"Verification failed. Redirecting...\";\n\n spinnerEl.style.display = \"none\";\n\n setTimeout(() => {\n window.location.href = originalUrl;\n }, 1500);\n };\n\n // Handle direct status from URL\n if (urlStatus === \"verified\" && verificationReference) {\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onSuccess?.(verificationReference);\n redirectToOriginal(\"verified\", verificationReference);\n return;\n }\n\n if (urlStatus === \"failed\" || urlStatus === \"expired\") {\n const errorMsg = getErrorMessage(errorCode);\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: urlStatus,\n errorCode,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onError?.(new Error(errorMsg), errorCode || undefined);\n redirectToOriginal(urlStatus);\n return;\n }\n\n // No status in URL — poll the backend\n if (!activeSessionToken) {\n statusEl.textContent = \"No verification session found.\";\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(\"No session token available\"));\n return;\n }\n\n let retryCount = 0;\n const MAX_RETRIES = 3;\n\n const pollStatus = async () => {\n try {\n const response = await verifyGuardianStatus({\n accessToken: options.accessToken,\n baseUrl: apiBaseUrl,\n sessionToken: activeSessionToken,\n });\n\n if (response.status === \"verified\") {\n const ref = response.verification_reference ||\n response.guardian_details?.verification_reference;\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference: ref,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n if (ref) options.onSuccess?.(ref);\n redirectToOriginal(\"verified\", ref || undefined);\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n const errorMsg = getVerificationError(response.error_code, response.error);\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: response.status,\n errorCode: response.error_code,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n options.onError?.(new Error(errorMsg), response.error_code || undefined);\n redirectToOriginal(response.status);\n return;\n }\n\n // Still in progress — retry with backoff\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const timeoutMsg = \"Verification is taking too long. Please return to the original page.\";\n statusEl.textContent = timeoutMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(timeoutMsg));\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n statusEl.textContent = \"Still processing... Please wait.\";\n setTimeout(pollStatus, delay);\n } catch (error) {\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const errMsg = (error as Error).message || \"Failed to check verification status.\";\n statusEl.textContent = errMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(error as Error);\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n setTimeout(pollStatus, delay);\n }\n };\n\n // Start first poll after 3s\n setTimeout(pollStatus, 3000);\n}\n\nfunction getVerificationError(errorCode: string | null, fallbackError: string | null): string {\n return getErrorMessage(errorCode) || fallbackError || \"Verification failed. Please try again.\";\n}\n"],"mappings":"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","names":["src_exports","__export","src_default","destroy","digilockerCallback","init","inline","Store","initialState","partial","prevState","listener","el","tag","attrs","children","element","applyAttrs","appendChildren","svg","key","value","applyStyles","event","UNITLESS_PROPS","styles","stringValue","parent","child","clearElement","createMediaQuery","query","mql","currentMatches","listeners","handler","e","cb","InvalidTokenError","b64DecodeUnicode","str","m","p","code","base64UrlDecode","output","jwtDecode","token","options","pos","part","decoded","e","decodeTokenSafely","token","jwtDecode","error","apiCache","CACHE_TTL","getCachedData","key","cached","setCachedData","data","ttl","clearApiCache","BASE_URL","BASE_URL_PUBLIC","fetchConsentContent","noticeId","accessToken","baseUrl","language","specific_uuid","validate_against","include_fully_consented_data","signal","decodedToken","decodeTokenSafely","ORG","WS","apiBaseUrl","cacheKey","cached","getCachedData","url","response","errorMessage","error","data","setCachedData","fetchConsentContentPublic","org_uuid","workspace_uuid","notice_uuid","submitConsentEvent","ledgerBaseUrl","noticeUuid","purposes","declined","meta_data","guardianVerificationReference","selfDeclaredAdult","validatedPurposes","purpose","dataElements","element","payload","clearApiCache","submitConsentEventPublic","_a","_b","errorData","fetchTTSAudioUrls","initiateGuardianVerification","guardianName","guardianContact","guardianRelationship","frontendCallbackUrl","metadata","responseData","detail","verifyGuardianStatus","sessionToken","_c","_d","_e","_f","_g","_h","fetchNoticeConsentStatusForScope","accessToken","ledgerBaseUrl","organisationUuid","workspaceUuid","noticeUuid","signal","response","data","body","fetchNoticeConsentStatus","decodedToken","decodeTokenSafely","ORG","WS","isNoticeFullyConsented","status","buildLedgerConsentOverlay","configPurposes","_a","_b","byUuid","p","purpose_selections","cp","lp","purposeStatus","selectedByUuid","de","data_elements","STYLE_ID","STYLE_CONTENT","injectCheckboxStyles","root","style","styles","renderModalPurposes","purposes","options","_a","_b","selectedPurposes","collapsedPurposes","selectedDataElements","initialDataElementSelections","settings","isMobile","isAlreadyConsented","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","font","container","el","styles","purpose","purposeWrapper","chevron","svg","chevronContainer","titleEl","descEl","textContainer","collapseBtn","e","rightElement","createGreenCheckmark","applyStyles","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","asterisk","deRightElement","deCheckbox","deRow","size","ariaLabel","svgSize","strokeWidth","pathD","checkSvg","LANGUAGE_NATIVE_LABELS","toNativeLabel","name","_a","renderLanguageSelector","options","_b","_c","_d","languages","selectedLanguage","settings","onSelect","dropdownContainer","isOpen","buttonText","el","chevronSvg","svg","buttonStyle","styles","button","toggleDropdown","e","closeDropdown","dropdown","lang","isSelected","itemStyle","item","container","positionDropdown","rect","clickOutsideHandler","path","target","repositionHandler","openDropdown","setupKeyboardTrap","modalEl","onEscape","handler","e","_a","focusableElements","focusable","el","first","last","active","firstFocusable","STORAGE_KEY","isBrowser","saveConsentState","state","stateWithTimestamp","STORAGE_KEY","error","getConsentState","savedState","parsed","clearConsentState","updateConsentState","updates","currentState","DPO_AUDIO_ELEMENT_MAP","TTSManager","onStateChange","root","params","_a","response","fetchTTSAudioUrls","error","content","_b","urls","audioSeq","elementSeq","push","url","elementId","purpose","purposeAudio","de","deAudio","mapping","DPO_AUDIO_ELEMENT_MAP","audioUrl","startIndex","index","audio","element","rect","el","renderAgeVerification","options","settings","colors","isMobile","logoUrl","onYes","onNo","onClose","headingColor","textColor","font","logo","el","styles","title","topLeft","closeBtn","closeSvg","svg","topSection","description","question","middleSection","btnBase","yesBtn","noBtn","bottomSection","RELATIONSHIP_OPTIONS","renderGuardianForm","options","_a","formData","settings","colors","isMobile","logoUrl","isSubmitting","onSubmit","onCancel","onFieldChange","headingColor","textColor","borderColor","bgColor","radius","font","accentColor","inputStyle","errorStyle","labelStyle","hintStyle","logo","el","styles","title","topLeft","topSection","subtitle","infoIcon","svg","infoText","infoBanner","nameLabel","nameInput","e","nameHint","nameError","nameGroup","contactLabel","contactInput","contactHint","contactError","contactGroup","relLabel","selectedLabel","o","chevronSvg","selectedSpan","relationshipDisplay","dropdownList","i","option","isSelected","optionEl","doClose","label","checkSvg","dropdownOpen","relContainer","handleClickOutside","doOpen","rect","spaceBelow","dropdownHeight","relationshipError","generalError","fieldsContainer","middleSection","btnBase","submitBtn","cancelBtn","bottomSection","validateGuardianForm","data","errors","getVerificationErrorMessage","errorCode","fallbackError","renderVerificationScreen","options","settings","colors","isMobile","logoUrl","isInitiating","isPolling","isComplete","isAutoTransitioning","error","canRetry","onContinue","onBack","headingColor","textColor","font","accentColor","logo","el","styles","title","topLeft","topSection","middleSection","successCircle","checkSvg","svg","successText","wrapper","spinner","statusMsg","errorCircle","xSvg","failedText","errorBox","btnBase","bottomSection","acceptBtnStyle","declineBtnStyle","continueBtn","retryBtn","goBackBtn","cancelBtn","resolveColors","settings","activeConfig","_a","_b","_c","_d","_e","_f","_g","_h","primaryColor","secondaryColor","ModalController","options","Store","createMediaQuery","state","prevState","_a","_b","_c","_d","data","fetchConsentContent","activeConfig","purposeSelections","reconsentRequired","ledgerOverlayApplied","ledgerStatus","fetchNoticeConsentStatus","overlay","buildLedgerConsentOverlay","initialCollapsed","initialPurposes","initialElements","initialDataElementSelections","needsConsentPurposes","alreadyConsentedPurposes","isFullyConsentedReviewMode","purpose","selection","de","combinedId","deSelection","wasSelected","selectedLanguage","isMinorFlow","showAgeVerification","restoreState","pollingTokenToResume","persistedState","getConsentState","clearConsentState","err","error","injectCheckboxStyles","TTSManager","el","styles","settingsObj","modalStyle","loadingEl","contentEl","_e","_f","_g","_h","isMobile","colors","resolveColors","clearElement","ageRefs","renderAgeVerification","setupKeyboardTrap","renderGuardianForm","field","value","s","verRefs","renderVerificationScreen","clearName","headingColor","textColor","linkColor","font","logoImg","supportedLangs","allLanguages","l","renderLanguageSelector","lang","ttsStrokeColor","speakerSvg","svg","topRight","topSection","headerRow","topLeft","baseTextStyle","noticeTextSpan","policyPrefixText","policyAnchorText","policySpan","noticeAndPolicyP","renderModalPurposes","key","defaultText","itemId","uuid","euuid","puuid","footerDiv","footerP","addlSpan","pcAnchorText","dpo","gText","gLink","connectorSpan","emailLink","dpText","dpLink","dpoTextSpan","dpoLink","acceptBtnText","acceptStyle","declineBtnText","declineStyle","bottomSection","contentWrapper","displayLanguage","content","translations","translationMap","message","errorContent","purposeData","purposeUuid","p","newPurposeState","updatedElements","elementUuid","newDataElements","requiredElements","shouldCheckPurpose","purposes","dataElements","submitConsentEvent","checkbox","disabled","updateRefs","refs","container","isCollapsed","chevron","collapseBtn","errors","validateGuardianForm","digilockerMode","callbackUrl","response","initiateGuardianVerification","saveConsentState","popup","openedWindow","token","attempts","consecutiveErrors","paused","MAX_ATTEMPTS","MAX_CONSECUTIVE_ERRORS","POLL_INTERVAL","poll","verifyGuardianStatus","ref","getVerificationErrorMessage","strokeColor","pauseSvg","inlineStyles","renderInlinePurposes","purposes","options","_a","selectedPurposes","collapsedPurposes","selectedDataElements","settings","isMobile","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","container","el","purpose","purposeWrapper","chevron","svg","chevronContainer","titleEl","inlineStyles","descEl","textContainer","collapseBtn","e","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","asterisk","deCheckbox","deRow","InlineController","options","Store","createMediaQuery","injectCheckboxStyles","state","prevState","_a","accessToken","_b","_c","_d","activeConfig","fetchConsentContentPublic","initialCollapsed","initialPurposes","initialElements","purpose","de","err","error","status","fetchNoticeConsentStatusForScope","isNoticeFullyConsented","textColor","el","inlineStyles","renderInlinePurposes","key","defaultText","itemId","uuid","elementUuid","purposeUuid","content","lang","translations","translationMap","purposeData","value","p","newPurposeState","updatedElements","combinedId","newElementState","newDataElements","requiredElements","shouldCheckPurpose","checkbox","container","isCollapsed","chevron","collapseBtn","isValid","tokenToUse","submitConsentEventPublic","hasSelectedRequired","hasSelectedAny","purposeSelected","element","message","getErrorMessage","errorCode","handleDigilockerCallback","options","_a","_b","_c","injectCheckboxStyles","params","sessionToken","urlStatus","verificationReference","persistedState","getConsentState","originalUrl","storedBaseUrl","storedSessionToken","activeSessionToken","apiBaseUrl","isInIframe","container","el","statusEl","spinnerEl","redirectToOriginal","result","ref","updateConsentState","errorMsg","retryCount","MAX_RETRIES","pollStatus","_d","_e","response","verifyGuardianStatus","getVerificationError","timeoutMsg","delay","error","errMsg","fallbackError","activeModal","activeInline","init","options","destroy","ModalController","err","_a","inline","InlineController","digilockerCallback","handleDigilockerCallback","RedactoConsent","src_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/state.ts","../src/core/dom.ts","../src/core/media-query.ts","../src/services/cache.ts","../../../node_modules/.pnpm/jwt-decode@4.0.0/node_modules/jwt-decode/build/esm/index.js","../src/core/jwt-decode.ts","../src/api/sandbox.ts","../src/api/constants.ts","../src/api/language.ts","../src/api/index.ts","../src/api/notice-consent-status.ts","../src/styles/inject.ts","../src/styles/modal.ts","../src/modal/purposes.ts","../src/modal/language-selector.ts","../src/modal/keyboard.ts","../src/services/storage.ts","../src/constants.ts","../src/modal/tts.ts","../src/modal/age-verification.ts","../src/modal/guardian-form.ts","../src/modal/verification-screen.ts","../src/modal/colors.ts","../src/modal/layout.ts","../src/modal/index.ts","../src/styles/inline.ts","../src/inline/purposes.ts","../src/inline/index.ts","../src/modal/digilocker-callback.ts"],"sourcesContent":["import { ModalController } from \"./modal\";\nimport { InlineController } from \"./inline\";\nimport { handleDigilockerCallback } from \"./modal/digilocker-callback\";\nimport type { ModalOptions, InlineOptions, DigiLockerCallbackOptions } from \"./types\";\n\nlet activeModal: ModalController | null = null;\nlet activeInline: InlineController | null = null;\n\n/**\n * Initialize a modal consent dialog.\n * Renders a full-screen overlay with the consent form.\n */\nfunction init(options: ModalOptions): void {\n // Destroy any existing instance\n destroy();\n\n activeModal = new ModalController(options);\n activeModal.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Initialize an inline consent form.\n * Renders consent purposes inside a target container element.\n */\nfunction inline(options: InlineOptions): void {\n // Destroy any existing inline instance\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n\n activeInline = new InlineController(options);\n activeInline.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Destroy all active consent instances.\n */\nfunction destroy(): void {\n if (activeModal) {\n activeModal.destroy();\n activeModal = null;\n }\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n}\n\n/**\n * Handle DigiLocker callback (for guardian verification redirect flow).\n * Call this on the DigiLocker callback page.\n */\nfunction digilockerCallback(options: DigiLockerCallbackOptions): void {\n handleDigilockerCallback(options);\n}\n\nconst RedactoConsent = {\n init,\n inline,\n destroy,\n digilockerCallback,\n version: \"0.1.0\",\n};\n\nexport default RedactoConsent;\nexport { init, inline, destroy, digilockerCallback };\nexport type { ModalOptions, InlineOptions, DigiLockerCallbackOptions };\nexport type { Settings } from \"./api/types\";\n","/**\n * Simple observable store — replaces React useState.\n * Shallow-merges updates and notifies subscribers.\n */\n\nexport type Listener<T> = (state: T, prevState: T) => void;\n\nexport class Store<T extends Record<string, any>> {\n private state: T;\n private listeners: Set<Listener<T>> = new Set();\n\n constructor(initialState: T) {\n this.state = { ...initialState };\n }\n\n getState(): Readonly<T> {\n return this.state;\n }\n\n setState(partial: Partial<T>): void {\n const prevState = this.state;\n this.state = { ...this.state, ...partial };\n this.listeners.forEach((listener) => listener(this.state, prevState));\n }\n\n subscribe(listener: Listener<T>): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n destroy(): void {\n this.listeners.clear();\n }\n}\n","/**\n * DOM creation helpers — replaces JSX.\n */\n\ntype Attrs = Record<string, any>;\n\n/**\n * Create an HTML element with attributes, styles, events, and children.\n *\n * Attribute keys:\n * - \"style\" → merged into element.style\n * - \"className\" → element.className\n * - \"on...\" → addEventListener (e.g. onClick → \"click\")\n * - \"dataset\" → Object.assign(element.dataset, value)\n * - anything else → setAttribute\n */\nexport function el(\n tag: string,\n attrs?: Attrs | null,\n ...children: (Node | string | null | undefined | false)[]\n): HTMLElement {\n const element = document.createElement(tag);\n if (attrs) applyAttrs(element, attrs);\n appendChildren(element, children);\n return element;\n}\n\n/**\n * Create an SVG element.\n */\nexport function svg(\n tag: string,\n attrs?: Attrs | null,\n ...children: (Node | string | null | undefined | false)[]\n): SVGElement {\n const element = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n tag\n );\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n if (key === \"style\" && typeof value === \"object\") {\n applyStyles(element as unknown as HTMLElement, value);\n } else {\n element.setAttribute(key, String(value));\n }\n }\n }\n appendChildren(element as unknown as HTMLElement, children);\n return element;\n}\n\nfunction applyAttrs(element: HTMLElement, attrs: Attrs): void {\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n\n if (key === \"style\" && typeof value === \"object\") {\n applyStyles(element, value);\n } else if (key === \"className\") {\n element.className = value;\n } else if (key === \"dataset\" && typeof value === \"object\") {\n Object.assign(element.dataset, value);\n } else if (key.startsWith(\"on\") && typeof value === \"function\") {\n const event = key.slice(2).toLowerCase();\n element.addEventListener(event, value);\n } else if (key === \"checked\" || key === \"disabled\" || key === \"readOnly\") {\n (element as any)[key] = value;\n } else {\n element.setAttribute(key, String(value));\n }\n }\n}\n\n/**\n * CSS properties that take a unitless number, mirroring React's CSSProperty\n * list. For these we MUST NOT append \"px\" — doing so produces invalid CSS\n * (e.g. `font-weight: 400px`) and the browser falls back to the user-agent\n * default (which is what made <h3> purpose descriptions render as bold).\n */\nconst UNITLESS_PROPS = new Set([\n \"animationIterationCount\",\n \"aspectRatio\",\n \"borderImageOutset\",\n \"borderImageSlice\",\n \"borderImageWidth\",\n \"boxFlex\",\n \"boxFlexGroup\",\n \"boxOrdinalGroup\",\n \"columnCount\",\n \"columns\",\n \"flex\",\n \"flexGrow\",\n \"flexPositive\",\n \"flexShrink\",\n \"flexNegative\",\n \"flexOrder\",\n \"fontWeight\",\n \"gridArea\",\n \"gridRow\",\n \"gridRowEnd\",\n \"gridRowSpan\",\n \"gridRowStart\",\n \"gridColumn\",\n \"gridColumnEnd\",\n \"gridColumnSpan\",\n \"gridColumnStart\",\n \"lineClamp\",\n \"lineHeight\",\n \"opacity\",\n \"order\",\n \"orphans\",\n \"scale\",\n \"tabSize\",\n \"widows\",\n \"zIndex\",\n \"zoom\",\n]);\n\n/**\n * Apply a camelCase style object to an element.\n *\n * Numeric values are interpreted as pixels (matching React's behavior) EXCEPT\n * for the unitless properties listed above, which are passed through as-is.\n */\nexport function applyStyles(\n element: HTMLElement,\n styles: Record<string, any>\n): void {\n for (const [key, value] of Object.entries(styles)) {\n if (value == null) continue;\n const stringValue =\n typeof value === \"number\" && !UNITLESS_PROPS.has(key)\n ? `${value}px`\n : String(value);\n (element.style as any)[key] = stringValue;\n }\n}\n\nfunction appendChildren(\n parent: HTMLElement,\n children: (Node | string | null | undefined | false)[]\n): void {\n for (const child of children) {\n if (child == null || child === false) continue;\n if (typeof child === \"string\") {\n parent.appendChild(document.createTextNode(child));\n } else {\n parent.appendChild(child);\n }\n }\n}\n\n/**\n * Remove all children from an element.\n */\nexport function clearElement(element: HTMLElement): void {\n while (element.firstChild) {\n element.removeChild(element.firstChild);\n }\n}\n","/**\n * matchMedia wrapper with subscribe — replaces useMediaQuery hook.\n */\n\nexport type MediaQuerySubscription = {\n matches: boolean;\n subscribe: (cb: (matches: boolean) => void) => void;\n destroy: () => void;\n};\n\nexport function createMediaQuery(query: string): MediaQuerySubscription {\n const mql = window.matchMedia(query);\n let currentMatches = mql.matches;\n const listeners: Set<(matches: boolean) => void> = new Set();\n\n const handler = (e: MediaQueryListEvent) => {\n currentMatches = e.matches;\n listeners.forEach((cb) => cb(currentMatches));\n };\n\n mql.addEventListener(\"change\", handler);\n\n return {\n get matches() {\n return currentMatches;\n },\n subscribe(cb: (matches: boolean) => void) {\n listeners.add(cb);\n },\n destroy() {\n mql.removeEventListener(\"change\", handler);\n listeners.clear();\n },\n };\n}\n","const apiCache = new Map<string, { data: any; timestamp: number; ttl: number }>();\nconst CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport function getCachedData(key: string): any | null {\n const cached = apiCache.get(key);\n if (cached && Date.now() - cached.timestamp < cached.ttl) {\n return cached.data;\n }\n if (cached) {\n apiCache.delete(key);\n }\n return null;\n}\n\nexport function setCachedData(key: string, data: any, ttl = CACHE_TTL): void {\n apiCache.set(key, { data, timestamp: Date.now(), ttl });\n}\n\nexport function clearApiCache(): void {\n apiCache.clear();\n}\n","export class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }));\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n }\n catch (err) {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);\n }\n try {\n return JSON.parse(decoded);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);\n }\n}\n","import { jwtDecode } from \"jwt-decode\";\nimport type { RedactoJwtPayload } from \"../api/types\";\n\n/**\n * Decode JWT with error handling — returns null on failure.\n */\nexport function decodeTokenSafely(token: string): RedactoJwtPayload | null {\n try {\n return jwtDecode(token) as RedactoJwtPayload;\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return null;\n }\n}\n","/**\n * Sandbox-mode auth primitives for the consent PoC.\n *\n * In sandbox mode the SDK talks to the consent-server with a pasted static\n * token and an explicit test subject, bypassing the JWT entirely. Org/workspace\n * UUIDs come from options (they still build the `/public/organisations/{org}/\n * workspaces/{ws}/...` URL paths) instead of being decoded from a token.\n *\n * Auth is the single `X-Consent-Token` header carrying the static token; its\n * presence alone marks the request as `environment=test`. There is no subject\n * header. The acting identity (the test subject) rides the request's own\n * payload: query params (`primary_email` / `primary_mobile`) on GET/query reads,\n * and the body on POSTs. The server normalizes and namespaces it `test::`\n * server-side. Call sites resolve the credential via {@link buildAuthHeaders}\n * and the identity via {@link sandboxQueryIdentity} / {@link sandboxBodyIdentity}.\n *\n * This file exists so every JWT-decode / Authorization site resolves its\n * org/workspace UUIDs and builds its auth header through one place, keeping\n * sandbox vs. JWT branching from drifting across the fetch sites.\n */\nimport { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ResolvedRequestAuth,\n SandboxAuth,\n SandboxIdentityPayload,\n SandboxOptions,\n} from \"./types\";\n\n/** HTTP header carrying the static sandbox token (the credential). */\nexport const SANDBOX_TOKEN_HEADER = \"X-Consent-Token\";\n\n/**\n * Resolve a {@link SandboxAuth} from sandbox options, or null when sandbox mode\n * is not active (no token).\n *\n * @throws Error when a sandbox token is provided but org/workspace or the acting\n * identity are incomplete — sandbox mode cannot build URLs or identify the\n * acting principal without them.\n */\nexport const resolveSandboxAuth = (\n options: SandboxOptions\n): SandboxAuth | null => {\n const token = options.token?.trim();\n if (!token) {\n return null;\n }\n\n const organisationUuid = options.organisationUuid?.trim();\n const workspaceUuid = options.workspaceUuid?.trim();\n const ucic = options.sandboxUcic?.trim();\n const subject = options.sandboxSubject?.trim();\n\n if (!organisationUuid || !workspaceUuid) {\n throw new Error(\n \"Sandbox mode requires organisationUuid and workspaceUuid\"\n );\n }\n if (!ucic && !subject) {\n throw new Error(\"Sandbox mode requires a UCIC, email, or mobile\");\n }\n\n return { token, ucic, subject: subject ?? \"\", organisationUuid, workspaceUuid };\n};\n\n/**\n * Resolve org/workspace UUIDs plus the sandbox context for an authenticated\n * request. In sandbox mode these come from options; otherwise they are decoded\n * from the JWT (preserving the pre-sandbox error messages exactly).\n *\n * @throws Error when neither a valid sandbox config nor a decodable token with\n * org/workspace UUIDs is available.\n */\nexport const resolveRequestAuth = (\n accessToken: string | undefined,\n options: SandboxOptions\n): ResolvedRequestAuth => {\n const sandbox = resolveSandboxAuth(options);\n if (sandbox) {\n return {\n organisationUuid: sandbox.organisationUuid,\n workspaceUuid: sandbox.workspaceUuid,\n sandbox,\n };\n }\n\n const decodedToken = accessToken ? decodeTokenSafely(accessToken) : null;\n if (!decodedToken) {\n throw new Error(\"Invalid access token\");\n }\n const { organisation_uuid, workspace_uuid } = decodedToken;\n if (!organisation_uuid || !workspace_uuid) {\n throw new Error(\"Invalid token: missing organization or workspace UUID\");\n }\n return {\n organisationUuid: organisation_uuid,\n workspaceUuid: workspace_uuid,\n sandbox: null,\n };\n};\n\n/**\n * Build the request headers for an authenticated call. In sandbox mode this is\n * the single `X-Consent-Token` credential (its presence marks the request as\n * `environment=test`); otherwise the standard `Authorization: Bearer`. There is\n * no subject header — the acting identity travels in the request's own payload\n * (see {@link sandboxQueryIdentity} for reads, {@link sandboxBodyIdentity} for\n * POSTs).\n */\nexport const buildAuthHeaders = (\n accessToken: string | undefined,\n sandbox: SandboxAuth | null\n): Record<string, string> => {\n if (sandbox) {\n return { [SANDBOX_TOKEN_HEADER]: sandbox.token };\n }\n return { Authorization: `Bearer ${accessToken}` };\n};\n\n/**\n * The identity payload fragment for the sandbox acting principal:\n * `{ org_user_id }` when a UCIC is set (it takes precedence), else\n * `{ primary_email }` when the subject looks like an email (contains \"@\"),\n * otherwise `{ primary_mobile }`. Merge this into a JSON request body (POST) or\n * into query params (GET) so the server can resolve the acting test identity.\n */\nexport const sandboxBodyIdentity = (\n sandbox: SandboxAuth\n): SandboxIdentityPayload => {\n if (sandbox.ucic) {\n return { org_user_id: sandbox.ucic };\n }\n return sandbox.subject.includes(\"@\")\n ? { primary_email: sandbox.subject }\n : { primary_mobile: sandbox.subject };\n};\n\n/**\n * The identity query fragment for GET/query reads: `{ org_user_id }` when a UCIC\n * is set (it takes precedence), else `{ primary_email }` when the subject looks\n * like an email (contains \"@\"), otherwise `{ primary_mobile }`. Append these to\n * the request's query string so the server can resolve the acting test identity\n * (the server reads `org_user_id` / `primary_email` / `primary_mobile` query\n * params on sandbox reads).\n */\nexport const sandboxQueryIdentity = (\n sandbox: SandboxAuth\n): SandboxIdentityPayload => sandboxBodyIdentity(sandbox);\n","export const CODE_BY_NAME = new Map<string, string>([\n [\"english\", \"en\"],\n [\"assamese\", \"as\"],\n [\"bengali\", \"bn\"],\n [\"bodo\", \"brx\"],\n [\"dogri\", \"doi\"],\n [\"goan konkani\", \"gom\"],\n [\"gujarati\", \"gu\"],\n [\"hindi\", \"hi\"],\n [\"kannada\", \"kn\"],\n [\"kashmiri\", \"ks\"],\n [\"maithili\", \"mai\"],\n [\"malayalam\", \"ml\"],\n [\"manipuri\", \"mni-Mtei\"],\n [\"marathi\", \"mr\"],\n [\"nepali\", \"ne\"],\n [\"odia\", \"or\"],\n [\"punjabi\", \"pa\"],\n [\"sanskrit\", \"sa\"],\n [\"santali\", \"sat\"],\n [\"sindhi\", \"sd\"],\n [\"tamil\", \"ta\"],\n [\"telugu\", \"te\"],\n [\"urdu\", \"ur\"],\n]);\n\nexport const CODE_BY_LOWER = new Map<string, string>(\n [...CODE_BY_NAME.values()].map((c) => [c.toLowerCase(), c])\n);\n","import { CODE_BY_LOWER, CODE_BY_NAME } from \"./constants\";\n\nexport function toLanguageCode(lang?: string | null): string | undefined {\n if (!lang) {\n return undefined;\n }\n const trimmed = lang.trim();\n if (!trimmed) {\n return undefined;\n }\n const lower = trimmed.toLowerCase();\n return CODE_BY_LOWER.get(lower) ?? CODE_BY_NAME.get(lower) ?? trimmed;\n}\n\nexport function resolveDisplayLanguage(\n requested: string | undefined,\n defaultLanguage: string | undefined,\n translations: Record<string, unknown> | undefined\n): string {\n const fallback = defaultLanguage || \"en\";\n const requestedCode = toLanguageCode(requested);\n if (!requestedCode) {\n return fallback;\n }\n\n for (const key of Object.keys(translations || {})) {\n if (toLanguageCode(key) === requestedCode) {\n return key;\n }\n }\n\n return fallback;\n}\n","import { clearApiCache, getCachedData, setCachedData } from \"../services/cache\";\nimport { decodeTokenSafely } from \"../core/jwt-decode\";\nimport {\n buildAuthHeaders,\n resolveRequestAuth,\n sandboxBodyIdentity,\n sandboxQueryIdentity,\n} from \"./sandbox\";\nimport { toLanguageCode } from \"./language\";\nimport type {\n ConsentContent,\n ConsentEventPayload,\n FetchConsentContentParams,\n FetchConsentContentPublicParams,\n FetchTTSAudioUrlsParams,\n InitiateGuardianVerificationParams,\n InitiateGuardianVerificationResponse,\n SubmitConsentEventParams,\n SubmitConsentEventPublicParams,\n TTSAudioUrlsResponse,\n VerifyGuardianStatusParams,\n VerifyGuardianStatusResponse,\n} from \"./types\";\n\nconst BASE_URL = \"https://api.redacto.io/consent\";\nconst BASE_URL_PUBLIC = \"https://api.redacto.tech/consent\";\n\n// ─── Modal: fetch notice (authenticated, JWT-decoded) ───\n\nexport const fetchConsentContent = async ({\n noticeId,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n validate_against = \"all\",\n include_fully_consented_data = false,\n signal,\n ...sandboxParams\n}: FetchConsentContentParams & { signal?: AbortSignal }): Promise<ConsentContent> => {\n if (!noticeId || !validate_against) {\n throw new Error(\"noticeId is required\");\n }\n if (!accessToken && !sandboxParams.token) {\n throw new Error(\"accessToken or token is required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n // Include org + workspace in the sandbox cache identity so two sessions\n // sharing a subject but scoped to different orgs never collide.\n const cacheIdentity = sandbox\n ? `sandbox:${sandbox.organisationUuid}:${sandbox.workspaceUuid}:${sandbox.ucic || sandbox.subject}`\n : accessToken;\n const cacheKey = `${cacheIdentity}-${noticeId}-${validate_against}-${language}-${specific_uuid || \"\"}-${include_fully_consented_data}`;\n\n if (validate_against === \"all\" && !specific_uuid) {\n const cached = getCachedData(cacheKey);\n if (cached) return cached;\n }\n\n const url = new URL(`${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeId}`);\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n url.searchParams.append(\"validate_against\", validate_against);\n if (include_fully_consented_data) url.searchParams.append(\"include_fully_consented_data\", \"true\");\n // Sandbox mode: the acting identity travels as query params\n // (primary_email / primary_mobile); the credential is the X-Consent-Token header.\n if (sandbox) {\n for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {\n url.searchParams.append(key, value);\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n \"Accept-Language\": language,\n },\n signal,\n });\n\n if (!response.ok) {\n let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;\n if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice not found\";\n else if (response.status === 409) errorMessage = \"User has already provided consent\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const data: ConsentContent = await response.json();\n\n if (validate_against === \"all\" && !specific_uuid) {\n setCachedData(cacheKey, data);\n }\n\n return data;\n};\n\n// ─── Inline: fetch notice (public, no auth) ───\n\nexport const fetchConsentContentPublic = async ({\n org_uuid,\n workspace_uuid,\n notice_uuid,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n}: FetchConsentContentPublicParams): Promise<ConsentContent> => {\n const apiBaseUrl = baseUrl || BASE_URL_PUBLIC;\n const noticesUrl = `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices`;\n\n const url = new URL(\n accessToken ? `${noticesUrl}/${notice_uuid}` : `${noticesUrl}/get-notice/${notice_uuid}`\n );\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept-Language\": language,\n ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),\n },\n });\n\n if (response.status === 401) {\n const error = new Error(\"Unauthorized\") as Error & { status?: number };\n error.status = 401;\n throw error;\n }\n if (response.status === 409) {\n const error = new Error(\"User has already provided consent\") as Error & { status?: number };\n error.status = 409;\n throw error;\n }\n if (!response.ok) {\n throw new Error(`Failed to fetch consent content: ${response.statusText}`);\n }\n\n return await response.json();\n};\n\n// ─── Modal: submit consent (JWT-decoded) ───\n\nexport const submitConsentEvent = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n guardianVerificationReference,\n selfDeclaredAdult,\n language,\n signal,\n ...sandboxParams\n}: SubmitConsentEventParams & { signal?: AbortSignal }): Promise<void> => {\n if (!noticeUuid || !Array.isArray(purposes)) {\n throw new Error(\"noticeUuid and purposes array are required\");\n }\n if (!accessToken && !sandboxParams.token) {\n throw new Error(\"accessToken or token is required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working. Sandbox\n // never routes to the Go ledger (no X-Consent-Token support), so a sandbox\n // session forces the consent-server path even if a ledgerBaseUrl is set.\n const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;\n\n const validatedPurposes = purposes.map((purpose) => {\n if (!purpose.uuid) throw new Error(\"Invalid purpose data: missing uuid\");\n\n const dataElements = (purpose.data_elements || [])\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n });\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: validatedPurposes,\n select_all_mandatory: false,\n source: \"WEB\",\n declined: Boolean(declined),\n meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : undefined,\n guardian_verification_reference: guardianVerificationReference,\n self_declared_adult: selfDeclaredAdult,\n language: toLanguageCode(language),\n };\n\n // Sandbox mode: merge the acting test identity into the body (the server has\n // no subject header; it namespaces this identity `test::`).\n const requestBody = sandbox ? { ...payload, ...sandboxBodyIdentity(sandbox) } : payload;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/submit-consent`,\n {\n method: \"POST\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Invalid request data\";\n } catch {\n errorMessage = \"Invalid request data\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice not found\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n clearApiCache();\n};\n\n// ─── Inline: submit consent (direct org/workspace) ───\n\nexport const submitConsentEventPublic = async ({\n org_uuid,\n workspace_uuid,\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n language,\n}: SubmitConsentEventPublicParams): Promise<void> => {\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working.\n const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL_PUBLIC;\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: purposes.map((purpose) => {\n if (!purpose.uuid) throw new Error(\"Invalid purpose data: missing uuid\");\n\n const dataElements = purpose.data_elements\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n }),\n select_all_mandatory: false,\n source: \"WEB\",\n declined,\n meta_data,\n language: toLanguageCode(language),\n };\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n }\n );\n\n if (!response.ok) {\n let errorData;\n try {\n errorData = await response.json();\n } catch {\n errorData = { message: response.statusText };\n }\n\n if (response.status === 409) {\n const error = new Error(\n errorData.detail?.message || errorData.message || \"User has already provided consent\"\n ) as Error & { status?: number; code?: number };\n error.status = 409;\n error.code = errorData.code || 409;\n throw error;\n }\n\n const error = new Error(\n errorData.detail?.message || errorData.message || `Failed to submit consent event: ${response.statusText}`\n ) as Error & { status?: number; code?: number };\n error.status = response.status;\n error.code = errorData.code;\n throw error;\n }\n};\n\n// ─── TTS Audio ───\n\nexport const fetchTTSAudioUrls = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n language,\n signal,\n ...sandboxParams\n}: FetchTTSAudioUrlsParams & { signal?: AbortSignal }): Promise<TTSAudioUrlsResponse> => {\n if ((!accessToken && !sandboxParams.token) || !noticeUuid || !language) {\n throw new Error(\"accessToken (or token), noticeUuid, and language are required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n // Prefer the Go ledger for audio, but a sandbox session never routes there:\n // the ledger's public reads are JWT-gated and don't support X-Consent-Token.\n // Without this a ledger-minted token is rejected by the consent server and\n // per-language audio silently disappears.\n const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;\n const url = new URL(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeUuid}/audio/${language}`\n );\n // Sandbox mode: the acting identity travels as query params\n // (primary_email / primary_mobile); the credential is the X-Consent-Token header.\n if (sandbox) {\n for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {\n url.searchParams.append(key, value);\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n Accept: \"application/json\",\n },\n signal,\n });\n\n if (!response.ok) {\n let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;\n if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice or audio not found\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return await response.json();\n};\n\n// ─── Guardian Verification ───\n\nexport const initiateGuardianVerification = async ({\n accessToken,\n baseUrl,\n guardianName,\n guardianContact,\n guardianRelationship,\n frontendCallbackUrl,\n metadata,\n signal,\n}: InitiateGuardianVerificationParams): Promise<InitiateGuardianVerificationResponse> => {\n // Guardian verification is JWT-only: sandbox sessions have no minor-notice /\n // guardian support (the server 403s them, and C1 blocks minor notices at\n // render), so no sandbox identity is wired through here.\n if (!accessToken) throw new Error(\"accessToken is required\");\n if (!guardianName?.trim()) throw new Error(\"Guardian name is required\");\n if (!guardianContact?.trim()) throw new Error(\"Guardian contact is required\");\n if (!guardianRelationship?.trim()) throw new Error(\"Guardian relationship is required\");\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const payload: Record<string, any> = {\n guardian_name: guardianName.trim(),\n guardian_contact: guardianContact.trim(),\n guardian_relationship: guardianRelationship.trim(),\n };\n if (frontendCallbackUrl) payload.frontend_callback_url = frontendCallbackUrl;\n if (metadata) payload.metadata = metadata;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/initiate-verification`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Invalid request data\";\n } catch {\n errorMessage = \"Invalid request data\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 404) errorMessage = \"Organization or workspace not found\";\n else if (response.status === 422) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Validation error: Please check your input\";\n } catch {\n errorMessage = \"Validation error: Please check your input\";\n }\n } else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n if (detail.already_verified) {\n return {\n success: true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: true,\n verification_reference: detail.verification_reference,\n };\n }\n\n if (!detail.session_token || !detail.digilocker_redirect_url) {\n throw new Error(\"Invalid response: missing session_token or digilocker_redirect_url\");\n }\n\n return {\n success: detail.success ?? true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: false,\n session_token: detail.session_token,\n digilocker_redirect_url: detail.digilocker_redirect_url,\n expires_at: detail.expires_at,\n };\n};\n\nexport const verifyGuardianStatus = async ({\n accessToken,\n baseUrl,\n sessionToken,\n signal,\n}: VerifyGuardianStatusParams): Promise<VerifyGuardianStatusResponse> => {\n // Guardian verification is JWT-only: sandbox sessions have no minor-notice /\n // guardian support (the server 403s them, and C1 blocks minor notices at\n // render), so no sandbox identity is wired through here.\n if (!accessToken || !sessionToken) {\n throw new Error(\"accessToken and sessionToken are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/verify-status`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ session_token: sessionToken }),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.detail?.message || \"Invalid session token\";\n } catch {\n errorMessage = \"Invalid session token\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 404)\n errorMessage = \"Verification session not found or expired. Please restart the verification process.\";\n else if (response.status === 410)\n errorMessage = \"Verification session has expired. Please restart the verification process.\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n return {\n status: detail.status ?? \"in_progress\",\n guardian_info_uuid: detail.guardian_info_uuid ?? null,\n verification_reference: detail.verification_reference ?? null,\n guardian_details: detail.guardian_details ?? null,\n error: detail.error ?? null,\n error_code: detail.error_code ?? null,\n can_retry: detail.can_retry ?? true,\n };\n};\n","import { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ConsentContent,\n DataElementSelection,\n FetchNoticeConsentStatusForScopeParams,\n FetchNoticeConsentStatusParams,\n LedgerConsentOverlay,\n NoticeConsentStatusResponse,\n PurposeSelection,\n} from \"./types\";\n\n/**\n * Go-ledger notice `check-consent` read.\n *\n * Post-cutover, consent records live in the Go ledger, so Python's notice\n * validation (which powered the 409 CONSENT_ALREADY_PROVIDED and the\n * `purpose_selections` / `reconsent_required` overlay) reads an empty consent\n * DB. When a `ledgerBaseUrl` is configured, the modal and the inline embed ask\n * the ledger directly instead.\n *\n * Every failure mode (no ledger configured, undecodable token, non-OK\n * response, network/abort/parse error) degrades to `null` so callers fall\n * back to the legacy Python-driven flow.\n */\n\n/**\n * Fetch the principal's current consent status for a notice from the Go\n * ledger (`check-consent`), with org/workspace supplied explicitly. The\n * principal resolves from the bearer token server-side, so the body is empty.\n * Returns null on any failure so the caller can fall back to the legacy flow.\n */\nexport const fetchNoticeConsentStatusForScope = async ({\n accessToken,\n ledgerBaseUrl,\n organisationUuid,\n workspaceUuid,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusForScopeParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {\n return null;\n }\n\n try {\n const response = await fetch(\n `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: \"{}\",\n signal,\n }\n );\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as\n | NoticeConsentStatusResponse\n | { detail?: NoticeConsentStatusResponse };\n // The ledger returns the response directly; tolerate a {detail} envelope too.\n const body =\n data && typeof data === \"object\" && \"detail\" in data && data.detail\n ? data.detail\n : (data as NoticeConsentStatusResponse);\n\n if (!body || !Array.isArray(body.purposes)) return null;\n return body;\n } catch {\n // Network / abort / parse failure — degrade to the legacy Python flow.\n return null;\n }\n};\n\n/**\n * Same read, resolving org/workspace by decoding the JWT (the modal's tokens\n * carry them). Returns null on any failure.\n */\nexport const fetchNoticeConsentStatus = async ({\n accessToken,\n ledgerBaseUrl,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !noticeUuid) return null;\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) return null;\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) return null;\n\n return fetchNoticeConsentStatusForScope({\n accessToken,\n ledgerBaseUrl,\n organisationUuid: ORG,\n workspaceUuid: WS,\n noticeUuid,\n signal,\n });\n};\n\n/**\n * Whether the principal has already fully consented to this notice with no\n * reconsent needed — the ledger equivalent of Python's 409\n * `CONSENT_ALREADY_PROVIDED`. Requires an active consent record with every\n * mandatory purpose still ACTIVE.\n */\nexport const isNoticeFullyConsented = (status: NoticeConsentStatusResponse): boolean =>\n status.consented && status.all_mandatory_active;\n\n/**\n * Translate the ledger's notice consent status into the\n * `{ purpose_selections, reconsent_required }` shape the modal already\n * consumes, so prior-consent pre-fill and reconsent categorization work off\n * the ledger. Returns null for a first-time principal (no consent record —\n * every purpose INACTIVE), preserving the normal first-time consent flow.\n *\n * `needs_reconsent` is derived from `status` (anything not ACTIVE needs\n * reconsent: expired / withdrawn / declined / inactive). NOTE: notice-version\n * reconsent is NOT covered — the ledger's check-consent has no version\n * awareness yet, so a republished-notice version bump won't re-prompt until\n * that lands on the ledger (tracked fast-follow).\n */\nexport const buildLedgerConsentOverlay = (\n status: NoticeConsentStatusResponse,\n configPurposes: ConsentContent[\"detail\"][\"active_config\"][\"purposes\"]\n): LedgerConsentOverlay | null => {\n const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));\n const hasHistory = status.purposes.some((p) => (p.status || \"INACTIVE\") !== \"INACTIVE\");\n if (!hasHistory) return null;\n\n const purpose_selections: Record<string, PurposeSelection> = {};\n for (const cp of configPurposes) {\n const lp = byUuid.get(cp.uuid);\n const purposeStatus = lp?.status || \"INACTIVE\";\n const selectedByUuid = new Map((lp?.data_elements || []).map((de) => [de.uuid, de.selected]));\n const data_elements: Record<string, DataElementSelection> = {};\n for (const de of cp.data_elements) {\n data_elements[de.uuid] = {\n selected: selectedByUuid.get(de.uuid) ?? false,\n enabled: de.enabled,\n required: de.required,\n };\n }\n purpose_selections[cp.uuid] = {\n selected: lp?.selected ?? false,\n status: purposeStatus,\n needs_reconsent: purposeStatus !== \"ACTIVE\",\n data_elements,\n };\n }\n\n const reconsent_required = configPurposes.some(\n (cp) => (purpose_selections[cp.uuid]?.status || \"INACTIVE\") !== \"ACTIVE\"\n );\n return { reconsent_required, purpose_selections };\n};\n","const STYLE_ID = \"redacto-consent-checkbox-styles\";\n\nconst STYLE_CONTENT = `\n /* Redacto Consent SDK Checkbox Styles */\n .redacto-checkbox-large {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 20px !important;\n width: 20px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-small {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 16px !important;\n width: 16px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-large:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-small:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-large:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 4px !important;\n height: 8px !important;\n border: solid white !important;\n border-width: 0 2px 2px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-small:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 3px !important;\n height: 6px !important;\n border: solid white !important;\n border-width: 0 1.5px 1.5px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-large:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n .redacto-checkbox-small:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n /* TTS Highlight Styles */\n .redacto-tts-highlight {\n position: relative !important;\n transition: background-color 0.3s ease, outline 0.3s ease !important;\n }\n\n h2.redacto-tts-highlight,\n h3.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n span.redacto-tts-highlight,\n a.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n p.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n button.redacto-tts-highlight {\n outline: 3px solid #FFF9C4 !important;\n outline-offset: 2px !important;\n }\n\n /* Overlay fade-in */\n @keyframes overlayFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n /* Spinner animation */\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* DigiLocker callback retry button hover */\n .redacto-dl-retry-btn:hover {\n background-color: #2563eb !important;\n }\n `;\n\n/**\n * Inject the checkbox / TTS / animation stylesheet into the given root.\n *\n * - When called with a `Document`, the style tag is placed in `document.head`.\n * - When called with a `ShadowRoot`, the style tag is placed inside the shadow\n * so it only applies within that shadow tree (full CSS isolation from the\n * host page).\n *\n * No-ops if the stylesheet is already present in the target root.\n */\nexport const injectCheckboxStyles = (\n root: Document | ShadowRoot\n): void => {\n if (typeof document === \"undefined\") return;\n\n // Skip if already injected into this root.\n const existing =\n root instanceof Document\n ? root.getElementById(STYLE_ID)\n : root.querySelector(`#${STYLE_ID}`);\n if (existing) return;\n\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = STYLE_CONTENT;\n\n if (root instanceof Document) {\n root.head.appendChild(style);\n } else {\n root.appendChild(style);\n }\n};\n","export const styles = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 999,\n animation: \"overlayFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1)\",\n pointerEvents: \"all\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n modal: {\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"700px\",\n borderRadius: \"8px\",\n backgroundColor: \"#ffffff\",\n boxShadow: \"4px 0px 4px 0px #00000040\",\n border: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n maxHeight: \"90vh\",\n zIndex: 1000,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n fontFamily: \"inherit\",\n },\n\n content: {\n margin: \"22px\",\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n overflow: \"hidden\",\n minHeight: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topLeft: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: \"1 1 0\",\n minWidth: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n // The main notice header is two stacked rows: the logo alone on row 1,\n // aligned per active_config.logo_position, then the title and the\n // TTS/language controls on row 2. `topSection` and `topLeft` above keep their\n // single-row shape for the age-verification, guardian and verification\n // screens, which have no controls to place and share those styles.\n // Mirrors consent-sdk-react/src/RedactoNoticeConsent/styles.ts.\n headerStack: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n logoRow: {\n display: \"flex\",\n alignItems: \"center\",\n width: \"100%\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n headerRow: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"10px\",\n width: \"100%\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n logo: {\n height: \"32px\",\n width: \"auto\",\n maxWidth: \"140px\",\n objectFit: \"contain\",\n flexShrink: 0,\n margin: 0,\n padding: 0,\n display: \"block\",\n },\n\n title: {\n fontSize: \"18px\",\n fontWeight: 700,\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#101828\",\n flex: \"1 1 auto\",\n minWidth: 0,\n wordBreak: \"normal\",\n overflowWrap: \"anywhere\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n topRight: {\n borderRadius: \"8px\",\n padding: \"3px 9px\",\n border: \"1px solid #d0d5dd\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#344054\",\n gap: \"5px\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n cursor: \"pointer\",\n backgroundColor: \"#ffffff\",\n },\n\n middleSection: {\n margin: \"0px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"12px\",\n flexGrow: 1,\n overflowY: \"auto\",\n minHeight: 0,\n paddingRight: \"15px\",\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n privacyText: {\n fontSize: \"16px\",\n fontWeight: 400,\n lineHeight: \"150%\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n link: {\n color: \"#4f87ff\",\n textDecoration: \"none\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n subTitle: {\n fontWeight: 600,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionsContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"10px\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n bottomSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n gap: \"29px\",\n paddingTop: \"15px\",\n borderTop: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n button: {\n width: \"100%\",\n borderRadius: \"8px\",\n padding: \"9px 45px\",\n fontWeight: 400,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n cursor: \"pointer\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"center\",\n },\n\n acceptButton: {\n backgroundColor: \"#4f87ff\",\n border: \"none\",\n color: \"#ffffff\",\n },\n\n cancelButton: {\n border: \"1px solid #d0d5dd\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n },\n\n languageSelectorContainer: {\n position: \"relative\",\n // Shares `headerRow` with the title, which grows; without this a long\n // heading squeezes the language button instead of wrapping itself.\n flexShrink: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n languageDropdown: {\n position: \"absolute\",\n top: \"100%\",\n right: 0,\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 2px 4px rgba(0, 0, 0, 0.1)\",\n zIndex: 10,\n width: \"max-content\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n marginTop: \"4px\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n languageItem: {\n padding: \"8px 12px\",\n cursor: \"pointer\",\n fontSize: \"12px\",\n color: \"#344054\",\n backgroundColor: \"#ffffff\",\n borderBottom: \"1px solid #e5e7eb\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n selectedLanguageItem: {\n backgroundColor: \"#f3f4f6\",\n fontWeight: 600,\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\n\nexport type ModalPurposeRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>;\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderModalPurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections?: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n isAlreadyConsented: boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string) => void;\n onPurposeCollapse: (purposeUuid: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string) => void;\n }\n): ModalPurposeRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n initialDataElementSelections = {},\n settings,\n isMobile,\n isAlreadyConsented,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#323B4B\";\n const textColor = settings?.textColor || \"#344054\";\n const font = settings?.font || \"inherit\";\n\n const container = el(\"div\", { style: styles.optionsContainer });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n\n // Chevron\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: headingColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[purpose.uuid] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(purpose.uuid, chevron);\n\n const chevronContainer = el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", justifyContent: \"center\", marginLeft: \"5px\" } },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n id: `purpose-name-${purpose.uuid}`,\n style: {\n ...styles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n titleElements.set(purpose.uuid, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n id: `purpose-description-${purpose.uuid}`,\n style: {\n ...styles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n fontFamily: font,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(purpose.uuid, descEl);\n\n const textContainer = el(\"div\", { style: styles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: styles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[purpose.uuid]),\n \"aria-controls\": `purpose-${purpose.uuid}`,\n \"aria-label\": `${collapsedPurposes[purpose.uuid] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(purpose.uuid, collapseBtn);\n\n // Purpose checkbox or green checkmark\n let rightElement: HTMLElement;\n if (!isAlreadyConsented) {\n const purposeCheckbox = el(\"input\", {\n className: \"redacto-checkbox-large\",\n type: \"checkbox\",\n checked: selectedPurposes[purpose.uuid] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(purpose.uuid, purposeCheckbox);\n rightElement = purposeCheckbox;\n } else {\n rightElement = createGreenCheckmark(\n 20,\n `Already consented to ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`\n );\n applyStyles(rightElement, { marginLeft: \"12px\" });\n }\n\n const optionRow = el(\"div\", { style: styles.optionItem }, collapseBtn, rightElement);\n\n // Data elements\n const deContainer = el(\"div\", {\n id: `purpose-${purpose.uuid}`,\n style: styles.dataElementsContainer,\n });\n\n if (purpose.data_elements?.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n id: `data-element-${purpose.uuid}-${dataElement.uuid}`,\n style: {\n ...styles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n fontFamily: font,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (dataElement.required) {\n const asterisk = el(\"span\", { style: { color: \"red\", marginLeft: \"4px\" }, \"aria-label\": \"required\" });\n asterisk.textContent = \"*\";\n labelSpan.appendChild(asterisk);\n }\n\n let deRightElement: HTMLElement;\n if (!isAlreadyConsented) {\n const deCheckbox = el(\"input\", {\n className: \"redacto-checkbox-small\",\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${dataElement.required ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n deRightElement = deCheckbox;\n } else {\n const wasSelected = initialDataElementSelections[combinedId] || false;\n if (wasSelected) {\n deRightElement = createGreenCheckmark(\n 16,\n `Consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`\n );\n } else {\n deRightElement = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"16px\",\n height: \"16px\",\n borderRadius: \"50%\",\n border: \"2px solid #d0d5dd\",\n backgroundColor: \"transparent\",\n },\n \"aria-label\": `Not consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`,\n });\n }\n }\n\n const deRow = el(\"div\", { style: styles.dataElementItem }, labelSpan, deRightElement);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(purpose.uuid, deContainer);\n deContainer.style.display = !collapsedPurposes[purpose.uuid] && purpose.data_elements?.length > 0 ? \"flex\" : \"none\";\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n\nfunction createGreenCheckmark(size: number, ariaLabel: string): HTMLElement {\n const svgSize = size === 20 ? 12 : 10;\n const strokeWidth = size === 20 ? \"2\" : \"1.5\";\n const pathD = size === 20 ? \"M4 6L5.5 7.5L8.5 4.5\" : \"M3 5L4.5 6.5L7.5 3.5\";\n\n const checkSvg = svg(\n \"svg\",\n {\n width: String(svgSize),\n height: String(svgSize),\n viewBox: `0 0 ${svgSize} ${svgSize}`,\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: pathD,\n stroke: \"white\",\n \"stroke-width\": strokeWidth,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n return el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: `${size}px`,\n height: `${size}px`,\n borderRadius: \"50%\",\n backgroundColor: \"#10B981\",\n },\n \"aria-label\": ariaLabel,\n }, checkSvg);\n}\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\n\nconst LANGUAGE_NATIVE_LABELS: Record<string, string> = {\n English: \"English\",\n Assamese: \"অসমীয়া (Assamese)\",\n Bengali: \"বাংলা (Bengali)\",\n Bodo: \"बड़ो (Bodo)\",\n Dogri: \"डोगरी (Dogri)\",\n \"Goan Konkani\": \"कोंकणी (Goan Konkani)\",\n Gujarati: \"ગુજરાતી (Gujarati)\",\n Hindi: \"हिन्दी (Hindi)\",\n Kannada: \"ಕನ್ನಡ (Kannada)\",\n Kashmiri: \"كٲشُر (Kashmiri)\",\n Maithili: \"मैथिली (Maithili)\",\n Malayalam: \"മലയാളം (Malayalam)\",\n Manipuri: \"ꯃꯩꯇꯩꯂꯣꯟ (Manipuri)\",\n Marathi: \"मराठी (Marathi)\",\n Nepali: \"नेपाली (Nepali)\",\n Odia: \"ଓଡ଼ିଆ (Odia)\",\n Punjabi: \"ਪੰਜਾਬੀ (Punjabi)\",\n Sanskrit: \"संस्कृतम् (Sanskrit)\",\n Santali: \"ᱥᱟᱱᱛᱟᱲᱤ (Santali)\",\n Sindhi: \"سنڌي (Sindhi)\",\n Tamil: \"தமிழ் (Tamil)\",\n Telugu: \"తెలుగు (Telugu)\",\n Urdu: \"اردو (Urdu)\",\n};\n\nconst toNativeLabel = (name: string): string => LANGUAGE_NATIVE_LABELS[name] ?? name;\n\nexport type LanguageSelectorRefs = {\n container: HTMLElement;\n button: HTMLElement;\n dropdown: HTMLElement;\n buttonText: HTMLElement;\n};\n\nexport function renderLanguageSelector(options: {\n languages: string[];\n selectedLanguage: string;\n settings?: Partial<Settings>;\n onSelect: (lang: string) => void;\n /**\n * Where the dropdown panel itself is appended. We append it as a sibling of\n * the modal (rather than inside `container`) so it can escape the modal's\n * `transform: translate(...)` stacking context. Pass the shadow root when\n * the modal is rendered inside a shadow boundary; otherwise pass\n * `document.body`.\n */\n dropdownContainer: HTMLElement | ShadowRoot;\n}): LanguageSelectorRefs {\n const { languages, selectedLanguage, settings, onSelect, dropdownContainer } = options;\n\n let isOpen = false;\n\n const buttonText = el(\"span\");\n buttonText.textContent = toNativeLabel(selectedLanguage);\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"8\",\n height: \"5\",\n viewBox: \"0 0 8 5\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n svg(\"path\", {\n d: \"M1 1L4 4L7 1\",\n stroke: settings?.button?.language?.textColor || \"#344054\",\n \"stroke-width\": \"1.5\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n const buttonStyle: Record<string, any> = { ...styles.topRight };\n if (settings?.button?.language) {\n buttonStyle.backgroundColor = settings.button.language.backgroundColor;\n buttonStyle.color = settings.button.language.textColor;\n }\n\n const button = el(\"div\", {\n style: buttonStyle,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": \"false\",\n \"aria-label\": `Language selector, current: ${toNativeLabel(selectedLanguage)}`,\n onClick: () => toggleDropdown(),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggleDropdown();\n } else if (e.key === \"Escape\") {\n closeDropdown();\n }\n },\n }, buttonText, chevronSvg);\n\n // Dropdown — uses position:fixed to escape modal's transform stacking context\n const dropdown = el(\"div\", {\n style: {\n position: \"fixed\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 4px 12px rgba(0, 0, 0, 0.15)\",\n zIndex: 2147483647, // max int — always on top\n minWidth: \"140px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n display: \"none\",\n },\n role: \"listbox\",\n \"aria-label\": \"Select language\",\n });\n\n for (const lang of languages) {\n const isSelected = lang === selectedLanguage;\n const itemStyle = isSelected\n ? { ...styles.languageItem, ...styles.selectedLanguageItem }\n : { ...styles.languageItem };\n\n if (settings?.button?.language) {\n if (isSelected && settings.button.language.selectedBackgroundColor) {\n itemStyle.backgroundColor = settings.button.language.selectedBackgroundColor;\n }\n if (isSelected && settings.button.language.selectedTextColor) {\n itemStyle.color = settings.button.language.selectedTextColor;\n }\n }\n\n const item = el(\"div\", {\n style: itemStyle,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n onClick: () => {\n onSelect(lang);\n closeDropdown();\n },\n onMouseenter: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = \"#f3f4f6\";\n },\n onMouseleave: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = isSelected ? \"#f3f4f6\" : \"#ffffff\";\n },\n });\n item.textContent = toNativeLabel(lang);\n dropdown.appendChild(item);\n }\n\n // Container only holds the button — dropdown is appended to its container\n // (shadow root in the modal flow, body for non-shadow callers) so it can\n // escape the modal's transform stacking context.\n const container = el(\"div\", { style: styles.languageSelectorContainer }, button);\n\n dropdownContainer.appendChild(dropdown);\n\n function positionDropdown() {\n const rect = button.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 4}px`;\n dropdown.style.right = `${window.innerWidth - rect.right}px`;\n dropdown.style.left = \"auto\";\n }\n\n // Click outside handler. When the modal is inside a shadow root the click\n // event's `target` is retargeted to the shadow host for listeners on the\n // document. `composedPath()` returns the real path through the shadow tree\n // so we can correctly detect whether the click originated inside the\n // selector or its dropdown.\n const clickOutsideHandler = (e: Event) => {\n const path = (e as Event & { composedPath?: () => EventTarget[] }).composedPath?.() ?? [];\n if (path.includes(container) || path.includes(dropdown)) return;\n\n // Fallback for environments without composedPath()\n if (path.length === 0) {\n const target = e.target as Node;\n if (container.contains(target) || dropdown.contains(target)) return;\n }\n closeDropdown();\n };\n\n // Reposition on scroll/resize while open\n const repositionHandler = () => {\n if (isOpen) positionDropdown();\n };\n\n function toggleDropdown() {\n isOpen ? closeDropdown() : openDropdown();\n }\n\n function openDropdown() {\n isOpen = true;\n positionDropdown();\n dropdown.style.display = \"block\";\n button.setAttribute(\"aria-expanded\", \"true\");\n setTimeout(() => {\n document.addEventListener(\"click\", clickOutsideHandler);\n }, 0);\n window.addEventListener(\"scroll\", repositionHandler, true);\n window.addEventListener(\"resize\", repositionHandler);\n }\n\n function closeDropdown() {\n isOpen = false;\n dropdown.style.display = \"none\";\n button.setAttribute(\"aria-expanded\", \"false\");\n document.removeEventListener(\"click\", clickOutsideHandler);\n window.removeEventListener(\"scroll\", repositionHandler, true);\n window.removeEventListener(\"resize\", repositionHandler);\n }\n\n return { container, button, dropdown, buttonText };\n}\n","/**\n * Focus trap + keyboard navigation for the modal.\n */\n\nexport type KeyboardTrapCleanup = () => void;\n\nexport function setupKeyboardTrap(\n modalEl: HTMLElement,\n onEscape: () => void\n): KeyboardTrapCleanup {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onEscape();\n return;\n }\n\n if (e.key === \"Tab\") {\n const focusableElements = modalEl.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusable = Array.from(focusableElements).filter(\n (el) => !el.hasAttribute(\"disabled\") && el.offsetParent !== null\n );\n\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n // When the modal lives inside a shadow root, document.activeElement\n // returns the shadow host rather than the actually focused element.\n // Read activeElement from the modal's own root for a correct answer.\n const root = modalEl.getRootNode() as Document | ShadowRoot;\n const active =\n (root as ShadowRoot).activeElement ?? document.activeElement;\n\n if (e.shiftKey) {\n if (active === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n\n document.addEventListener(\"keydown\", handler);\n\n // Auto-focus first focusable element\n requestAnimationFrame(() => {\n const firstFocusable = modalEl.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n firstFocusable?.focus();\n });\n\n return () => {\n document.removeEventListener(\"keydown\", handler);\n };\n}\n","import type { PersistedConsentState } from \"../api/types\";\n\nconst STORAGE_KEY = \"redacto_consent_sdk_state\";\nconst STATE_EXPIRY_MS = 30 * 60 * 1000; // 30 minutes\n\nconst isBrowser = (): boolean => {\n return typeof window !== \"undefined\" && typeof window.sessionStorage !== \"undefined\";\n};\n\nexport const saveConsentState = (state: PersistedConsentState): void => {\n if (!isBrowser()) {\n console.warn(\"SessionStorage not available - state not persisted\");\n return;\n }\n\n try {\n const stateWithTimestamp = {\n ...state,\n timestamp: new Date().toISOString(),\n };\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));\n } catch (error) {\n console.error(\"Failed to save consent state:\", error);\n }\n};\n\nexport const getConsentState = (): PersistedConsentState | null => {\n if (!isBrowser()) return null;\n\n try {\n const savedState = sessionStorage.getItem(STORAGE_KEY);\n if (!savedState) return null;\n\n const parsed: PersistedConsentState = JSON.parse(savedState);\n\n const stateAge = Date.now() - new Date(parsed.timestamp).getTime();\n if (stateAge > STATE_EXPIRY_MS) {\n clearConsentState();\n return null;\n }\n\n return parsed;\n } catch (error) {\n console.error(\"Failed to get consent state:\", error);\n return null;\n }\n};\n\nexport const clearConsentState = (): void => {\n if (!isBrowser()) return;\n\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch (error) {\n console.error(\"Failed to clear consent state:\", error);\n }\n};\n\nexport const updateConsentState = (updates: Partial<PersistedConsentState>): void => {\n const currentState = getConsentState();\n if (currentState) {\n saveConsentState({\n ...currentState,\n ...updates,\n timestamp: new Date().toISOString(),\n });\n }\n};\n\nexport const hasPendingVerification = (): boolean => {\n const state = getConsentState();\n return state !== null && state.flowState === \"digilocker-pending\";\n};\n\nexport const getVerificationResult = (): \"pending\" | \"verified\" | \"failed\" | \"in_progress\" | \"expired\" | null => {\n const state = getConsentState();\n return state?.verificationResult ?? null;\n};\n\nexport const getVerificationReference = (): string | null => {\n const state = getConsentState();\n return state?.verificationReference ?? null;\n};\n","import type { DpoInfoAudioKey, LogoPosition } from \"./api/types\";\n\nexport const DEFAULT_LOGO_POSITION: LogoPosition = \"left\";\n\n/**\n * `justify-content` for the logo row, keyed by the configured position. The row\n * is full width, so aligning it is the whole of the layout change.\n */\nexport const LOGO_POSITION_JUSTIFY: Record<LogoPosition, string> = {\n left: \"flex-start\",\n center: \"center\",\n right: \"flex-end\",\n};\n\nexport const DPO_AUDIO_ELEMENT_MAP: ReadonlyArray<{\n audioKey: DpoInfoAudioKey;\n elementId: string;\n}> = [\n { audioKey: \"grievance_text_audio_url\", elementId: \"dpo-grievance-text\" },\n { audioKey: \"grievance_anchor_text_audio_url\", elementId: \"dpo-grievance-link\" },\n { audioKey: \"grievance_email_connector_text_audio_url\", elementId: \"dpo-grievance-email-connector\" },\n { audioKey: \"grievance_email_audio_url\", elementId: \"dpo-grievance-email\" },\n { audioKey: \"dp_board_text_audio_url\", elementId: \"dpo-dp-board-text\" },\n { audioKey: \"dp_board_anchor_text_audio_url\", elementId: \"dpo-dp-board-link\" },\n { audioKey: \"dpo_text_audio_url\", elementId: \"dpo-dpo-text\" },\n { audioKey: \"dpo_anchor_text_audio_url\", elementId: \"dpo-dpo-link\" },\n] as const;\n","import { fetchTTSAudioUrls } from \"../api\";\nimport { DPO_AUDIO_ELEMENT_MAP } from \"../constants\";\nimport type {\n ActiveConfig,\n SandboxOptions,\n TTSAudioUrlsResponse,\n} from \"../api/types\";\n\nexport class TTSManager {\n private audioUrls: TTSAudioUrlsResponse[\"detail\"] | null = null;\n private audioSequence: string[] = [];\n private elementIdSequence: string[] = [];\n private currentAudio: HTMLAudioElement | null = null;\n private currentIndex = 0;\n private _isPlaying = false;\n private _isPaused = false;\n private _isAvailable = false;\n private highlightedElementId: string | null = null;\n private abortController: AbortController | null = null;\n private onStateChange: () => void;\n private root: Document | ShadowRoot;\n\n /**\n * @param onStateChange Invoked whenever playback state changes so the host\n * can refresh its UI (e.g. swap the play/pause icon).\n * @param root The root in which to look up highlightable elements by id.\n * When the modal is rendered inside a shadow root, pass that shadow root\n * so queries stay scoped to the SDK's tree (and don't accidentally hit\n * element ids that the host page also defines).\n */\n constructor(onStateChange: () => void, root: Document | ShadowRoot) {\n this.onStateChange = onStateChange;\n this.root = root;\n }\n\n get isPlaying(): boolean { return this._isPlaying; }\n get isPaused(): boolean { return this._isPaused; }\n get isAvailable(): boolean { return this._isAvailable; }\n\n async fetchAudioUrls(params: SandboxOptions & {\n accessToken?: string;\n baseUrl?: string;\n ledgerBaseUrl?: string;\n noticeUuid: string;\n language: string;\n content: ActiveConfig;\n }): Promise<void> {\n // Reset availability + sequences SYNCHRONOUSLY before notifying. The\n // language can change while a previous language's URLs are still loaded;\n // if we don't clear here, a click on the speaker icon (or the in-flight\n // stop()) would either keep the icon showing or replay the previous\n // language's audio. We then fire a single onStateChange() so the UI hides\n // the icon while the new language's audio is being fetched.\n this.stopInternal();\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n try {\n const response = await fetchTTSAudioUrls({\n accessToken: params.accessToken,\n baseUrl: params.baseUrl,\n ledgerBaseUrl: params.ledgerBaseUrl,\n noticeUuid: params.noticeUuid,\n language: params.language,\n signal: this.abortController.signal,\n token: params.token,\n sandboxUcic: params.sandboxUcic,\n sandboxSubject: params.sandboxSubject,\n organisationUuid: params.organisationUuid,\n workspaceUuid: params.workspaceUuid,\n });\n\n this.audioUrls = response.detail;\n this.buildSequences(params.content);\n // Only mark TTS as available if the backend actually returned playable\n // audio for this language. Some languages (e.g. Santali) come back with\n // a 200 but empty / partial fields — surfacing the speaker icon in that\n // case would let users click it and replay the previous language.\n this._isAvailable = this.audioSequence.length > 0;\n this.onStateChange();\n } catch (error) {\n if ((error as Error).name !== \"AbortError\") {\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n }\n }\n }\n\n private buildSequences(content: ActiveConfig): void {\n if (!this.audioUrls) return;\n const urls = this.audioUrls;\n\n const audioSeq: string[] = [];\n const elementSeq: string[] = [];\n\n const push = (url: string | undefined, elementId: string) => {\n if (url) {\n audioSeq.push(url);\n elementSeq.push(elementId);\n }\n };\n\n // 1. Notice banner heading\n push(urls.notice_banner_heading_audio_url, \"privacy-notice-title\");\n // 2. Notice text\n push(urls.notice_text_audio_url, \"privacy-notice-text\");\n // 3. Privacy policy prefix text\n push(urls.privacy_policy_prefix_text_audio_url, \"privacy-policy-text\");\n // 4. Privacy policy anchor text\n push(urls.privacy_policy_anchor_text_audio_url, \"privacy-policy-link\");\n // 5. Purpose section heading\n push(urls.purpose_section_heading_audio_url, \"purpose-section-heading\");\n\n // 6. For each purpose: name, description, data elements\n for (const purpose of content.purposes) {\n const purposeAudio = urls.purposes_audio?.[purpose.uuid];\n if (purposeAudio) {\n push(purposeAudio.name_audio_url, `purpose-name-${purpose.uuid}`);\n push(purposeAudio.description_audio_url, `purpose-description-${purpose.uuid}`);\n }\n\n for (const de of purpose.data_elements) {\n const deAudio = urls.data_elements_audio?.[de.uuid];\n if (deAudio) {\n push(deAudio.name_audio_url, `data-element-${purpose.uuid}-${de.uuid}`);\n }\n }\n }\n\n // 7. Additional text\n push(urls.additional_text_audio_url, \"additional-text\");\n // 8. Privacy center anchor text\n push(urls.privacy_center_anchor_text_audio_url, \"privacy-center-link\");\n\n // 9. DPO info audio\n if (urls.dpo_info_audio) {\n for (const mapping of DPO_AUDIO_ELEMENT_MAP) {\n const audioUrl = urls.dpo_info_audio[mapping.audioKey];\n push(audioUrl, mapping.elementId);\n }\n }\n\n // 10. Confirm / Decline buttons\n push(urls.confirm_button_text_audio_url, \"confirm-button-text\");\n push(urls.decline_button_text_audio_url, \"decline-button-text\");\n\n this.audioSequence = audioSeq;\n this.elementIdSequence = elementSeq;\n }\n\n toggle(): void {\n this._isPlaying ? this.pause() : this.play();\n }\n\n play(): void {\n if (this.audioSequence.length === 0) return;\n\n if (this._isPaused && this.currentAudio) {\n this.currentAudio.play()\n .then(() => {\n this._isPlaying = true;\n this._isPaused = false;\n this.onStateChange();\n })\n .catch(() => {});\n } else {\n const startIndex = this._isPlaying ? this.currentIndex : 0;\n this.playNextAudio(startIndex);\n }\n }\n\n pause(): void {\n if (this.currentAudio && this._isPlaying) {\n this.currentAudio.pause();\n this._isPlaying = false;\n this._isPaused = true;\n this.onStateChange();\n }\n }\n\n stop(): void {\n this.stopInternal();\n this.onStateChange();\n }\n\n /**\n * Internal stop used by code paths (like fetchAudioUrls) that will fire\n * their own onStateChange after composing a richer state update — we don't\n * want the intermediate notification to flicker the UI based on a half-set\n * state (e.g. _isAvailable still true from the previous language).\n */\n private stopInternal(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio.currentTime = 0;\n this.currentAudio = null;\n }\n this._isPlaying = false;\n this._isPaused = false;\n this.currentIndex = 0;\n this.removeHighlights();\n this.highlightedElementId = null;\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.stop();\n }\n\n private playNextAudio(index: number): void {\n if (index >= this.audioSequence.length) {\n this.stop();\n return;\n }\n\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio = null;\n }\n\n const audio = new Audio(this.audioSequence[index]);\n this.currentAudio = audio;\n this.currentIndex = index;\n this._isPlaying = true;\n this._isPaused = false;\n\n // Highlight\n const elementId = this.elementIdSequence[index];\n if (elementId) {\n this.highlightElement(elementId);\n }\n\n audio.onended = () => this.playNextAudio(index + 1);\n audio.onerror = () => {\n console.warn(`Failed to load audio at index ${index}`);\n this.playNextAudio(index + 1);\n };\n\n audio.play().catch((error) => {\n console.warn(`Failed to play audio at index ${index}:`, error);\n this._isPlaying = false;\n this.onStateChange();\n });\n\n this.onStateChange();\n }\n\n private highlightElement(elementId: string): void {\n this.removeHighlights();\n this.highlightedElementId = elementId;\n\n setTimeout(() => {\n // ShadowRoot has getElementById in modern browsers; fall back to\n // querySelector with CSS.escape for safety.\n const element =\n \"getElementById\" in this.root\n ? (this.root as Document | ShadowRoot & { getElementById(id: string): HTMLElement | null }).getElementById(elementId)\n : (this.root as ShadowRoot).querySelector<HTMLElement>(`#${CSS.escape(elementId)}`);\n if (element) {\n element.classList.add(\"redacto-tts-highlight\");\n\n const rect = element.getBoundingClientRect();\n const isVisible =\n rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth;\n\n if (!isVisible) {\n element.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }\n }\n }, 50);\n }\n\n private removeHighlights(): void {\n this.root.querySelectorAll(\".redacto-tts-highlight\").forEach((el) => {\n el.classList.remove(\"redacto-tts-highlight\");\n });\n }\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type AgeVerificationRefs = {\n container: HTMLElement;\n};\n\nexport function renderAgeVerification(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n onYes: () => void;\n onNo: () => void;\n onClose: () => void;\n}): AgeVerificationRefs {\n const { settings, colors, isMobile, logoUrl, onYes, onNo, onClose } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n\n // ─── Top Section (matches React: logo+title left, X button right) ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Redacto Logo\" });\n\n const title = el(\"h2\", {\n id: \"age-verification-title\",\n style: {\n ...styles.title,\n fontSize: isMobile ? \"16px\" : \"18px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Age Verification Required\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n\n const closeBtn = el(\"button\", {\n style: {\n background: \"none\",\n border: \"none\",\n color: headingColor,\n cursor: \"pointer\",\n padding: isMobile ? \"2px\" : \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Close modal\",\n onClick: onClose,\n });\n const closeSvg = svg(\n \"svg\",\n {\n width: isMobile ? \"18\" : \"20\",\n height: isMobile ? \"18\" : \"20\",\n viewBox: \"0 0 20 20\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: \"M15 5L5 15M5 5L15 15\",\n stroke: \"currentColor\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n closeBtn.appendChild(closeSvg);\n\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft, closeBtn);\n\n // ─── Middle Section ───\n const description = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"16px\",\n },\n });\n description.textContent = \"To proceed with this consent form, we need to verify your age.\";\n\n const question = el(\"p\", {\n style: {\n ...styles.subTitle,\n color: textColor,\n fontFamily: font,\n marginBottom: \"24px\",\n textAlign: \"left\",\n },\n });\n question.textContent = \"Are you 18 years of age or older?\";\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, color: textColor, fontFamily: font },\n }, description, question);\n\n // ─── Bottom Section (Yes first, No second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const yesBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Confirm that I am 18 years of age or older\",\n onClick: onYes,\n });\n yesBtn.textContent = \"Yes, I am 18 or older\";\n\n const noBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Indicate that I am under 18 years of age\",\n onClick: onNo,\n });\n noBtn.textContent = \"No, I am under 18\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, color: textColor, fontFamily: font },\n }, yesBtn, noBtn);\n\n // ─── Assemble (wrapped in content div like modal) ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nconst RELATIONSHIP_OPTIONS = [\n { value: \"Father\", label: \"Father\" },\n { value: \"Mother\", label: \"Mother\" },\n { value: \"Legal Guardian\", label: \"Legal Guardian\" },\n { value: \"Grandparent\", label: \"Grandparent\" },\n];\n\nexport type GuardianFormData = {\n guardianName: string;\n guardianContact: string;\n guardianRelationship: string;\n};\n\nexport type GuardianFormRefs = {\n container: HTMLElement;\n nameInput: HTMLInputElement;\n contactInput: HTMLInputElement;\n relationshipDisplay: HTMLElement;\n nameError: HTMLElement;\n contactError: HTMLElement;\n relationshipError: HTMLElement;\n submitBtn: HTMLButtonElement;\n generalError: HTMLElement;\n};\n\nexport function renderGuardianForm(options: {\n formData: GuardianFormData;\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isSubmitting: boolean;\n onSubmit: () => void;\n onCancel: () => void;\n onFieldChange: (field: keyof GuardianFormData, value: string) => void;\n}): GuardianFormRefs {\n const { formData, settings, colors, isMobile, logoUrl, isSubmitting, onSubmit, onCancel, onFieldChange } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const borderColor = colors.declineBorder;\n const bgColor = settings?.backgroundColor || \"#ffffff\";\n const radius = colors.borderRadius;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n const inputStyle: Record<string, any> = {\n width: \"100%\",\n padding: \"10px 12px\",\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n fontSize: \"13px\",\n fontFamily: font,\n color: textColor,\n backgroundColor: bgColor,\n marginBottom: \"2px\",\n boxSizing: \"border-box\",\n outline: \"none\",\n };\n\n const errorStyle: Record<string, any> = {\n color: \"#DC2626\",\n fontSize: \"11px\",\n marginTop: \"4px\",\n marginBottom: \"0px\",\n display: \"none\",\n };\n\n const labelStyle: Record<string, any> = {\n fontSize: \"13px\",\n fontWeight: 500,\n color: textColor,\n fontFamily: font,\n marginBottom: \"4px\",\n display: \"block\",\n };\n\n const hintStyle: Record<string, any> = {\n fontSize: \"11px\",\n color: \"#667085\",\n marginTop: \"2px\",\n marginBottom: \"0px\",\n lineHeight: \"1.4\",\n };\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"guardian-form-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const subtitle = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: \"13px\",\n lineHeight: \"1.5\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"12px\",\n },\n });\n subtitle.textContent = \"Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed.\";\n\n // Info banner with SVG icon\n const infoIcon = svg(\n \"svg\",\n {\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#2563EB\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"circle\", { cx: \"12\", cy: \"12\", r: \"10\" }),\n svg(\"line\", { x1: \"12\", y1: \"16\", x2: \"12\", y2: \"12\" }),\n svg(\"line\", { x1: \"12\", y1: \"8\", x2: \"12.01\", y2: \"8\" })\n );\n (infoIcon as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-top:1px\";\n\n const infoText = el(\"span\");\n infoText.textContent = \"The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document.\";\n\n const infoBanner = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"8px\",\n padding: \"10px 12px\",\n backgroundColor: \"#EFF6FF\",\n border: \"1px solid #BFDBFE\",\n borderRadius: radius,\n marginBottom: \"16px\",\n fontSize: \"12px\",\n lineHeight: \"1.5\",\n color: \"#1E40AF\",\n },\n }, infoIcon, infoText);\n\n // ─── Name field ───\n const nameLabel = el(\"label\", { for: \"guardianName\", style: labelStyle });\n nameLabel.innerHTML = `Guardian's Full Name <span style=\"color:#DC2626\">*</span>`;\n\n const nameInput = el(\"input\", {\n id: \"guardianName\",\n type: \"text\",\n style: inputStyle,\n value: formData.guardianName,\n placeholder: \"e.g. Rajesh Kumar\",\n autoComplete: \"name\",\n \"aria-describedby\": \"guardianName-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianName\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const nameHint = el(\"p\", { id: \"guardianName-hint\", style: hintStyle });\n nameHint.textContent = \"Enter the full name as per government ID (Aadhaar, PAN, etc.)\";\n\n const nameError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const nameGroup = el(\"div\", null, nameLabel, nameInput, nameHint, nameError);\n\n // ─── Contact field ───\n const contactLabel = el(\"label\", { for: \"guardianContact\", style: labelStyle });\n contactLabel.innerHTML = `Guardian's Phone Number <span style=\"color:#DC2626\">*</span>`;\n\n const contactInput = el(\"input\", {\n id: \"guardianContact\",\n type: \"tel\",\n inputMode: \"tel\",\n style: inputStyle,\n value: formData.guardianContact,\n placeholder: \"e.g. 9876543210\",\n autoComplete: \"tel\",\n \"aria-describedby\": \"guardianContact-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianContact\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const contactHint = el(\"p\", { id: \"guardianContact-hint\", style: hintStyle });\n contactHint.textContent = \"Mobile number linked to guardian's Aadhaar\";\n\n const contactError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const contactGroup = el(\"div\", null, contactLabel, contactInput, contactHint, contactError);\n\n // ─── Relationship dropdown ───\n const relLabel = el(\"label\", { id: \"guardianRelationship-label\", style: labelStyle });\n relLabel.innerHTML = `Relationship <span style=\"color:#DC2626\">*</span>`;\n\n const selectedLabel = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)?.label;\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#667085\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"6 9 12 15 18 9\" })\n );\n (chevronSvg as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-left:8px;transition:transform 0.2s\";\n\n const selectedSpan = el(\"span\", {\n style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" },\n });\n selectedSpan.textContent = selectedLabel || \"Select relationship\";\n\n const relationshipDisplay = el(\"div\", {\n role: \"combobox\",\n \"aria-expanded\": \"false\",\n \"aria-haspopup\": \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n tabIndex: \"0\",\n style: {\n ...inputStyle,\n color: selectedLabel ? textColor : \"#9CA3AF\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n userSelect: \"none\",\n transition: \"border-color 0.15s, box-shadow 0.15s\",\n },\n }, selectedSpan, chevronSvg);\n\n // Dropdown list\n const dropdownList = el(\"div\", {\n id: \"guardianRelationship-listbox\",\n role: \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n style: {\n position: \"absolute\",\n top: \"calc(100% + 4px)\",\n left: 0,\n right: 0,\n backgroundColor: bgColor,\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\",\n zIndex: 50,\n overflow: \"hidden\",\n padding: \"4px 0\",\n maxHeight: \"220px\",\n overflowY: \"auto\",\n display: \"none\",\n },\n });\n\n for (let i = 0; i < RELATIONSHIP_OPTIONS.length; i++) {\n const option = RELATIONSHIP_OPTIONS[i];\n const isSelected = formData.guardianRelationship === option.value;\n\n const optionEl = el(\"div\", {\n id: `guardianRelationship-option-${i}`,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n style: {\n padding: \"9px 12px\",\n fontSize: \"13px\",\n fontFamily: font,\n color: isSelected ? accentColor : textColor,\n backgroundColor: \"transparent\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n transition: \"background-color 0.1s\",\n },\n onClick: () => {\n onFieldChange(\"guardianRelationship\", option.value);\n selectedSpan.textContent = option.label;\n relationshipDisplay.style.color = textColor;\n doClose();\n },\n onMouseenter: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"#F3F4F6\"; },\n onMouseleave: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"transparent\"; },\n });\n\n const label = el(\"span\");\n label.textContent = option.label;\n optionEl.appendChild(label);\n\n if (isSelected) {\n const checkSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: accentColor, \"stroke-width\": \"2.5\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n (checkSvg as unknown as HTMLElement).style.flexShrink = \"0\";\n optionEl.appendChild(checkSvg);\n }\n\n dropdownList.appendChild(optionEl);\n }\n\n let dropdownOpen = false;\n\n const relContainer = el(\"div\", { style: { position: \"relative\" } });\n\n const handleClickOutside = (e: Event) => {\n if (!relContainer.contains(e.target as Node)) {\n doClose();\n }\n };\n\n function doOpen() {\n dropdownOpen = true;\n dropdownList.style.display = \"block\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"true\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(180deg)\";\n relationshipDisplay.style.borderColor = accentColor;\n relationshipDisplay.style.boxShadow = `0 0 0 1px ${accentColor}`;\n\n // Determine direction: open upward if not enough space below\n const rect = relContainer.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const dropdownHeight = 220;\n const shouldOpenUpward = spaceBelow < dropdownHeight && rect.top > dropdownHeight;\n\n if (shouldOpenUpward) {\n dropdownList.style.top = \"auto\";\n dropdownList.style.bottom = \"calc(100% + 4px)\";\n dropdownList.style.boxShadow = \"0 -4px 12px rgba(0,0,0,0.1), 0 -1px 3px rgba(0,0,0,0.06)\";\n } else {\n dropdownList.style.top = \"calc(100% + 4px)\";\n dropdownList.style.bottom = \"auto\";\n dropdownList.style.boxShadow = \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\";\n }\n\n // Scroll the dropdown into view\n requestAnimationFrame(() => {\n dropdownList.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n });\n\n // Listen for clicks outside (next tick so current click doesn't trigger it)\n setTimeout(() => document.addEventListener(\"mousedown\", handleClickOutside), 0);\n }\n\n function doClose() {\n dropdownOpen = false;\n dropdownList.style.display = \"none\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"false\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(0deg)\";\n relationshipDisplay.style.borderColor = borderColor;\n relationshipDisplay.style.boxShadow = \"none\";\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n\n relationshipDisplay.addEventListener(\"click\", () => {\n dropdownOpen ? doClose() : doOpen();\n });\n\n relationshipDisplay.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!dropdownOpen) doOpen();\n } else if (e.key === \"Escape\" || e.key === \"Tab\") {\n doClose();\n }\n });\n\n const relationshipError = el(\"div\", { style: errorStyle, role: \"alert\" });\n\n relContainer.appendChild(relLabel);\n relContainer.appendChild(relationshipDisplay);\n relContainer.appendChild(dropdownList);\n relContainer.appendChild(relationshipError);\n\n // General error\n const generalError = el(\"div\", {\n role: \"alert\",\n style: {\n color: \"#DC2626\",\n fontSize: \"13px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n display: \"none\",\n },\n });\n\n const fieldsContainer = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"14px\" },\n }, nameGroup, contactGroup, relContainer);\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, overflow: \"visible\", color: textColor, fontFamily: font },\n }, subtitle, infoBanner, fieldsContainer, generalError);\n\n // ─── Bottom Section (Verify first, Cancel second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const submitBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n disabled: isSubmitting,\n \"aria-label\": isSubmitting ? \"Verifying guardian identity\" : \"Proceed to guardian verification\",\n onClick: onSubmit,\n }) as HTMLButtonElement;\n submitBtn.textContent = isSubmitting ? \"Verifying...\" : \"Verify via DigiLocker\";\n\n const cancelBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Cancel\",\n onClick: onCancel,\n });\n cancelBtn.textContent = \"Cancel\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, paddingTop: \"12px\", color: textColor, fontFamily: font },\n }, submitBtn, cancelBtn);\n\n // ─── Assemble ───\n const container = el(\"div\", { style: { ...styles.content, overflow: \"visible\" } }, topSection, middleSection, bottomSection);\n\n return {\n container,\n nameInput,\n contactInput,\n relationshipDisplay,\n nameError,\n contactError,\n relationshipError,\n submitBtn,\n generalError,\n };\n}\n\nexport function validateGuardianForm(data: GuardianFormData): Record<string, string> {\n const errors: Record<string, string> = {};\n if (!data.guardianName.trim()) errors.guardianName = \"Guardian name is required\";\n if (!data.guardianContact.trim()) errors.guardianContact = \"Guardian contact is required\";\n if (!data.guardianRelationship.trim()) errors.guardianRelationship = \"Relationship to guardian is required\";\n return errors;\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings, GuardianVerificationErrorCode } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type VerificationScreenRefs = {\n container: HTMLElement;\n};\n\nexport function getVerificationErrorMessage(\n errorCode: string | null,\n fallbackError: string | null\n): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"The guardian must be 18 years or older. Please provide details of a different guardian.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker verification could not be completed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"DigiLocker did not return an authorization code. Please try again.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please try again.\";\n default:\n return fallbackError || \"Verification failed. Please try again.\";\n }\n}\n\nexport function renderVerificationScreen(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isInitiating: boolean;\n isPolling: boolean;\n isComplete: boolean;\n isAutoTransitioning?: boolean;\n error: string | null;\n errorCode: string | null;\n canRetry: boolean;\n onContinue: () => void;\n onBack: (clearName?: boolean) => void;\n}): VerificationScreenRefs {\n const {\n settings, colors, isMobile, logoUrl,\n isInitiating, isPolling, isComplete, isAutoTransitioning,\n error, errorCode, canRetry,\n onContinue, onBack,\n } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"verification-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const middleSection = el(\"div\", {\n style: {\n ...styles.middleSection,\n color: textColor,\n fontFamily: font,\n textAlign: \"center\",\n },\n });\n\n if (isComplete && !error) {\n // Success state: green checkmark circle\n const successCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#D1FAE5\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n });\n const checkSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#059669\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n successCircle.appendChild(checkSvg);\n\n const successText = el(\"p\", {\n style: {\n color: headingColor,\n fontFamily: font,\n fontSize: \"16px\",\n fontWeight: 600,\n lineHeight: \"1.5\",\n marginTop: \"12px\",\n marginBottom: \"24px\",\n },\n });\n successText.textContent = \"Verification Completed\";\n\n const wrapper = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flex: \"1\",\n },\n }, successCircle, successText);\n middleSection.appendChild(wrapper);\n\n } else if ((isInitiating || isPolling) && !error) {\n // Polling state: spinner + status message\n const spinner = el(\"div\", {\n style: {\n width: \"48px\",\n height: \"48px\",\n border: \"4px solid #e5e7eb\",\n borderTopColor: accentColor,\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n margin: \"24px auto\",\n },\n });\n\n const statusMsg = el(\"div\", {\n style: {\n color: \"#059669\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #A7F3D0\",\n backgroundColor: \"#D1FAE5\",\n textAlign: \"center\",\n },\n });\n statusMsg.textContent = isInitiating\n ? \"Opening DigiLocker in a new tab...\"\n : \"Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete.\";\n\n middleSection.appendChild(spinner);\n middleSection.appendChild(statusMsg);\n }\n\n if (error) {\n // Error state: red X circle + error text\n const errorCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#fee2e2\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n margin: \"24px auto\",\n },\n });\n const xSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#dc2626\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"line\", { x1: \"18\", y1: \"6\", x2: \"6\", y2: \"18\" }),\n svg(\"line\", { x1: \"6\", y1: \"6\", x2: \"18\", y2: \"18\" })\n );\n errorCircle.appendChild(xSvg);\n\n const failedText = el(\"p\", {\n style: {\n ...styles.privacyText,\n color: textColor,\n fontFamily: font,\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n marginBottom: \"12px\",\n },\n });\n failedText.textContent = \"Verification failed\";\n\n const errorBox = el(\"div\", {\n style: {\n color: \"#DC2626\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n },\n });\n errorBox.textContent = error;\n\n middleSection.appendChild(errorCircle);\n middleSection.appendChild(failedText);\n middleSection.appendChild(errorBox);\n }\n\n // ─── Bottom Section ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const bottomSection = el(\"div\", {\n style: {\n ...styles.bottomSection,\n paddingTop: \"12px\",\n display: \"flex\",\n gap: \"12px\",\n justifyContent: \"center\",\n color: textColor,\n fontFamily: font,\n },\n });\n\n const acceptBtnStyle = {\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n };\n const declineBtnStyle = {\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n };\n\n // Hide bottom section during auto-transition\n if (!isAutoTransitioning) {\n if (isComplete && !error) {\n const continueBtn = el(\"button\", {\n style: { ...btnBase, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": \"Continue to consent form\",\n onClick: onContinue,\n });\n continueBtn.textContent = \"Continue\";\n bottomSection.appendChild(continueBtn);\n } else if (error && canRetry) {\n const retryBtn = el(\"button\", {\n style: { ...btnBase, ...styles.acceptButton, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": errorCode === \"GUARDIAN_UNDER_18\" ? \"Change guardian details\" : \"Try verification again\",\n onClick: () => onBack(errorCode === \"GUARDIAN_UNDER_18\"),\n });\n retryBtn.textContent = errorCode === \"GUARDIAN_UNDER_18\" ? \"Change Guardian\" : \"Try Again\";\n bottomSection.appendChild(retryBtn);\n } else if (error) {\n const goBackBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Go back\",\n onClick: () => onBack(false),\n });\n goBackBtn.textContent = \"Go Back\";\n bottomSection.appendChild(goBackBtn);\n } else {\n // Polling state — show cancel\n const cancelBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Cancel verification\",\n onClick: () => onBack(false),\n });\n cancelBtn.textContent = \"Cancel\";\n bottomSection.appendChild(cancelBtn);\n }\n }\n\n // ─── Assemble ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import type { ActiveConfig, Settings } from \"../api/types\";\n\nexport type ResolvedColors = {\n acceptBg: string;\n acceptText: string;\n declineBg: string;\n declineText: string;\n declineBorder: string;\n link: string;\n heading: string;\n text: string;\n font: string;\n borderRadius: string;\n primaryColor: string;\n secondaryColor: string;\n};\n\n/**\n * Resolves colors using the React SDK's fallback chain:\n * settings → API active_config → hardcoded default\n */\nexport function resolveColors(\n settings: Partial<Settings> | undefined,\n activeConfig: ActiveConfig | null | undefined\n): ResolvedColors {\n const primaryColor = activeConfig?.primary_color || \"#4f87ff\";\n const secondaryColor = activeConfig?.secondary_color || \"#4f87ff\";\n\n return {\n acceptBg: settings?.button?.accept?.backgroundColor || primaryColor,\n acceptText: settings?.button?.accept?.textColor || \"#ffffff\",\n declineBg: settings?.button?.decline?.backgroundColor || \"#ffffff\",\n declineText: settings?.button?.decline?.textColor || \"#000000\",\n declineBorder: settings?.borderColor || \"#d0d5dd\",\n link: settings?.link || secondaryColor,\n heading: settings?.headingColor || \"#323B4B\",\n text: settings?.textColor || \"#344054\",\n font: settings?.font || \"inherit\",\n borderRadius: settings?.borderRadius || \"8px\",\n primaryColor,\n secondaryColor,\n };\n}\n","import type { LogoPosition } from \"../api/types\";\nimport { DEFAULT_LOGO_POSITION, LOGO_POSITION_JUSTIFY } from \"../constants\";\n\n/**\n * Resolves `active_config.logo_position` onto a position the header can lay out.\n *\n * The field is absent on notices published before it existed and on responses\n * from an older consent-server, so an unrecognised value is not an error — it\n * simply means \"the customer never chose\", which is the left-aligned default.\n *\n * Sibling of `resolveColors` in ./colors.ts: same config-then-default shape,\n * kept deliberately parallel with the React package's layout.ts.\n */\nexport function resolveLogoPosition(raw: string | undefined | null): LogoPosition {\n return raw === \"center\" || raw === \"right\" ? raw : DEFAULT_LOGO_POSITION;\n}\n\nexport function logoRowJustify(position: LogoPosition): string {\n return LOGO_POSITION_JUSTIFY[position];\n}\n","import { Store } from \"../core/state\";\nimport { el, svg, clearElement } from \"../core/dom\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport {\n fetchConsentContent,\n submitConsentEvent,\n fetchTTSAudioUrls,\n initiateGuardianVerification,\n verifyGuardianStatus,\n} from \"../api\";\nimport {\n buildLedgerConsentOverlay,\n fetchNoticeConsentStatus,\n} from \"../api/notice-consent-status\";\nimport { resolveDisplayLanguage } from \"../api/language\";\nimport { clearApiCache } from \"../services/cache\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { styles } from \"../styles/modal\";\nimport { renderModalPurposes, type ModalPurposeRefs } from \"./purposes\";\nimport { renderLanguageSelector, type LanguageSelectorRefs } from \"./language-selector\";\nimport { setupKeyboardTrap, type KeyboardTrapCleanup } from \"./keyboard\";\nimport {\n saveConsentState,\n getConsentState,\n clearConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport { TTSManager } from \"./tts\";\nimport { renderAgeVerification } from \"./age-verification\";\nimport {\n renderGuardianForm,\n validateGuardianForm,\n type GuardianFormData,\n type GuardianFormRefs,\n} from \"./guardian-form\";\nimport {\n renderVerificationScreen,\n getVerificationErrorMessage,\n} from \"./verification-screen\";\nimport { resolveColors } from \"./colors\";\nimport { logoRowJustify, resolveLogoPosition } from \"./layout\";\nimport type { SandboxOptions } from \"../api/types\";\nimport type { ModalOptions } from \"../types\";\nimport type {\n ActiveConfig,\n ConsentContent,\n PurposeItemData,\n PurposeSelection,\n Settings,\n TranslationObject,\n} from \"../api/types\";\n\ntype ModalState = {\n isLoading: boolean;\n isSubmitting: boolean;\n isSubmittingAccept: boolean;\n isSubmittingDecline: boolean;\n content: ConsentContent | null;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n isFullyConsentedReviewMode: boolean;\n selectedLanguage: string;\n errorMessage: string | null;\n fetchError: Error | null;\n needsConsentPurposes: PurposeItemData[];\n alreadyConsentedPurposes: PurposeItemData[];\n // Age/Guardian flow\n isMinorFlow: boolean;\n selfDeclaredAdult: boolean;\n showAgeVerification: boolean;\n showGuardianForm: boolean;\n showVerificationScreen: boolean;\n verificationReference: string | null;\n isVerificationComplete: boolean;\n isInitiatingVerification: boolean;\n isPollingStatus: boolean;\n verificationError: string | null;\n verificationErrorCode: string | null;\n canRetryVerification: boolean;\n guardianFormData: GuardianFormData;\n};\n\nexport class ModalController {\n private store: Store<ModalState>;\n private options: ModalOptions;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private previousBodyOverflow: string | null = null;\n private previousHtmlOverflow: string | null = null;\n private overlayEl: HTMLElement | null = null;\n private modalEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: ModalPurposeRefs | null = null;\n private alreadyConsentedPurposeRefs: ModalPurposeRefs | null = null;\n private langSelectorRefs: LanguageSelectorRefs | null = null;\n private keyboardCleanup: KeyboardTrapCleanup | null = null;\n private abortController: AbortController | null = null;\n private unsubscribe: (() => void) | null = null;\n private ttsManager: TTSManager | null = null;\n private guardianFormRefs: GuardianFormRefs | null = null;\n private statusPollTimeout: ReturnType<typeof setTimeout> | null = null;\n private popupCheckInterval: ReturnType<typeof setInterval> | null = null;\n private verificationPopup: Window | null = null;\n private verificationSessionToken: string | null = null;\n private visibilityChangeHandler: (() => void) | null = null;\n\n // DOM refs for targeted updates\n private acceptBtn: HTMLButtonElement | null = null;\n private declineBtn: HTMLButtonElement | null = null;\n private middleSection: HTMLElement | null = null;\n private errorEl: HTMLElement | null = null;\n private noticeTitleEl: HTMLElement | null = null;\n private noticeTextEl: HTMLElement | null = null;\n private purposeHeadingEl: HTMLElement | null = null;\n private additionalTextEl: HTMLElement | null = null;\n private privacyPolicyLinkEl: HTMLAnchorElement | null = null;\n private privacyCenterLinkEl: HTMLAnchorElement | null = null;\n private ttsButton: HTMLElement | null = null;\n\n constructor(options: ModalOptions) {\n this.options = options;\n this.store = new Store<ModalState>({\n isLoading: true,\n isSubmitting: false,\n isSubmittingAccept: false,\n isSubmittingDecline: false,\n content: null,\n selectedPurposes: {},\n selectedDataElements: {},\n initialDataElementSelections: {},\n collapsedPurposes: {},\n hasAlreadyConsented: false,\n isFullyConsentedReviewMode: false,\n selectedLanguage: options.language || \"en\",\n errorMessage: null,\n fetchError: null,\n needsConsentPurposes: [],\n alreadyConsentedPurposes: [],\n isMinorFlow: false,\n selfDeclaredAdult: false,\n showAgeVerification: false,\n showGuardianForm: false,\n showVerificationScreen: false,\n verificationReference: null,\n isVerificationComplete: false,\n isInitiatingVerification: false,\n isPollingStatus: false,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n // TTSManager is instantiated lazily in renderOverlayWithLoading() once the\n // shadow root exists, so it can scope its DOM queries inside the shadow.\n }\n\n async init(): Promise<void> {\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderOverlayWithLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.keyboardCleanup?.();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.ttsManager?.destroy();\n this.stopPolling();\n this.store.destroy();\n\n // Removing the shadow host nukes the entire shadow tree (overlay, modal,\n // language dropdown, injected stylesheet) in a single operation.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n\n // Restore the host page's scroll lock to whatever it was before we opened.\n if (this.previousBodyOverflow !== null) {\n document.body.style.overflow = this.previousBodyOverflow;\n this.previousBodyOverflow = null;\n }\n if (this.previousHtmlOverflow !== null) {\n document.documentElement.style.overflow = this.previousHtmlOverflow;\n this.previousHtmlOverflow = null;\n }\n\n this.hostEl = null;\n this.shadowRoot = null;\n this.overlayEl = null;\n this.modalEl = null;\n this.purposeRefs = null;\n this.langSelectorRefs = null;\n }\n\n // ─── Private ───\n\n /**\n * Sandbox auth options to forward to every API call. When `token` is set the\n * API layer sends the single `X-Consent-Token` header, injects the subject\n * into each request's payload, and reads org/workspace from these fields\n * instead of decoding the JWT. Empty in the normal JWT flow.\n */\n private sandboxParams(): SandboxOptions {\n return {\n token: this.options.token,\n // The static token carries no identity; read the acting principal from the\n // optional ucic/email/mobile. UCIC takes precedence server-side.\n // sandboxUcic / sandboxSubject stay as fallbacks.\n sandboxUcic: this.options.ucic || this.options.sandboxUcic,\n sandboxSubject:\n this.options.email || this.options.mobile || this.options.sandboxSubject,\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n };\n }\n\n private async fetchNotice(): Promise<void> {\n this.abortController = new AbortController();\n this.store.setState({ isLoading: true, fetchError: null });\n\n try {\n // Standard flow reads the notice from the Go ledger. The magic-link flow\n // (applicationId/specific_uuid) and sandbox sessions stay on the consent\n // server: the ledger notice read supports neither (no specific_uuid, no\n // X-Consent-Token auth). Without this a ledger-minted token is rejected\n // by the consent server and the modal renders with no content.\n const noticeBaseUrl =\n this.options.ledgerBaseUrl &&\n !this.options.applicationId &&\n !this.options.token\n ? this.options.ledgerBaseUrl\n : this.options.baseUrl;\n const data = await fetchConsentContent({\n noticeId: this.options.noticeId,\n accessToken: this.options.accessToken,\n refreshToken: this.options.refreshToken,\n baseUrl: noticeBaseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n validate_against: this.options.validateAgainst || \"all\",\n include_fully_consented_data: this.options.includeFullyConsentedData,\n signal: this.abortController.signal,\n ...this.sandboxParams(),\n });\n\n const activeConfig = data.detail.active_config;\n\n // Overlay the prior-consent / reconsent state from the Go ledger's\n // check-consent. Consents live in the ledger post-cutover, so Python's\n // notice-validation overlay is empty; the notice text/config still comes\n // from Python (above). Falls back to the Python-provided values when the\n // ledger is unavailable, and is skipped for the magic-link flow\n // (applicationId), which pre-fills from a specific event.\n let purposeSelections = data.detail.purpose_selections;\n let reconsentRequired = data.detail.reconsent_required;\n let ledgerOverlayApplied = false;\n if (this.options.ledgerBaseUrl && !this.options.applicationId) {\n const ledgerStatus = await fetchNoticeConsentStatus({\n accessToken: this.options.accessToken,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: this.options.noticeId,\n signal: this.abortController.signal,\n });\n if (ledgerStatus) {\n const overlay = buildLedgerConsentOverlay(ledgerStatus, activeConfig.purposes);\n reconsentRequired = overlay?.reconsent_required ?? false;\n purposeSelections = overlay?.purpose_selections;\n ledgerOverlayApplied = Boolean(overlay);\n }\n }\n\n // Initialize state\n const initialCollapsed: Record<string, boolean> = {};\n const initialPurposes: Record<string, boolean> = {};\n const initialElements: Record<string, boolean> = {};\n const initialDataElementSelections: Record<string, boolean> = {};\n\n // Categorize purposes for reconsent. With a ledger overlay, categorize\n // whenever prior consent exists (even without reconsent needed) so a\n // fully-consented principal gets the already-consented presentation /\n // review mode instead of a fresh consent flow — the ledger-mode\n // equivalent of Python's 409-driven short-circuit.\n let needsConsentPurposes: PurposeItemData[] = [];\n let alreadyConsentedPurposes: PurposeItemData[] = [];\n let isFullyConsentedReviewMode = false;\n\n if (purposeSelections && (reconsentRequired || ledgerOverlayApplied)) {\n for (const purpose of activeConfig.purposes) {\n const selection = purposeSelections[purpose.uuid];\n initialCollapsed[purpose.uuid] = true;\n\n if (selection && selection.selected && !selection.needs_reconsent) {\n alreadyConsentedPurposes.push(purpose);\n initialPurposes[purpose.uuid] = true;\n for (const de of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${de.uuid}`;\n const deSelection = selection.data_elements?.[de.uuid];\n const wasSelected = deSelection?.selected || false;\n initialElements[combinedId] = wasSelected;\n initialDataElementSelections[combinedId] = wasSelected;\n }\n } else {\n needsConsentPurposes.push(purpose);\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n }\n } else {\n needsConsentPurposes = activeConfig.purposes;\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n }\n\n // Check if all purposes are already consented (review mode)\n if (\n this.options.includeFullyConsentedData &&\n needsConsentPurposes.length === 0 &&\n alreadyConsentedPurposes.length > 0\n ) {\n isFullyConsentedReviewMode = true;\n }\n\n const selectedLanguage = resolveDisplayLanguage(\n this.options.language,\n activeConfig.default_language,\n activeConfig.supported_languages_and_translations\n );\n\n // Check if minor flow is required, and restore in-progress verification\n // state from a previous session (e.g. user closed the SDK or returned\n // from a DigiLocker redirect mid-flow). Without this restoration, the\n // notice would be shown directly and guardian verification skipped.\n let isMinorFlow = false;\n let showAgeVerification = false;\n let restoreState: Partial<ModalState> = {};\n let pollingTokenToResume: string | null = null;\n if (data.detail.is_minor) {\n isMinorFlow = true;\n const persistedState = getConsentState();\n\n // Discard persisted state from a different notice\n if (persistedState?.noticeId && persistedState.noticeId !== this.options.noticeId) {\n clearConsentState();\n } else if (\n persistedState?.flowState === \"digilocker-pending\" &&\n persistedState.sessionToken\n ) {\n // User is mid-verification — resume the verification screen and polling\n restoreState = {\n showVerificationScreen: true,\n isPollingStatus: true,\n };\n pollingTokenToResume = persistedState.sessionToken;\n } else if (\n persistedState?.verificationResult === \"verified\" &&\n persistedState.verificationReference\n ) {\n // Verification completed during a redirect — show success state\n restoreState = {\n showVerificationScreen: true,\n isVerificationComplete: true,\n verificationReference: persistedState.verificationReference,\n };\n clearConsentState();\n } else if (\n persistedState?.verificationResult === \"failed\" ||\n persistedState?.verificationResult === \"expired\"\n ) {\n // Verification failed/expired during a redirect — show error\n restoreState = {\n showVerificationScreen: true,\n verificationError:\n persistedState.verificationResult === \"expired\"\n ? \"Verification session has expired. Please try again.\"\n : \"Verification failed. Please try again.\",\n canRetryVerification: true,\n };\n clearConsentState();\n } else {\n // No in-progress verification — start with age verification\n showAgeVerification = true;\n }\n }\n\n this.store.setState({\n content: data,\n isLoading: false,\n selectedLanguage,\n collapsedPurposes: initialCollapsed,\n selectedPurposes: initialPurposes,\n selectedDataElements: initialElements,\n initialDataElementSelections,\n needsConsentPurposes,\n alreadyConsentedPurposes,\n isFullyConsentedReviewMode,\n isMinorFlow,\n showAgeVerification,\n ...restoreState,\n });\n\n // Resume polling after state has been applied so the verification screen\n // is visible while polling runs.\n if (pollingTokenToResume) {\n this.startStatusPolling(pollingTokenToResume);\n }\n } catch (err: unknown) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private handleStateChange(state: ModalState, prevState: ModalState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n return;\n }\n\n // Already consented → close\n if (state.hasAlreadyConsented && !prevState.hasAlreadyConsented) {\n this.destroy();\n return;\n }\n\n // Fetch error → show error\n if (state.fetchError && !prevState.fetchError) {\n this.renderError(state.fetchError.message);\n return;\n }\n\n // Screen transitions (age → guardian → verification → consent)\n if (state.showAgeVerification !== prevState.showAgeVerification ||\n state.showGuardianForm !== prevState.showGuardianForm ||\n state.showVerificationScreen !== prevState.showVerificationScreen) {\n this.rebuildUI();\n return;\n }\n\n // Verification screen state changes\n if (state.showVerificationScreen && (\n state.isVerificationComplete !== prevState.isVerificationComplete ||\n state.verificationError !== prevState.verificationError ||\n state.isPollingStatus !== prevState.isPollingStatus ||\n state.isInitiatingVerification !== prevState.isInitiatingVerification)) {\n this.rebuildUI();\n return;\n }\n\n // Checkbox changes\n if (\n state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements\n ) {\n this.updateCheckboxes(state);\n }\n\n // Collapse changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n\n // Submitting state\n if (state.isSubmittingAccept !== prevState.isSubmittingAccept ||\n state.isSubmittingDecline !== prevState.isSubmittingDecline) {\n this.updateButtonStates(state);\n }\n }\n\n private renderOverlayWithLoading(): void {\n // Mount a single host <div> on document.body and attach an open shadow\n // root. All overlay, modal, and stylesheet content lives inside the shadow\n // so the host page's CSS cannot bleed in (and vice versa). This is what\n // makes the SDK render identically across customer sites and WordPress\n // installs that ship aggressive global stylesheets / accessibility plugins.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent\", \"\");\n // Lock the host to a zero-size, fixed-position box so it cannot perturb a\n // flex / grid body layout. We deliberately DO NOT reset inherited text\n // properties (font-family, color, line-height) — those flow through the\n // shadow boundary so the modal picks up the host page's font, matching\n // how the React SDK renders.\n this.hostEl.style.position = \"fixed\";\n this.hostEl.style.top = \"0\";\n this.hostEl.style.left = \"0\";\n this.hostEl.style.width = \"0\";\n this.hostEl.style.height = \"0\";\n this.hostEl.style.zIndex = \"2147483646\";\n document.body.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n\n // Lock background scroll on the host page while the modal is open. We\n // capture the previous values so destroy() can restore exactly what was\n // there (including the empty string, which means \"use stylesheet rule\").\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n\n // Inject SDK stylesheet into the shadow root (not document.head).\n injectCheckboxStyles(this.shadowRoot);\n\n // Lazy-instantiate TTSManager now that we have a root for it to query.\n this.ttsManager = new TTSManager(\n () => this.updateTTSButton(),\n this.shadowRoot\n );\n\n const blockUI = this.options.blockUI !== false;\n\n if (blockUI) {\n this.overlayEl = el(\"div\", {\n style: styles.overlay,\n role: \"presentation\",\n });\n this.shadowRoot.appendChild(this.overlayEl);\n }\n\n const settingsObj = this.options.settings;\n const modalStyle = { ...styles.modal } as Record<string, any>;\n if (settingsObj?.backgroundColor) modalStyle.backgroundColor = settingsObj.backgroundColor;\n if (settingsObj?.borderRadius) modalStyle.borderRadius = settingsObj.borderRadius;\n if (settingsObj?.borderColor) modalStyle.border = `1px solid ${settingsObj.borderColor}`;\n if (settingsObj?.font) modalStyle.fontFamily = settingsObj.font;\n if (this.mediaQuery.matches) {\n modalStyle.width = \"90%\";\n modalStyle.maxWidth = \"90%\";\n }\n\n this.modalEl = el(\"div\", {\n style: modalStyle,\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"aria-label\": \"Privacy consent\",\n });\n\n // Loading content\n const loadingEl = el(\n \"div\",\n { style: styles.loadingContainer },\n el(\"div\", { style: styles.loadingSpinner }),\n el(\"p\", { style: { ...styles.privacyText, color: settingsObj?.textColor || \"#344054\" } }, \"Loading...\")\n );\n\n const contentEl = el(\"div\", { style: styles.content }, loadingEl);\n this.modalEl.appendChild(contentEl);\n this.shadowRoot.appendChild(this.modalEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.modalEl) return;\n\n const activeConfig = state.content.detail.active_config;\n const settingsObj = this.options.settings;\n const isMobile = this.mediaQuery.matches;\n const colors = resolveColors(settingsObj, activeConfig);\n\n // ─── Age Verification Screen ───\n if (state.showAgeVerification) {\n clearElement(this.modalEl);\n const ageRefs = renderAgeVerification({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n onYes: () => this.handleAgeVerificationYes(),\n onNo: () => this.handleAgeVerificationNo(),\n onClose: () => this.handleDecline(),\n });\n this.modalEl.appendChild(ageRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Guardian Form Screen ───\n if (state.showGuardianForm) {\n clearElement(this.modalEl);\n this.guardianFormRefs = renderGuardianForm({\n formData: state.guardianFormData,\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isSubmitting: state.isInitiatingVerification,\n onSubmit: () => this.handleGuardianFormSubmit(),\n onCancel: () => this.handleDecline(),\n onFieldChange: (field, value) => {\n const s = this.store.getState();\n this.store.setState({\n guardianFormData: { ...s.guardianFormData, [field]: value },\n });\n },\n });\n this.modalEl.appendChild(this.guardianFormRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Verification Screen ───\n if (state.showVerificationScreen) {\n clearElement(this.modalEl);\n const verRefs = renderVerificationScreen({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isInitiating: state.isInitiatingVerification,\n isPolling: state.isPollingStatus,\n isComplete: state.isVerificationComplete,\n error: state.verificationError,\n errorCode: state.verificationErrorCode,\n canRetry: state.canRetryVerification,\n onContinue: () => this.handleVerificationContinue(),\n onBack: (clearName?: boolean) => {\n if (clearName) {\n this.handleChangeGuardian();\n } else if (state.verificationError && state.canRetryVerification) {\n this.handleVerificationRetry();\n } else {\n this.handleDecline();\n }\n },\n });\n this.modalEl.appendChild(verRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => {});\n return;\n }\n\n // Clear modal content\n clearElement(this.modalEl);\n\n const headingColor = settingsObj?.headingColor || \"#101828\";\n const textColor = colors.text;\n const linkColor = colors.link;\n const font = colors.font;\n\n // ─── Top Section ───\n const logoImg = activeConfig.logo_url\n ? el(\"img\", {\n src: activeConfig.logo_url,\n style: {\n ...styles.logo,\n maxWidth: isMobile ? \"96px\" : \"140px\",\n maxHeight: isMobile ? \"28px\" : \"32px\",\n },\n alt: \"Logo\",\n })\n : null;\n\n this.noticeTitleEl = el(\"span\", {\n id: \"privacy-notice-title\",\n style: { ...styles.title, color: headingColor, fontFamily: font, fontSize: isMobile ? \"16px\" : \"18px\" },\n });\n this.noticeTitleEl.textContent = this.getTranslatedText(\"notice_banner_heading\", activeConfig.notice_banner_heading);\n\n // Clean up previous language dropdown (since rebuildUI re-creates it).\n // The dropdown lives inside the shadow root (sibling of the modal) so we\n // remove it from there.\n if (\n this.langSelectorRefs?.dropdown &&\n this.shadowRoot &&\n this.langSelectorRefs.dropdown.parentNode === this.shadowRoot\n ) {\n this.shadowRoot.removeChild(this.langSelectorRefs.dropdown);\n }\n\n // Language selector\n const supportedLangs = Object.keys(activeConfig.supported_languages_and_translations || {});\n const allLanguages = [activeConfig.default_language || \"English\", ...supportedLangs.filter((l) => l !== activeConfig.default_language)];\n\n this.langSelectorRefs = renderLanguageSelector({\n languages: allLanguages,\n selectedLanguage: state.selectedLanguage,\n settings: settingsObj,\n onSelect: (lang) => this.handleLanguageSelect(lang),\n dropdownContainer: this.shadowRoot!,\n });\n\n // TTS button with SVG speaker icon (matches React)\n const ttsStrokeColor = settingsObj?.button?.language?.textColor || \"currentColor\";\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: ttsStrokeColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n\n this.ttsButton = el(\"button\", {\n style: {\n ...styles.topRight,\n display: \"none\",\n padding: \"3px 9px\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Start audio playback\",\n title: \"Start Talkback\",\n onClick: () => this.ttsManager?.toggle(),\n });\n this.ttsButton.appendChild(speakerSvg);\n\n // Fetch TTS audio (the API uses \"English\" for English, not \"en\")\n this.ttsManager?.fetchAudioUrls({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: activeConfig.notice_uuid,\n language: this.getLanguageCode(state.selectedLanguage),\n content: activeConfig,\n ...this.sandboxParams(),\n });\n\n // TTS button on LEFT, language selector on RIGHT (matches React)\n const topRight = el(\"div\", {\n style: { display: \"flex\", alignItems: \"center\", gap: \"8px\", flexShrink: 0 },\n }, this.ttsButton, this.langSelectorRefs.container);\n\n // Two stacked rows at every breakpoint: the logo alone on row 1, aligned\n // per the admin-chosen position, then title + controls on row 2.\n const logoPosition = resolveLogoPosition(activeConfig.logo_position);\n const headerRows: HTMLElement[] = [];\n // Row 1 only exists when there is a logo. This package has no bundled\n // fallback (unlike React), so rendering it regardless would leave nothing\n // but the headerStack gap — a phantom band above the title.\n if (logoImg) {\n headerRows.push(\n el(\n \"div\",\n { style: { ...styles.logoRow, justifyContent: logoRowJustify(logoPosition) } },\n logoImg\n )\n );\n }\n headerRows.push(el(\"div\", { style: styles.headerRow }, this.noticeTitleEl, topRight));\n\n const topSection = el(\n \"div\",\n { style: { ...styles.headerStack, gap: isMobile ? \"12px\" : \"10px\" } },\n ...headerRows\n );\n\n // ─── Middle Section ───\n this.middleSection = el(\"div\", { style: styles.middleSection });\n\n const baseTextStyle = { ...styles.privacyText, color: textColor, fontFamily: font, fontSize: isMobile ? \"14px\" : \"16px\" };\n\n // Notice text + Privacy policy in ONE <p> (matches React: single <p> with <br>)\n const noticeTextSpan = el(\"span\", { id: \"privacy-notice-text\" });\n noticeTextSpan.textContent = this.getTranslatedText(\"notice_text\", activeConfig.notice_text);\n\n const policyPrefixText = this.getTranslatedText(\"privacy_policy_prefix_text\", activeConfig.privacy_policy_prefix_text);\n const policyAnchorText = this.getTranslatedText(\"privacy_policy_anchor_text\", activeConfig.privacy_policy_anchor_text);\n\n this.privacyPolicyLinkEl = el(\"a\", {\n id: \"privacy-policy-link\",\n href: activeConfig.privacy_policy_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n \"aria-label\": \"Privacy Policy (opens in new tab)\",\n }) as HTMLAnchorElement;\n this.privacyPolicyLinkEl.textContent = policyAnchorText;\n\n const policySpan = el(\"span\", { id: \"privacy-policy-text\" },\n `${policyPrefixText} `,\n this.privacyPolicyLinkEl\n );\n\n const noticeAndPolicyP = el(\"p\", { style: baseTextStyle },\n noticeTextSpan,\n el(\"br\"),\n policySpan\n );\n\n // Purpose section heading\n this.purposeHeadingEl = el(\"h2\", {\n id: \"purpose-section-heading\",\n style: { ...styles.subTitle, color: headingColor, fontFamily: font },\n });\n this.purposeHeadingEl.textContent = this.getTranslatedText(\"purpose_section_heading\", activeConfig.purpose_section_heading);\n\n this.middleSection.appendChild(noticeAndPolicyP);\n this.middleSection.appendChild(this.purposeHeadingEl);\n\n // Render purposes (needs consent)\n if (state.needsConsentPurposes.length > 0) {\n this.purposeRefs = renderModalPurposes(state.needsConsentPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: false,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (euuid, puuid) => this.handleDataElementCheckboxChange(euuid, puuid),\n });\n this.middleSection.appendChild(this.purposeRefs.container);\n }\n\n // Render already-consented purposes\n if (state.alreadyConsentedPurposes.length > 0) {\n this.alreadyConsentedPurposeRefs = renderModalPurposes(state.alreadyConsentedPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n initialDataElementSelections: state.initialDataElementSelections,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: true,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: () => {},\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: () => {},\n });\n this.middleSection.appendChild(this.alreadyConsentedPurposeRefs.container);\n }\n\n // Additional text + Privacy Center + DPO Info in ONE block (matches React layout)\n if (activeConfig.privacy_center_url || activeConfig.dpo_info) {\n const footerDiv = el(\"div\", {\n style: {\n ...baseTextStyle,\n fontSize: isMobile ? \"13px\" : \"14px\",\n lineHeight: \"1.4\",\n borderTop: \"1px solid rgba(152, 162, 179, 0.3)\",\n paddingTop: \"12px\",\n marginTop: \"12px\",\n },\n });\n\n const footerP = el(\"p\", { style: { margin: \"0\", opacity: \"0.6\" } });\n\n // Privacy Center section: \"additional_text Privacy Center.\"\n if (activeConfig.privacy_center_url) {\n if (activeConfig.additional_text) {\n const addlSpan = el(\"span\", { id: \"additional-text\" });\n addlSpan.textContent = this.getTranslatedText(\"additional_text\", activeConfig.additional_text);\n footerP.appendChild(addlSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n }\n\n const pcAnchorText = this.getTranslatedText(\"privacy_center_anchor_text\", activeConfig.privacy_center_anchor_text || \"Privacy Center\");\n this.privacyCenterLinkEl = el(\"a\", {\n id: \"privacy-center-link\",\n href: activeConfig.privacy_center_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n }) as HTMLAnchorElement;\n this.privacyCenterLinkEl.textContent = pcAnchorText;\n footerP.appendChild(this.privacyCenterLinkEl);\n footerP.appendChild(document.createTextNode(\".\"));\n }\n\n // DPO Info section (all inline with <br> separators, matching React)\n if (activeConfig.dpo_info) {\n const dpo = activeConfig.dpo_info;\n\n if (activeConfig.privacy_center_url) {\n footerP.appendChild(el(\"br\"));\n }\n\n // Grievance line\n if (dpo.grievance_text) {\n const gText = el(\"span\", { id: \"dpo-grievance-text\" });\n gText.textContent = this.getTranslatedDpoText(\"grievance_text\", dpo.grievance_text);\n footerP.appendChild(gText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.grievance_url) {\n const gLink = el(\"a\", {\n id: \"dpo-grievance-link\",\n href: dpo.grievance_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n gLink.textContent = this.getTranslatedDpoText(\"grievance_anchor_text\", dpo.grievance_anchor_text);\n footerP.appendChild(gLink);\n }\n\n if (dpo.grievance_email) {\n footerP.appendChild(document.createTextNode(\" \"));\n const connectorSpan = el(\"span\", { id: \"dpo-grievance-email-connector\" });\n connectorSpan.textContent = this.getTranslatedDpoText(\n \"grievance_email_connector_text\",\n dpo.grievance_email_connector_text || \"or email to\"\n );\n footerP.appendChild(connectorSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n const emailLink = el(\"a\", {\n id: \"dpo-grievance-email\",\n href: `mailto:${dpo.grievance_email}`,\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n emailLink.textContent = dpo.grievance_email;\n footerP.appendChild(emailLink);\n }\n }\n\n // DP Board line\n if (dpo.dp_board_text) {\n footerP.appendChild(el(\"br\"));\n const dpText = el(\"span\", { id: \"dpo-dp-board-text\" });\n dpText.textContent = this.getTranslatedDpoText(\"dp_board_text\", dpo.dp_board_text);\n footerP.appendChild(dpText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dp_board_url) {\n const dpLink = el(\"a\", {\n id: \"dpo-dp-board-link\",\n href: dpo.dp_board_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpLink.textContent = this.getTranslatedDpoText(\"dp_board_anchor_text\", dpo.dp_board_anchor_text);\n footerP.appendChild(dpLink);\n }\n }\n\n // DPO line\n if (dpo.dpo_text) {\n footerP.appendChild(el(\"br\"));\n const dpoTextSpan = el(\"span\", { id: \"dpo-dpo-text\" });\n dpoTextSpan.textContent = this.getTranslatedDpoText(\"dpo_text\", dpo.dpo_text);\n footerP.appendChild(dpoTextSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dpo_url) {\n const dpoLink = el(\"a\", {\n id: \"dpo-dpo-link\",\n href: dpo.dpo_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpoLink.textContent = this.getTranslatedDpoText(\"dpo_anchor_text\", dpo.dpo_anchor_text);\n footerP.appendChild(dpoLink);\n }\n }\n }\n\n footerDiv.appendChild(footerP);\n this.middleSection.appendChild(footerDiv);\n }\n\n // Error message\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: \"none\",\n },\n });\n\n // ─── Bottom Section: Accept FIRST, then Decline (matches React) ───\n const acceptBtnText = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\"confirm_button_text\", activeConfig.confirm_button_text);\n\n const acceptStyle: Record<string, any> = {\n ...styles.button,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n this.acceptBtn = el(\"button\", {\n id: \"confirm-button-text\",\n style: acceptStyle,\n type: \"button\",\n onClick: () => this.handleAccept(),\n }) as HTMLButtonElement;\n this.acceptBtn.textContent = acceptBtnText;\n\n const declineBtnText = this.getTranslatedText(\"decline_button_text\", activeConfig.decline_button_text);\n const declineStyle: Record<string, any> = {\n ...styles.button,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n this.declineBtn = el(\"button\", {\n id: \"decline-button-text\",\n style: declineStyle,\n type: \"button\",\n onClick: () => this.handleDecline(),\n }) as HTMLButtonElement;\n\n if (!state.isFullyConsentedReviewMode) {\n this.declineBtn.textContent = declineBtnText;\n }\n\n const bottomSection = el(\"div\", { style: styles.bottomSection });\n if (!state.isFullyConsentedReviewMode) {\n // React order: Accept first, Decline second\n bottomSection.appendChild(this.acceptBtn);\n bottomSection.appendChild(this.declineBtn);\n } else {\n bottomSection.appendChild(this.acceptBtn);\n }\n\n // Assemble modal\n const contentWrapper = el(\n \"div\",\n { style: styles.content },\n topSection,\n this.errorEl,\n this.middleSection,\n bottomSection\n );\n\n this.modalEl.appendChild(contentWrapper);\n\n // Set initial accept button disabled state\n this.updateAcceptButtonState(state);\n\n // Setup keyboard trap\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n }\n\n private getLanguageCode(displayLanguage: string): string {\n const content = this.store.getState().content?.detail.active_config;\n if (!content) return \"English\";\n\n // English maps to \"English\" for audio API\n if (displayLanguage === \"English\" || displayLanguage === \"en\" || displayLanguage === \"EN\") {\n return \"English\";\n }\n\n // If display language exists in translations, use it directly\n if (content.supported_languages_and_translations?.[displayLanguage]) {\n return displayLanguage;\n }\n\n // Fallback to default language or English\n return content.default_language === \"en\" || content.default_language === \"EN\"\n ? \"English\"\n : content.default_language || \"English\";\n }\n\n private getTranslatedDpoText(key: string, defaultText: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") return defaultText;\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang];\n if (!translationMap?.dpo_info) return defaultText;\n\n const value = (translationMap.dpo_info as any)[key];\n return typeof value === \"string\" && value ? value : defaultText;\n }\n\n private renderError(message: string): void {\n if (!this.modalEl) return;\n\n clearElement(this.modalEl);\n\n const errorContent = el(\n \"div\",\n { style: { ...styles.content, alignItems: \"center\", justifyContent: \"center\" } },\n el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n },\n }, message)\n );\n\n this.modalEl.appendChild(errorContent);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private handleLanguageSelect(lang: string): void {\n this.store.setState({ selectedLanguage: lang });\n // Rebuild UI to update all translations\n this.rebuildUI();\n }\n\n private togglePurposeCollapse(purposeUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [purposeUuid]: !state.collapsedPurposes[purposeUuid],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const newPurposeState = !state.selectedPurposes[purposeUuid];\n const updatedElements = { ...state.selectedDataElements };\n for (const de of purpose.data_elements) {\n updatedElements[`${purposeUuid}-${de.uuid}`] = newPurposeState;\n }\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: newPurposeState },\n selectedDataElements: updatedElements,\n });\n }\n\n private handleDataElementCheckboxChange(elementUuid: string, purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const combinedId = `${purposeUuid}-${elementUuid}`;\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: !state.selectedDataElements[combinedId],\n };\n\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n let shouldCheckPurpose: boolean;\n\n if (requiredElements.length > 0) {\n shouldCheckPurpose = requiredElements.every(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n } else {\n shouldCheckPurpose = purpose.data_elements.some(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n }\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: shouldCheckPurpose },\n });\n }\n\n private async handleAccept(): Promise<void> {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Review mode — just close\n if (state.isFullyConsentedReviewMode) {\n this.options.onAccept();\n this.destroy();\n return;\n }\n\n // Block submission for minors who have not completed guardian verification\n if (state.isMinorFlow && !state.verificationReference && !state.selfDeclaredAdult) {\n this.store.setState({\n errorMessage: \"Guardian verification is required before consent can be submitted.\",\n });\n return;\n }\n\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n this.abortController = new AbortController();\n this.store.setState({ isSubmitting: true, isSubmittingAccept: true, errorMessage: null });\n\n try {\n const purposes = content.purposes.map((purpose) => {\n const dataElements = purpose.data_elements\n .filter((de) => de.enabled)\n .map((de) => ({\n uuid: de.uuid,\n name: de.name,\n enabled: de.enabled,\n required: de.required,\n selected: state.selectedDataElements[`${purpose.uuid}-${de.uuid}`] || false,\n }));\n\n return {\n uuid: purpose.uuid,\n name: purpose.name,\n description: purpose.description,\n selected: state.selectedPurposes[purpose.uuid] || false,\n data_elements: dataElements,\n };\n });\n\n await submitConsentEvent({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: state.content!.detail.uuid,\n purposes,\n declined: false,\n meta_data: this.options.applicationId ? { specific_uuid: this.options.applicationId } : undefined,\n guardianVerificationReference: state.verificationReference || undefined,\n selfDeclaredAdult: state.selfDeclaredAdult || undefined,\n language: state.selectedLanguage,\n signal: this.abortController.signal,\n ...this.sandboxParams(),\n });\n\n this.options.onAccept();\n this.destroy();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n const message = error.status === 409\n ? \"You have already provided consent.\"\n : error.status && error.status >= 500\n ? \"Server error: Please try again later.\"\n : error.message || \"Failed to submit consent.\";\n this.store.setState({ errorMessage: message, isSubmitting: false, isSubmittingAccept: false });\n this.options.onError?.(error);\n }\n }\n\n private handleDecline(): void {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Stop any in-flight verification polling and clear the persisted\n // DigiLocker session so the next open starts the flow from scratch\n // (age verification → guardian form → verification screen).\n this.stopPolling();\n clearConsentState();\n\n this.options.onDecline();\n this.destroy();\n }\n\n private updateCheckboxes(state: ModalState): void {\n if (this.purposeRefs) {\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n // Update accept button disabled state\n this.updateAcceptButtonState(state);\n }\n\n private areAllRequiredChecked(state: ModalState): boolean {\n const content = state.content?.detail.active_config;\n if (!content?.purposes?.length) return false;\n\n return content.purposes.every((purpose) => {\n const requiredElements = purpose.data_elements.filter((de) => de.required && de.enabled);\n if (requiredElements.length === 0) return true;\n return requiredElements.every(\n (de) => state.selectedDataElements[`${purpose.uuid}-${de.uuid}`]\n );\n });\n }\n\n private updateAcceptButtonState(state: ModalState): void {\n if (!this.acceptBtn || state.isFullyConsentedReviewMode) return;\n\n const allRequiredChecked = this.areAllRequiredChecked(state);\n const disabled = !allRequiredChecked || state.isSubmittingAccept || state.isSubmittingDecline;\n\n this.acceptBtn.disabled = disabled;\n this.acceptBtn.style.opacity = disabled ? \"0.5\" : \"1\";\n this.acceptBtn.style.cursor = disabled ? \"not-allowed\" : \"pointer\";\n }\n\n private updateCollapseState(state: ModalState): void {\n const updateRefs = (refs: ModalPurposeRefs | null) => {\n if (!refs) return;\n for (const [purposeUuid, container] of refs.dataElementContainers) {\n const content = state.content?.detail.active_config;\n const purpose = content?.purposes.find((p) => p.uuid === purposeUuid);\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = refs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed ? \"rotate(90deg)\" : \"rotate(0deg)\";\n }\n\n const collapseBtn = refs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n };\n\n updateRefs(this.purposeRefs);\n updateRefs(this.alreadyConsentedPurposeRefs);\n }\n\n private updateErrorMessage(state: ModalState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n // ─── Age Verification Handlers ───\n\n private handleAgeVerificationYes(): void {\n this.store.setState({\n isMinorFlow: false,\n selfDeclaredAdult: true,\n showAgeVerification: false,\n });\n }\n\n private handleAgeVerificationNo(): void {\n this.store.setState({\n showAgeVerification: false,\n showGuardianForm: true,\n });\n }\n\n // ─── Guardian Form Handlers ───\n\n private async handleGuardianFormSubmit(): Promise<void> {\n const state = this.store.getState();\n const errors = validateGuardianForm(state.guardianFormData);\n if (Object.keys(errors).length > 0) {\n if (this.guardianFormRefs) {\n if (errors.guardianName) {\n this.guardianFormRefs.nameError.textContent = errors.guardianName;\n this.guardianFormRefs.nameError.style.display = \"block\";\n }\n if (errors.guardianContact) {\n this.guardianFormRefs.contactError.textContent = errors.guardianContact;\n this.guardianFormRefs.contactError.style.display = \"block\";\n }\n if (errors.guardianRelationship) {\n this.guardianFormRefs.relationshipError.textContent = errors.guardianRelationship;\n this.guardianFormRefs.relationshipError.style.display = \"block\";\n }\n }\n return;\n }\n\n this.store.setState({ isInitiatingVerification: true });\n\n const digilockerMode = this.options.digilockerMode || \"redirect\";\n const callbackUrl = digilockerMode === \"popup\"\n ? new URL(this.options.digilockerCallbackUrl || \"/digilocker-callback\", window.location.origin).href\n : undefined;\n\n try {\n const response = await initiateGuardianVerification({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n guardianName: state.guardianFormData.guardianName,\n guardianContact: state.guardianFormData.guardianContact,\n guardianRelationship: state.guardianFormData.guardianRelationship,\n frontendCallbackUrl: callbackUrl,\n });\n\n if (response.already_verified && response.verification_reference) {\n this.store.setState({\n verificationReference: response.verification_reference,\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: false,\n isVerificationComplete: true,\n });\n // Auto-transition to consent form after 1s\n setTimeout(() => {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }, 1000);\n return;\n }\n\n // Save state for redirect flow\n saveConsentState({\n flowState: \"digilocker-pending\",\n sessionToken: response.session_token,\n guardianInfoUuid: response.guardian_info_uuid,\n selectedPurposes: state.selectedPurposes,\n selectedDataElements: state.selectedDataElements,\n timestamp: new Date().toISOString(),\n originalUrl: window.location.href,\n noticeId: this.options.noticeId,\n baseUrl: this.options.baseUrl,\n });\n\n // Show verification screen with \"Opening DigiLocker...\" state\n this.store.setState({\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: true,\n isPollingStatus: false,\n });\n\n if (digilockerMode === \"popup\" && response.digilocker_redirect_url) {\n const popup = window.open(\n response.digilocker_redirect_url,\n \"digilocker_verification\",\n \"width=600,height=700,scrollbars=yes,resizable=yes\"\n );\n if (popup) {\n this.verificationPopup = popup;\n this.startPopupMonitoring(popup);\n } else {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Popup blocked. Please allow popups for this site.\",\n canRetryVerification: true,\n });\n return;\n }\n } else if (response.digilocker_redirect_url) {\n const openedWindow = window.open(response.digilocker_redirect_url, \"_blank\");\n if (!openedWindow) {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Unable to open DigiLocker. Please allow popups.\",\n canRetryVerification: true,\n });\n return;\n }\n try { openedWindow.opener = null; } catch {}\n }\n\n // Switch to polling state (spinner + \"Please complete verification...\" message)\n this.store.setState({\n isInitiatingVerification: false,\n isPollingStatus: true,\n });\n this.startStatusPolling(response.session_token!);\n } catch (error) {\n this.store.setState({ isInitiatingVerification: false });\n const err = error as Error & { status?: number };\n if (this.guardianFormRefs) {\n this.guardianFormRefs.generalError.textContent = err.message || \"Failed to initiate verification.\";\n this.guardianFormRefs.generalError.style.display = \"block\";\n }\n }\n }\n\n // ─── Verification Polling ───\n\n private startStatusPolling(token: string): void {\n this.verificationSessionToken = token;\n let attempts = 0;\n let consecutiveErrors = 0;\n let paused = false;\n const MAX_ATTEMPTS = 40;\n const MAX_CONSECUTIVE_ERRORS = 3;\n const POLL_INTERVAL = 3000;\n\n const poll = async () => {\n if (paused) return;\n attempts++;\n\n if (attempts > MAX_ATTEMPTS) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification is taking longer than expected. Please try again.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n try {\n const response = await verifyGuardianStatus({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n sessionToken: token,\n });\n\n consecutiveErrors = 0;\n\n if (response.status === \"verified\") {\n this.stopPolling();\n const ref = response.verification_reference || response.guardian_details?.verification_reference;\n if (!ref) {\n this.store.setState({\n verificationError: \"Verification completed but no reference received. Please try again.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n this.store.setState({\n verificationReference: ref,\n isVerificationComplete: true,\n isPollingStatus: false,\n });\n clearConsentState();\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n this.stopPolling();\n this.store.setState({\n verificationError: getVerificationErrorMessage(response.error_code, response.error),\n verificationErrorCode: response.error_code,\n canRetryVerification: response.can_retry,\n isPollingStatus: false,\n });\n return;\n }\n\n if (!paused) {\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n } catch (error) {\n const err = error as Error & { status?: number };\n if (err.status === 404 || err.status === 410) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification session not found or expired.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n consecutiveErrors++;\n if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {\n this.stopPolling();\n this.store.setState({\n verificationError: err.message || \"Unable to check verification status.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n };\n\n // Pause when tab hidden, resume on return\n this.visibilityChangeHandler = () => {\n if (document.hidden) {\n paused = true;\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n } else {\n paused = false;\n poll();\n }\n };\n document.addEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n\n private stopPolling(): void {\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n if (this.visibilityChangeHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n this.verificationPopup?.close();\n this.verificationPopup = null;\n }\n\n private startPopupMonitoring(popup: Window): void {\n this.popupCheckInterval = setInterval(() => {\n if (popup.closed) {\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n }\n }, 500);\n }\n\n // ─── Verification Screen Handlers ───\n\n private handleVerificationContinue(): void {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }\n\n private handleVerificationRetry(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n });\n }\n\n private handleChangeGuardian(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n }\n\n // ─── TTS ───\n\n private updateTTSButton(): void {\n if (!this.ttsButton || !this.ttsManager) return;\n\n // When the current language has no TTS audio (e.g. Santali in some\n // configs), hide the speaker icon entirely. Without this branch the\n // button would keep whatever display value it had from the previous\n // language and clicking it would replay the previous language's audio.\n if (!this.ttsManager.isAvailable) {\n this.ttsButton.style.display = \"none\";\n return;\n }\n\n this.ttsButton.style.display = \"flex\";\n\n // Swap SVG: speaker icon vs pause icon\n clearElement(this.ttsButton);\n const strokeColor = this.options.settings?.button?.language?.textColor || \"currentColor\";\n\n if (this.ttsManager.isPlaying) {\n // Pause icon\n const pauseSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\" }),\n svg(\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\" })\n );\n this.ttsButton.appendChild(pauseSvg);\n this.ttsButton.setAttribute(\"aria-label\", \"Pause audio playback\");\n this.ttsButton.setAttribute(\"title\", \"Pause Talkback\");\n } else {\n // Speaker icon\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n this.ttsButton.appendChild(speakerSvg);\n this.ttsButton.setAttribute(\"aria-label\", this.ttsManager.isPaused ? \"Resume audio playback\" : \"Start audio playback\");\n this.ttsButton.setAttribute(\"title\", this.ttsManager.isPaused ? \"Resume Talkback\" : \"Start Talkback\");\n }\n }\n\n private updateButtonStates(state: ModalState): void {\n if (this.acceptBtn) {\n if (state.isSubmittingAccept) {\n this.acceptBtn.textContent = \"Submitting...\";\n this.acceptBtn.disabled = true;\n this.acceptBtn.style.opacity = \"0.7\";\n this.acceptBtn.style.cursor = \"not-allowed\";\n } else {\n const content = state.content?.detail.active_config;\n this.acceptBtn.textContent = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\"confirm_button_text\", content?.confirm_button_text || \"Accept\");\n this.acceptBtn.disabled = false;\n this.acceptBtn.style.opacity = \"1\";\n this.acceptBtn.style.cursor = \"pointer\";\n }\n }\n\n if (this.declineBtn) {\n this.declineBtn.disabled = state.isSubmitting;\n this.declineBtn.style.opacity = state.isSubmitting ? \"0.7\" : \"1\";\n this.declineBtn.style.cursor = state.isSubmitting ? \"not-allowed\" : \"pointer\";\n }\n }\n}\n","export const inlineStyles = {\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { inlineStyles } from \"../styles/inline\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\n\nexport type PurposeRenderRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>; // purposeUuid or \"purposeUuid-elementUuid\"\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderInlinePurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string) => void;\n onPurposeCollapse: (purposeUuid: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string) => void;\n }\n): PurposeRenderRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n settings,\n isMobile,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = settings?.textColor || \"#344054\";\n\n const container = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" },\n });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n\n // Chevron SVG\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: settings?.headingColor || \"#323B4B\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[purpose.uuid] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(purpose.uuid, chevron);\n\n const chevronContainer = el(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n marginLeft: \"5px\",\n },\n },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n style: {\n ...inlineStyles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n },\n });\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n titleElements.set(purpose.uuid, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n style: {\n ...inlineStyles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(purpose.uuid, descEl);\n\n const textContainer = el(\"div\", { style: inlineStyles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: inlineStyles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[purpose.uuid]),\n \"aria-controls\": `purpose-${purpose.uuid}`,\n \"aria-label\": `${collapsedPurposes[purpose.uuid] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(purpose.uuid, collapseBtn);\n\n // Purpose checkbox\n const purposeCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedPurposes[purpose.uuid] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(purpose.uuid, purposeCheckbox);\n\n const optionRow = el(\"div\", { style: inlineStyles.optionItem }, collapseBtn, purposeCheckbox);\n\n // Data elements container\n const deContainer = el(\"div\", {\n id: `purpose-${purpose.uuid}`,\n style: inlineStyles.dataElementsContainer,\n });\n\n if (purpose.data_elements && purpose.data_elements.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n style: {\n ...inlineStyles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (dataElement.required) {\n const asterisk = el(\"span\", {\n style: { color: \"red\", marginLeft: \"4px\" },\n \"aria-label\": \"required\",\n });\n asterisk.textContent = \"*\";\n labelSpan.appendChild(asterisk);\n }\n\n const deCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${dataElement.required ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n\n const deRow = el(\"div\", { style: inlineStyles.dataElementItem }, labelSpan, deCheckbox);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(purpose.uuid, deContainer);\n\n // Show/hide data elements based on collapse state\n if (!collapsedPurposes[purpose.uuid] && purpose.data_elements?.length > 0) {\n deContainer.style.display = \"flex\";\n } else {\n deContainer.style.display = \"none\";\n }\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n","import { Store } from \"../core/state\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport { el, applyStyles, clearElement } from \"../core/dom\";\nimport { fetchConsentContentPublic, submitConsentEventPublic } from \"../api\";\nimport { resolveDisplayLanguage } from \"../api/language\";\nimport {\n fetchNoticeConsentStatusForScope,\n isNoticeFullyConsented,\n} from \"../api/notice-consent-status\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { inlineStyles } from \"../styles/inline\";\nimport { renderInlinePurposes, type PurposeRenderRefs } from \"./purposes\";\nimport type { InlineOptions } from \"../types\";\nimport type { ActiveConfig, TranslationObject } from \"../api/types\";\n\ntype InlineState = {\n content: ActiveConfig | null;\n isLoading: boolean;\n isSubmitting: boolean;\n selectedLanguage: string;\n collapsedPurposes: Record<string, boolean>;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n // Blocks auto-submit while the Go ledger check-consent read is in flight,\n // so an already-consented principal is not re-submitted post-cutover.\n isCheckingConsent: boolean;\n fetchError: Error | null;\n errorMessage: string | null;\n};\n\nexport class InlineController {\n private store: Store<InlineState>;\n private options: InlineOptions;\n private targetEl: HTMLElement | null = null;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private rootEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: PurposeRenderRefs | null = null;\n private errorEl: HTMLElement | null = null;\n private hasSubmitted = false;\n private hasCheckedLedgerConsent = false;\n private fetchedWithToken = false;\n private fetchGeneration = 0;\n private unsubscribe: (() => void) | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: InlineOptions) {\n this.options = options;\n this.store = new Store<InlineState>({\n content: null,\n isLoading: true,\n isSubmitting: false,\n selectedLanguage: options.language || \"en\",\n collapsedPurposes: {},\n selectedPurposes: {},\n selectedDataElements: {},\n hasAlreadyConsented: false,\n isCheckingConsent: false,\n fetchError: null,\n errorMessage: null,\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n }\n\n async init(): Promise<void> {\n this.abortController = new AbortController();\n\n // Resolve target element\n if (typeof this.options.target === \"string\") {\n this.targetEl = document.querySelector(this.options.target);\n if (!this.targetEl) {\n throw new Error(`Target element not found: ${this.options.target}`);\n }\n } else {\n this.targetEl = this.options.target;\n }\n\n // Mount the inline form inside an open shadow root attached to a host\n // <div> within the user's target container. This matches the modal's\n // isolation strategy so host-page CSS cannot bleed into the inline form\n // either.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent-inline\", \"\");\n // Block-level, but no `all: initial` — we want font / color / line-height\n // to inherit from the user's page so the inline form blends in like the\n // React SDK does.\n this.hostEl.style.display = \"block\";\n this.targetEl.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n injectCheckboxStyles(this.shadowRoot);\n\n // Subscribe to state changes\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n // Subscribe to media query changes\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n // Cancels the in-flight ledger read and marks the controller torn down, so\n // late-resolving work cannot fire host callbacks or submit consent.\n this.abortController?.abort();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.store.destroy();\n // Removing the host div tears down the shadow tree (and the rootEl\n // inside it) in one step.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n this.hostEl = null;\n this.shadowRoot = null;\n this.rootEl = null;\n this.purposeRefs = null;\n }\n\n updateToken(accessToken: string): void {\n this.options = { ...this.options, accessToken };\n if (accessToken && !this.fetchedWithToken) {\n void this.fetchNotice();\n return;\n }\n // A late-arriving token is the first chance to run the ledger\n // check-consent read; it gates auto-submit synchronously before trying.\n if (this.shouldCheckLedgerConsent()) {\n void this.checkLedgerConsent();\n return;\n }\n this.tryAutoSubmit();\n }\n\n // ─── Private ───\n\n // destroy() aborts the controller, so an aborted signal is the marker that\n // teardown has happened and async continuations must not touch the host.\n private isDestroyed(): boolean {\n return Boolean(this.abortController?.signal.aborted);\n }\n\n private async fetchNotice(): Promise<void> {\n const generation = ++this.fetchGeneration;\n this.fetchedWithToken = Boolean(this.options.accessToken);\n this.store.setState({ isLoading: true, fetchError: null, hasAlreadyConsented: false });\n try {\n const data = await fetchConsentContentPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n notice_uuid: this.options.notice_uuid,\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n });\n\n if (this.isDestroyed() || generation !== this.fetchGeneration) {\n return;\n }\n\n const activeConfig = data.detail.active_config;\n const initialCollapsed: Record<string, boolean> = {};\n const initialPurposes: Record<string, boolean> = {};\n const initialElements: Record<string, boolean> = {};\n\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n\n // Post-cutover, consent records live in the Go ledger, so Python's\n // get-notice no longer 409s for an already-consented principal. Kick off\n // the ledger check BEFORE the content state lands: its synchronous\n // prologue raises isCheckingConsent, so the content state change below\n // cannot auto-submit until the read settles.\n void this.checkLedgerConsent();\n\n this.store.setState({\n content: activeConfig,\n isLoading: false,\n selectedLanguage: resolveDisplayLanguage(\n this.options.language,\n activeConfig.default_language,\n activeConfig.supported_languages_and_translations\n ),\n collapsedPurposes: initialCollapsed,\n selectedPurposes: initialPurposes,\n selectedDataElements: initialElements,\n });\n } catch (err: unknown) {\n if (this.isDestroyed() || generation !== this.fetchGeneration) {\n return;\n }\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept?.();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private shouldCheckLedgerConsent(): boolean {\n return (\n Boolean(this.options.ledgerBaseUrl) &&\n !this.options.applicationId &&\n Boolean(this.options.accessToken) &&\n !this.hasCheckedLedgerConsent\n );\n }\n\n // Ask the Go ledger whether this principal has already fully consented —\n // the ledger equivalent of the legacy Python 409. Skipped without a ledger\n // (the 409 path governs) and for the magic-link applicationId flow. Any\n // failure returns null and falls through to the normal flow.\n private async checkLedgerConsent(): Promise<void> {\n if (!this.shouldCheckLedgerConsent()) return;\n this.hasCheckedLedgerConsent = true;\n this.store.setState({ isCheckingConsent: true });\n try {\n const status = await fetchNoticeConsentStatusForScope({\n accessToken: this.options.accessToken!,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n organisationUuid: this.options.org_uuid,\n workspaceUuid: this.options.workspace_uuid,\n noticeUuid: this.options.notice_uuid,\n signal: this.abortController?.signal,\n });\n if (this.isDestroyed()) {\n return;\n }\n if (status && isNoticeFullyConsented(status)) {\n this.store.setState({ hasAlreadyConsented: true });\n this.options.onAccept?.();\n }\n } finally {\n if (!this.isDestroyed()) {\n this.store.setState({ isCheckingConsent: false });\n // Re-run auto-submit now that the gate is down (no-op when already\n // consented or requirements are unmet).\n this.tryAutoSubmit();\n }\n }\n }\n\n private handleStateChange(state: InlineState, prevState: InlineState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n }\n\n // Already consented or fetch error → hide\n if (state.hasAlreadyConsented || state.fetchError) {\n if (this.rootEl && this.shadowRoot && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n this.rootEl = null;\n }\n return;\n }\n\n // Checkbox state changes → update checkboxes\n if (state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements) {\n this.updateCheckboxes(state);\n this.notifyValidation(state);\n this.tryAutoSubmit();\n }\n\n // Collapse state changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message changes\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n }\n\n private renderLoading(): void {\n if (!this.shadowRoot) return;\n\n const textColor = this.options.settings?.textColor || \"#344054\";\n\n this.rootEl = el(\n \"div\",\n { style: inlineStyles.loadingContainer },\n el(\"div\", { style: inlineStyles.loadingSpinner }),\n el(\"p\", { style: { fontSize: \"16px\", fontWeight: 400, color: textColor } }, \"Loading...\")\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.shadowRoot) return;\n\n // Remove existing root\n if (this.rootEl && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n }\n\n // Build error message element\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: state.errorMessage ? \"block\" : \"none\",\n },\n });\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n }\n\n // Build purposes\n this.purposeRefs = renderInlinePurposes(state.content.purposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n settings: this.options.settings,\n isMobile: this.mediaQuery.matches,\n getTranslatedText: (key, defaultText, itemId) =>\n this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (elementUuid, purposeUuid) =>\n this.handleDataElementCheckboxChange(elementUuid, purposeUuid),\n });\n\n this.rootEl = el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" } },\n this.errorEl,\n this.purposeRefs.container\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n this.notifyValidation(state);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private togglePurposeCollapse(purposeUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [purposeUuid]: !state.collapsedPurposes[purposeUuid],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const newPurposeState = !state.selectedPurposes[purposeUuid];\n\n const updatedElements = { ...state.selectedDataElements };\n for (const de of purpose.data_elements) {\n updatedElements[`${purposeUuid}-${de.uuid}`] = newPurposeState;\n }\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: newPurposeState },\n selectedDataElements: updatedElements,\n });\n }\n\n private handleDataElementCheckboxChange(elementUuid: string, purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const combinedId = `${purposeUuid}-${elementUuid}`;\n const newElementState = !state.selectedDataElements[combinedId];\n\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: newElementState,\n };\n\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n let shouldCheckPurpose: boolean;\n\n if (requiredElements.length > 0) {\n shouldCheckPurpose = requiredElements.every(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n } else {\n shouldCheckPurpose = purpose.data_elements.some(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n }\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: shouldCheckPurpose },\n });\n }\n\n private updateCheckboxes(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n\n private updateCollapseState(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [purposeUuid, container] of this.purposeRefs.dataElementContainers) {\n const content = this.store.getState().content;\n const purpose = content?.purposes.find((p) => p.uuid === purposeUuid);\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = this.purposeRefs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\";\n }\n\n const collapseBtn = this.purposeRefs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n }\n\n private updateErrorMessage(state: InlineState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n private areAllRequiredElementsChecked(): boolean {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return false;\n\n return content.purposes.every((purpose) => {\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n return requiredElements.every(\n (el) => state.selectedDataElements[`${purpose.uuid}-${el.uuid}`]\n );\n });\n }\n\n private notifyValidation(state: InlineState): void {\n const isValid = this.areAllRequiredElementsChecked();\n this.options.onValidationChange?.(isValid);\n }\n\n private async tryAutoSubmit(): Promise<void> {\n // A submit is a network write — never start one after teardown.\n if (this.isDestroyed()) {\n return;\n }\n\n const state = this.store.getState();\n const accessToken = this.options.accessToken;\n\n if (\n accessToken &&\n state.content &&\n this.areAllRequiredElementsChecked() &&\n !state.isSubmitting &&\n !state.isCheckingConsent &&\n !state.hasAlreadyConsented &&\n !this.hasSubmitted\n ) {\n this.hasSubmitted = true;\n try {\n await this.handleSubmit(accessToken);\n } catch (err) {\n this.hasSubmitted = false;\n this.options.onError?.(err as Error);\n }\n }\n }\n\n private async handleSubmit(tokenToUse: string): Promise<void> {\n const state = this.store.getState();\n const content = state.content;\n if (!tokenToUse || !content) {\n this.store.setState({ errorMessage: \"Unable to submit consent. Please try again.\" });\n throw new Error(\"Access token or content not available\");\n }\n\n try {\n this.store.setState({ isSubmitting: true, errorMessage: null });\n\n await submitConsentEventPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n accessToken: tokenToUse,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: content.notice_uuid,\n purposes: content.purposes.map((purpose) => {\n const hasSelectedRequired = purpose.data_elements.some(\n (el) =>\n el.required && (state.selectedDataElements[`${purpose.uuid}-${el.uuid}`] || false)\n );\n const hasSelectedAny = purpose.data_elements.some(\n (el) => state.selectedDataElements[`${purpose.uuid}-${el.uuid}`] || false\n );\n const purposeSelected =\n state.selectedPurposes[purpose.uuid] || hasSelectedRequired || hasSelectedAny;\n\n return {\n ...purpose,\n selected: purposeSelected,\n data_elements: purpose.data_elements.map((element) => ({\n ...element,\n selected: state.selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false,\n })),\n };\n }),\n declined: false,\n meta_data: this.options.applicationId\n ? { specific_uuid: this.options.applicationId }\n : undefined,\n language: state.selectedLanguage,\n });\n\n this.options.onAccept?.();\n this.hasSubmitted = false;\n } catch (error) {\n const err = error as Error & { status?: number };\n const message =\n err.status === 500\n ? \"An error occurred while submitting your consent. Please try again later.\"\n : err.message || \"Failed to submit consent. Please try again.\";\n this.store.setState({ errorMessage: message });\n this.hasSubmitted = false;\n throw error;\n } finally {\n this.store.setState({ isSubmitting: false });\n }\n }\n}\n","import { el } from \"../core/dom\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { verifyGuardianStatus } from \"../api\";\nimport {\n getConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport type { DigiLockerCallbackOptions } from \"../types\";\nimport type { GuardianVerificationErrorCode } from \"../api/types\";\n\nfunction getErrorMessage(errorCode?: GuardianVerificationErrorCode | string | null): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"Guardian verification failed: The guardian must be 18 years or older.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please restart the verification process.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker authentication failed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"Missing authorization code from DigiLocker. Please try again.\";\n default:\n return \"Verification failed. Please try again.\";\n }\n}\n\nexport function handleDigilockerCallback(options: DigiLockerCallbackOptions): void {\n // The DigiLocker callback page is a standalone screen, not embedded in a\n // host site, so styles can safely live in document.head here.\n injectCheckboxStyles(document);\n\n const params = new URLSearchParams(window.location.search);\n const sessionToken = params.get(\"session_token\");\n const urlStatus = params.get(\"status\") as \"verified\" | \"failed\" | \"expired\" | null;\n const verificationReference = params.get(\"verification_reference\");\n const errorCode = params.get(\"error_code\") as GuardianVerificationErrorCode | null;\n\n const persistedState = getConsentState();\n const originalUrl = persistedState?.originalUrl || \"/\";\n const storedBaseUrl = persistedState?.baseUrl;\n const storedSessionToken = persistedState?.sessionToken;\n const activeSessionToken = sessionToken || storedSessionToken;\n const apiBaseUrl = options.baseUrl || storedBaseUrl;\n\n // Check if in iframe\n let isInIframe = false;\n try {\n isInIframe = window.self !== window.top;\n } catch {\n isInIframe = true;\n }\n\n // Render status UI\n const container = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"200px\",\n padding: \"32px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n });\n\n const statusEl = el(\"p\", {\n style: { fontSize: \"16px\", fontWeight: 600, color: \"#101828\", textAlign: \"center\" },\n });\n statusEl.textContent = \"Processing verification...\";\n\n const spinnerEl = el(\"div\", {\n style: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"16px\",\n },\n });\n\n container.appendChild(spinnerEl);\n container.appendChild(statusEl);\n document.body.appendChild(container);\n\n const redirectToOriginal = (\n result: \"verified\" | \"failed\" | \"expired\",\n ref?: string\n ) => {\n updateConsentState({\n verificationResult: result,\n verificationReference: ref,\n flowState: result === \"verified\" ? \"consent-form\" : \"error\",\n });\n\n statusEl.textContent = result === \"verified\"\n ? \"Verification successful! Redirecting...\"\n : \"Verification failed. Redirecting...\";\n\n spinnerEl.style.display = \"none\";\n\n setTimeout(() => {\n window.location.href = originalUrl;\n }, 1500);\n };\n\n // Handle direct status from URL\n if (urlStatus === \"verified\" && verificationReference) {\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onSuccess?.(verificationReference);\n redirectToOriginal(\"verified\", verificationReference);\n return;\n }\n\n if (urlStatus === \"failed\" || urlStatus === \"expired\") {\n const errorMsg = getErrorMessage(errorCode);\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: urlStatus,\n errorCode,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onError?.(new Error(errorMsg), errorCode || undefined);\n redirectToOriginal(urlStatus);\n return;\n }\n\n // No status in URL — poll the backend\n if (!activeSessionToken) {\n statusEl.textContent = \"No verification session found.\";\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(\"No session token available\"));\n return;\n }\n\n let retryCount = 0;\n const MAX_RETRIES = 3;\n\n const pollStatus = async () => {\n try {\n const response = await verifyGuardianStatus({\n accessToken: options.accessToken,\n baseUrl: apiBaseUrl,\n sessionToken: activeSessionToken,\n });\n\n if (response.status === \"verified\") {\n const ref = response.verification_reference ||\n response.guardian_details?.verification_reference;\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference: ref,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n if (ref) options.onSuccess?.(ref);\n redirectToOriginal(\"verified\", ref || undefined);\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n const errorMsg = getVerificationError(response.error_code, response.error);\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: response.status,\n errorCode: response.error_code,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n options.onError?.(new Error(errorMsg), response.error_code || undefined);\n redirectToOriginal(response.status);\n return;\n }\n\n // Still in progress — retry with backoff\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const timeoutMsg = \"Verification is taking too long. Please return to the original page.\";\n statusEl.textContent = timeoutMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(timeoutMsg));\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n statusEl.textContent = \"Still processing... Please wait.\";\n setTimeout(pollStatus, delay);\n } catch (error) {\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const errMsg = (error as Error).message || \"Failed to check verification status.\";\n statusEl.textContent = errMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(error as Error);\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n setTimeout(pollStatus, delay);\n }\n };\n\n // Start first poll after 3s\n setTimeout(pollStatus, 3000);\n}\n\nfunction getVerificationError(errorCode: string | null, fallbackError: string | null): string {\n return getErrorMessage(errorCode) || fallbackError || \"Verification failed. Please try again.\";\n}\n"],"mappings":"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","names":["src_exports","__export","src_default","destroy","digilockerCallback","init","inline","Store","initialState","partial","prevState","listener","el","tag","attrs","children","element","applyAttrs","appendChildren","svg","key","value","applyStyles","event","UNITLESS_PROPS","styles","stringValue","parent","child","clearElement","createMediaQuery","query","mql","currentMatches","listeners","handler","e","cb","apiCache","CACHE_TTL","getCachedData","key","cached","setCachedData","data","ttl","clearApiCache","InvalidTokenError","b64DecodeUnicode","str","m","p","code","base64UrlDecode","output","jwtDecode","token","options","pos","part","decoded","e","decodeTokenSafely","token","jwtDecode","error","SANDBOX_TOKEN_HEADER","resolveSandboxAuth","options","_a","_b","_c","_d","_e","token","organisationUuid","workspaceUuid","ucic","subject","resolveRequestAuth","accessToken","sandbox","decodedToken","decodeTokenSafely","organisation_uuid","workspace_uuid","buildAuthHeaders","sandboxBodyIdentity","sandboxQueryIdentity","CODE_BY_NAME","CODE_BY_LOWER","c","toLanguageCode","lang","_a","_b","trimmed","lower","CODE_BY_LOWER","CODE_BY_NAME","resolveDisplayLanguage","requested","defaultLanguage","translations","fallback","requestedCode","key","BASE_URL","BASE_URL_PUBLIC","fetchConsentContent","noticeId","accessToken","baseUrl","language","specific_uuid","validate_against","include_fully_consented_data","signal","sandboxParams","ORG","WS","sandbox","resolveRequestAuth","apiBaseUrl","cacheKey","cached","getCachedData","url","key","value","sandboxQueryIdentity","response","buildAuthHeaders","errorMessage","error","data","setCachedData","fetchConsentContentPublic","org_uuid","workspace_uuid","notice_uuid","noticesUrl","submitConsentEvent","ledgerBaseUrl","noticeUuid","purposes","declined","meta_data","guardianVerificationReference","selfDeclaredAdult","validatedPurposes","purpose","dataElements","element","payload","toLanguageCode","requestBody","sandboxBodyIdentity","clearApiCache","submitConsentEventPublic","_a","_b","errorData","fetchTTSAudioUrls","initiateGuardianVerification","guardianName","guardianContact","guardianRelationship","frontendCallbackUrl","metadata","decodedToken","decodeTokenSafely","responseData","detail","verifyGuardianStatus","sessionToken","_c","_d","_e","_f","_g","_h","fetchNoticeConsentStatusForScope","accessToken","ledgerBaseUrl","organisationUuid","workspaceUuid","noticeUuid","signal","response","data","body","fetchNoticeConsentStatus","decodedToken","decodeTokenSafely","ORG","WS","isNoticeFullyConsented","status","buildLedgerConsentOverlay","configPurposes","_a","_b","byUuid","p","purpose_selections","cp","lp","purposeStatus","selectedByUuid","de","data_elements","STYLE_ID","STYLE_CONTENT","injectCheckboxStyles","root","style","styles","renderModalPurposes","purposes","options","_a","_b","selectedPurposes","collapsedPurposes","selectedDataElements","initialDataElementSelections","settings","isMobile","isAlreadyConsented","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","font","container","el","styles","purpose","purposeWrapper","chevron","svg","chevronContainer","titleEl","descEl","textContainer","collapseBtn","e","rightElement","createGreenCheckmark","applyStyles","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","asterisk","deRightElement","deCheckbox","deRow","size","ariaLabel","svgSize","strokeWidth","pathD","checkSvg","LANGUAGE_NATIVE_LABELS","toNativeLabel","name","_a","renderLanguageSelector","options","_b","_c","_d","languages","selectedLanguage","settings","onSelect","dropdownContainer","isOpen","buttonText","el","chevronSvg","svg","buttonStyle","styles","button","toggleDropdown","e","closeDropdown","dropdown","lang","isSelected","itemStyle","item","container","positionDropdown","rect","clickOutsideHandler","path","target","repositionHandler","openDropdown","setupKeyboardTrap","modalEl","onEscape","handler","e","_a","focusableElements","focusable","el","first","last","active","firstFocusable","STORAGE_KEY","isBrowser","saveConsentState","state","stateWithTimestamp","STORAGE_KEY","error","getConsentState","savedState","parsed","clearConsentState","updateConsentState","updates","currentState","DEFAULT_LOGO_POSITION","LOGO_POSITION_JUSTIFY","DPO_AUDIO_ELEMENT_MAP","TTSManager","onStateChange","root","params","_a","response","fetchTTSAudioUrls","error","content","_b","urls","audioSeq","elementSeq","push","url","elementId","purpose","purposeAudio","de","deAudio","mapping","DPO_AUDIO_ELEMENT_MAP","audioUrl","startIndex","index","audio","element","rect","el","renderAgeVerification","options","settings","colors","isMobile","logoUrl","onYes","onNo","onClose","headingColor","textColor","font","logo","el","styles","title","topLeft","closeBtn","closeSvg","svg","topSection","description","question","middleSection","btnBase","yesBtn","noBtn","bottomSection","RELATIONSHIP_OPTIONS","renderGuardianForm","options","_a","formData","settings","colors","isMobile","logoUrl","isSubmitting","onSubmit","onCancel","onFieldChange","headingColor","textColor","borderColor","bgColor","radius","font","accentColor","inputStyle","errorStyle","labelStyle","hintStyle","logo","el","styles","title","topLeft","topSection","subtitle","infoIcon","svg","infoText","infoBanner","nameLabel","nameInput","e","nameHint","nameError","nameGroup","contactLabel","contactInput","contactHint","contactError","contactGroup","relLabel","selectedLabel","o","chevronSvg","selectedSpan","relationshipDisplay","dropdownList","i","option","isSelected","optionEl","doClose","label","checkSvg","dropdownOpen","relContainer","handleClickOutside","doOpen","rect","spaceBelow","dropdownHeight","relationshipError","generalError","fieldsContainer","middleSection","btnBase","submitBtn","cancelBtn","bottomSection","validateGuardianForm","data","errors","getVerificationErrorMessage","errorCode","fallbackError","renderVerificationScreen","options","settings","colors","isMobile","logoUrl","isInitiating","isPolling","isComplete","isAutoTransitioning","error","canRetry","onContinue","onBack","headingColor","textColor","font","accentColor","logo","el","styles","title","topLeft","topSection","middleSection","successCircle","checkSvg","svg","successText","wrapper","spinner","statusMsg","errorCircle","xSvg","failedText","errorBox","btnBase","bottomSection","acceptBtnStyle","declineBtnStyle","continueBtn","retryBtn","goBackBtn","cancelBtn","resolveColors","settings","activeConfig","_a","_b","_c","_d","_e","_f","_g","_h","primaryColor","secondaryColor","resolveLogoPosition","raw","DEFAULT_LOGO_POSITION","logoRowJustify","position","LOGO_POSITION_JUSTIFY","ModalController","options","Store","createMediaQuery","state","prevState","_a","_b","_c","_d","noticeBaseUrl","data","fetchConsentContent","activeConfig","purposeSelections","reconsentRequired","ledgerOverlayApplied","ledgerStatus","fetchNoticeConsentStatus","overlay","buildLedgerConsentOverlay","initialCollapsed","initialPurposes","initialElements","initialDataElementSelections","needsConsentPurposes","alreadyConsentedPurposes","isFullyConsentedReviewMode","purpose","selection","de","combinedId","deSelection","wasSelected","selectedLanguage","resolveDisplayLanguage","isMinorFlow","showAgeVerification","restoreState","pollingTokenToResume","persistedState","getConsentState","clearConsentState","err","error","injectCheckboxStyles","TTSManager","el","styles","settingsObj","modalStyle","loadingEl","contentEl","_e","_f","_g","_h","isMobile","colors","resolveColors","clearElement","ageRefs","renderAgeVerification","setupKeyboardTrap","renderGuardianForm","field","value","s","verRefs","renderVerificationScreen","clearName","headingColor","textColor","linkColor","font","logoImg","supportedLangs","allLanguages","l","renderLanguageSelector","lang","ttsStrokeColor","speakerSvg","svg","topRight","logoPosition","resolveLogoPosition","headerRows","logoRowJustify","topSection","baseTextStyle","noticeTextSpan","policyPrefixText","policyAnchorText","policySpan","noticeAndPolicyP","renderModalPurposes","key","defaultText","itemId","uuid","euuid","puuid","footerDiv","footerP","addlSpan","pcAnchorText","dpo","gText","gLink","connectorSpan","emailLink","dpText","dpLink","dpoTextSpan","dpoLink","acceptBtnText","acceptStyle","declineBtnText","declineStyle","bottomSection","contentWrapper","displayLanguage","content","translations","translationMap","message","errorContent","purposeData","purposeUuid","p","newPurposeState","updatedElements","elementUuid","newDataElements","requiredElements","shouldCheckPurpose","purposes","dataElements","submitConsentEvent","checkbox","disabled","updateRefs","refs","container","isCollapsed","chevron","collapseBtn","errors","validateGuardianForm","digilockerMode","callbackUrl","response","initiateGuardianVerification","saveConsentState","popup","openedWindow","token","attempts","consecutiveErrors","paused","MAX_ATTEMPTS","MAX_CONSECUTIVE_ERRORS","POLL_INTERVAL","poll","verifyGuardianStatus","ref","getVerificationErrorMessage","strokeColor","pauseSvg","inlineStyles","renderInlinePurposes","purposes","options","_a","selectedPurposes","collapsedPurposes","selectedDataElements","settings","isMobile","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","container","el","purpose","purposeWrapper","chevron","svg","chevronContainer","titleEl","inlineStyles","descEl","textContainer","collapseBtn","e","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","asterisk","deCheckbox","deRow","InlineController","options","Store","createMediaQuery","injectCheckboxStyles","state","prevState","_a","_b","accessToken","_c","_d","generation","data","fetchConsentContentPublic","activeConfig","initialCollapsed","initialPurposes","initialElements","purpose","de","resolveDisplayLanguage","err","error","status","fetchNoticeConsentStatusForScope","isNoticeFullyConsented","textColor","el","inlineStyles","renderInlinePurposes","key","defaultText","itemId","uuid","elementUuid","purposeUuid","content","lang","translations","translationMap","purposeData","value","p","newPurposeState","updatedElements","combinedId","newElementState","newDataElements","requiredElements","shouldCheckPurpose","checkbox","container","isCollapsed","chevron","collapseBtn","isValid","tokenToUse","submitConsentEventPublic","hasSelectedRequired","hasSelectedAny","purposeSelected","element","message","getErrorMessage","errorCode","handleDigilockerCallback","options","_a","_b","_c","injectCheckboxStyles","params","sessionToken","urlStatus","verificationReference","persistedState","getConsentState","originalUrl","storedBaseUrl","storedSessionToken","activeSessionToken","apiBaseUrl","isInIframe","container","el","statusEl","spinnerEl","redirectToOriginal","result","ref","updateConsentState","errorMsg","retryCount","MAX_RETRIES","pollStatus","_d","_e","response","verifyGuardianStatus","getVerificationError","timeoutMsg","delay","error","errMsg","fallbackError","activeModal","activeInline","init","options","destroy","ModalController","err","_a","inline","InlineController","digilockerCallback","handleDigilockerCallback","RedactoConsent","src_default"]}
|