@opencx/widget-core 5.0.0-beta.5 → 5.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/index.cjs +8 -8
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1577 -1062
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/api/api-caller.d.ts +67 -0
  6. package/dist/src/api/api-caller.d.ts.map +1 -1
  7. package/dist/src/api/elicitation.d.ts +60 -0
  8. package/dist/src/api/elicitation.d.ts.map +1 -0
  9. package/dist/src/api/schema.d.ts +517 -56
  10. package/dist/src/api/schema.d.ts.map +1 -1
  11. package/dist/src/context/active-session-polling.ctx.d.ts +2 -0
  12. package/dist/src/context/active-session-polling.ctx.d.ts.map +1 -1
  13. package/dist/src/context/message.ctx.d.ts +4 -0
  14. package/dist/src/context/message.ctx.d.ts.map +1 -1
  15. package/dist/src/context/resolve-client-presentation.d.ts.map +1 -1
  16. package/dist/src/context/session.ctx.d.ts +5 -0
  17. package/dist/src/context/session.ctx.d.ts.map +1 -1
  18. package/dist/src/context/widget.ctx.d.ts +6 -1
  19. package/dist/src/context/widget.ctx.d.ts.map +1 -1
  20. package/dist/src/index.d.ts +3 -0
  21. package/dist/src/index.d.ts.map +1 -1
  22. package/dist/src/translation/ar.d.ts.map +1 -1
  23. package/dist/src/translation/bg.d.ts.map +1 -1
  24. package/dist/src/translation/bn.d.ts.map +1 -1
  25. package/dist/src/translation/cs.d.ts.map +1 -1
  26. package/dist/src/translation/da.d.ts.map +1 -1
  27. package/dist/src/translation/de.d.ts.map +1 -1
  28. package/dist/src/translation/el.d.ts.map +1 -1
  29. package/dist/src/translation/en.d.ts.map +1 -1
  30. package/dist/src/translation/es.d.ts.map +1 -1
  31. package/dist/src/translation/et.d.ts.map +1 -1
  32. package/dist/src/translation/fi.d.ts.map +1 -1
  33. package/dist/src/translation/fil.d.ts.map +1 -1
  34. package/dist/src/translation/fr.d.ts.map +1 -1
  35. package/dist/src/translation/hi.d.ts.map +1 -1
  36. package/dist/src/translation/hr.d.ts.map +1 -1
  37. package/dist/src/translation/hu.d.ts.map +1 -1
  38. package/dist/src/translation/index.d.ts +12 -0
  39. package/dist/src/translation/index.d.ts.map +1 -1
  40. package/dist/src/translation/is.d.ts.map +1 -1
  41. package/dist/src/translation/it.d.ts.map +1 -1
  42. package/dist/src/translation/ja.d.ts.map +1 -1
  43. package/dist/src/translation/ko.d.ts.map +1 -1
  44. package/dist/src/translation/lb.d.ts.map +1 -1
  45. package/dist/src/translation/lt.d.ts.map +1 -1
  46. package/dist/src/translation/lv.d.ts.map +1 -1
  47. package/dist/src/translation/mt.d.ts.map +1 -1
  48. package/dist/src/translation/nb.d.ts.map +1 -1
  49. package/dist/src/translation/nl.d.ts.map +1 -1
  50. package/dist/src/translation/no.d.ts.map +1 -1
  51. package/dist/src/translation/pl.d.ts.map +1 -1
  52. package/dist/src/translation/pt.d.ts.map +1 -1
  53. package/dist/src/translation/ro.d.ts.map +1 -1
  54. package/dist/src/translation/ru.d.ts.map +1 -1
  55. package/dist/src/translation/sk.d.ts.map +1 -1
  56. package/dist/src/translation/sv.d.ts.map +1 -1
  57. package/dist/src/translation/th.d.ts.map +1 -1
  58. package/dist/src/translation/tr.d.ts.map +1 -1
  59. package/dist/src/translation/ur.d.ts.map +1 -1
  60. package/dist/src/translation/vi.d.ts.map +1 -1
  61. package/dist/src/translation/zh-cn.d.ts.map +1 -1
  62. package/dist/src/types/component-name.d.ts +1 -1
  63. package/dist/src/types/component-name.d.ts.map +1 -1
  64. package/dist/src/types/messages.d.ts +2 -0
  65. package/dist/src/types/messages.d.ts.map +1 -1
  66. package/dist/src/types/widget-config.d.ts +4 -0
  67. package/dist/src/types/widget-config.d.ts.map +1 -1
  68. package/package.json +3 -2
  69. package/dist/src/__tests__/api/agent-stream-parts.spec.d.ts +0 -2
  70. package/dist/src/__tests__/api/agent-stream-parts.spec.d.ts.map +0 -1
  71. package/dist/src/__tests__/api/dictation-mint-cache.spec.d.ts +0 -2
  72. package/dist/src/__tests__/api/dictation-mint-cache.spec.d.ts.map +0 -1
  73. package/dist/src/__tests__/api/widget-api-wire.spec.d.ts +0 -2
  74. package/dist/src/__tests__/api/widget-api-wire.spec.d.ts.map +0 -1
  75. package/dist/src/__tests__/api-caller.mock.d.ts +0 -2
  76. package/dist/src/__tests__/api-caller.mock.d.ts.map +0 -1
  77. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-anonymous.spec.d.ts +0 -1
  78. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-anonymous.spec.d.ts.map +0 -1
  79. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-with-user-data-provided-by-org.spec.d.ts +0 -1
  80. package/dist/src/__tests__/context/contact/auth/auto-create-unverified-with-user-data-provided-by-org.spec.d.ts.map +0 -1
  81. package/dist/src/__tests__/context/contact/auth/manually-create-unverified-with-user-data-provided-by-user.spec.d.ts +0 -1
  82. package/dist/src/__tests__/context/contact/auth/manually-create-unverified-with-user-data-provided-by-user.spec.d.ts.map +0 -1
  83. package/dist/src/__tests__/context/contact/auth/with-secure-token.spec.d.ts +0 -1
  84. package/dist/src/__tests__/context/contact/auth/with-secure-token.spec.d.ts.map +0 -1
  85. package/dist/src/__tests__/context/contact/should-collect-data.spec.d.ts +0 -1
  86. package/dist/src/__tests__/context/contact/should-collect-data.spec.d.ts.map +0 -1
  87. package/dist/src/__tests__/context/contact-ctx.create-failure.spec.d.ts +0 -2
  88. package/dist/src/__tests__/context/contact-ctx.create-failure.spec.d.ts.map +0 -1
  89. package/dist/src/__tests__/context/dictation-ctx.spec.d.ts +0 -1
  90. package/dist/src/__tests__/context/dictation-ctx.spec.d.ts.map +0 -1
  91. package/dist/src/__tests__/context/message/merge-send-context.spec.d.ts +0 -2
  92. package/dist/src/__tests__/context/message/merge-send-context.spec.d.ts.map +0 -1
  93. package/dist/src/__tests__/context/message/on-message-received-hook.spec.d.ts +0 -1
  94. package/dist/src/__tests__/context/message/on-message-received-hook.spec.d.ts.map +0 -1
  95. package/dist/src/__tests__/context/message/pending-user-messages.spec.d.ts +0 -1
  96. package/dist/src/__tests__/context/message/pending-user-messages.spec.d.ts.map +0 -1
  97. package/dist/src/__tests__/context/message/sent-text-history.spec.d.ts +0 -1
  98. package/dist/src/__tests__/context/message/sent-text-history.spec.d.ts.map +0 -1
  99. package/dist/src/__tests__/context/message-ctx.agent-handlers.spec.d.ts +0 -2
  100. package/dist/src/__tests__/context/message-ctx.agent-handlers.spec.d.ts.map +0 -1
  101. package/dist/src/__tests__/context/message-ctx.client-context.spec.d.ts +0 -2
  102. package/dist/src/__tests__/context/message-ctx.client-context.spec.d.ts.map +0 -1
  103. package/dist/src/__tests__/context/message-ctx.mentions.spec.d.ts +0 -2
  104. package/dist/src/__tests__/context/message-ctx.mentions.spec.d.ts.map +0 -1
  105. package/dist/src/__tests__/context/message-ctx.page-mark-chips.spec.d.ts +0 -2
  106. package/dist/src/__tests__/context/message-ctx.page-mark-chips.spec.d.ts.map +0 -1
  107. package/dist/src/__tests__/context/message-ctx.send-acceptance.spec.d.ts +0 -2
  108. package/dist/src/__tests__/context/message-ctx.send-acceptance.spec.d.ts.map +0 -1
  109. package/dist/src/__tests__/context/message-ctx.send-features.spec.d.ts +0 -2
  110. package/dist/src/__tests__/context/message-ctx.send-features.spec.d.ts.map +0 -1
  111. package/dist/src/__tests__/context/reconcile-after-stream.spec.d.ts +0 -1
  112. package/dist/src/__tests__/context/reconcile-after-stream.spec.d.ts.map +0 -1
  113. package/dist/src/__tests__/context/resolve-client-presentation.spec.d.ts +0 -2
  114. package/dist/src/__tests__/context/resolve-client-presentation.spec.d.ts.map +0 -1
  115. package/dist/src/__tests__/context/restore-last-session.spec.d.ts +0 -2
  116. package/dist/src/__tests__/context/restore-last-session.spec.d.ts.map +0 -1
  117. package/dist/src/__tests__/context/session-ctx.stale-token-retry.spec.d.ts +0 -2
  118. package/dist/src/__tests__/context/session-ctx.stale-token-retry.spec.d.ts.map +0 -1
  119. package/dist/src/__tests__/context/storage-ctx.spec.d.ts +0 -2
  120. package/dist/src/__tests__/context/storage-ctx.spec.d.ts.map +0 -1
  121. package/dist/src/__tests__/context/streaming-engine.spec.d.ts +0 -1
  122. package/dist/src/__tests__/context/streaming-engine.spec.d.ts.map +0 -1
  123. package/dist/src/__tests__/context/upload.ctx.spec.d.ts +0 -2
  124. package/dist/src/__tests__/context/upload.ctx.spec.d.ts.map +0 -1
  125. package/dist/src/__tests__/context/widget-ctx.conversations.spec.d.ts +0 -1
  126. package/dist/src/__tests__/context/widget-ctx.conversations.spec.d.ts.map +0 -1
  127. package/dist/src/__tests__/context/widget-ctx.features.spec.d.ts +0 -1
  128. package/dist/src/__tests__/context/widget-ctx.features.spec.d.ts.map +0 -1
  129. package/dist/src/__tests__/dictation/dictation-commands.utils.spec.d.ts +0 -2
  130. package/dist/src/__tests__/dictation/dictation-commands.utils.spec.d.ts.map +0 -1
  131. package/dist/src/__tests__/test-utils.d.ts +0 -452
  132. package/dist/src/__tests__/test-utils.d.ts.map +0 -1
  133. package/dist/src/__tests__/translation.spec.d.ts +0 -2
  134. package/dist/src/__tests__/translation.spec.d.ts.map +0 -1
  135. package/dist/src/__tests__/utils/Poller.spec.d.ts +0 -2
  136. package/dist/src/__tests__/utils/Poller.spec.d.ts.map +0 -1
  137. package/dist/src/__tests__/utils/PrimitiveState.spec.d.ts +0 -2
  138. package/dist/src/__tests__/utils/PrimitiveState.spec.d.ts.map +0 -1
  139. package/dist/src/__tests__/utils/companion-layout.spec.d.ts +0 -2
  140. package/dist/src/__tests__/utils/companion-layout.spec.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/api/agent-stream-parts.ts","../src/utils/log.ts","../src/api/client.ts","../src/api/api-caller.ts","../src/utils/is-exhaustive.ts","../src/utils/PrimitiveState.ts","../src/utils/Poller.ts","../src/utils/run-catching.ts","../src/context/active-session-polling.ctx.ts","../src/context/contact.ctx.ts","../src/context/upload.ctx.ts","../src/utils/uuid.ts","../src/context/csat.ctx.ts","../src/dictation/dictation-commands.utils.ts","../src/dictation/dictation-drip.utils.ts","../src/dictation/dictation-mint-cache.ts","../src/utils/is-record.ts","../src/dictation/dictation-session.ts","../src/context/dictation.ctx.ts","../src/translation/ar.ts","../src/translation/bn.ts","../src/translation/bg.ts","../src/translation/cs.ts","../src/translation/da.ts","../src/translation/el.ts","../src/translation/de.ts","../src/translation/en.ts","../src/translation/es.ts","../src/translation/fil.ts","../src/translation/fi.ts","../src/translation/fr.ts","../src/translation/hi.ts","../src/translation/it.ts","../src/translation/ja.ts","../src/translation/ko.ts","../src/translation/nl.ts","../src/translation/no.ts","../src/translation/pl.ts","../src/translation/pt.ts","../src/translation/ro.ts","../src/translation/sv.ts","../src/translation/ru.ts","../src/translation/th.ts","../src/translation/tr.ts","../src/translation/ur.ts","../src/translation/vi.ts","../src/translation/zh-cn.ts","../src/translation/hr.ts","../src/translation/et.ts","../src/translation/hu.ts","../src/translation/is.ts","../src/translation/lv.ts","../src/translation/lt.ts","../src/translation/lb.ts","../src/translation/mt.ts","../src/translation/nb.ts","../src/translation/sk.ts","../src/translation/index.ts","../src/context/session.ctx.ts","../src/context/message.ctx.ts","../src/context/router.ctx.ts","../src/context/storage.ctx.ts","../src/context/widget-agent.ts","../src/context/widget.ctx.ts","../src/context/resolve-client-presentation.ts","../src/dictation/dictation-level-smoother.ts","../src/utils/companion-layout.ts"],"sourcesContent":["/**\n * The v5 stream's protocol-level data parts the client classifies a stream by.\n * Neither renders anything: the widget only needs to recognise them.\n */\n\n/**\n * The idle heartbeat. While a request waits — a message waiting to join the\n * session's live turn, or a turn that has not spoken yet — the backend emits\n * one so an idle timeout never cuts the connection. It is a `transient`\n * part: the protocol delivers it and never adds it to the message. Readers\n * that classify a stream by its first chunk must skip it.\n */\nexport const isAgentStreamKeepalive = (part: { type: string }): boolean =>\n part.type === 'data-keepalive';\n\n/**\n * The stream's answer to a message POSTed while the session already had a\n * live turn: the message was STEERED into that turn (no new turn, no reply\n * of its own — the live turn's single reply answers both messages). The\n * request's own stream carries exactly this part and ends.\n */\nexport const isTurnSteeredPart = (part: { type: string }): boolean =>\n part.type === 'data-turn-steered';\n","/**\n * The widget runs inside customers' pages, so every line it writes to the\n * console carries one attributable prefix. Use this instead of `console.*`.\n */\nconst PREFIX = '[opencx]';\n\nexport const log = {\n warn: (message: string, ...details: unknown[]): void => {\n console.warn(`${PREFIX} ${message}`, ...details);\n },\n error: (message: string, ...details: unknown[]): void => {\n console.error(`${PREFIX} ${message}`, ...details);\n },\n};\n","import createClient, { type Middleware } from 'openapi-fetch';\nimport { log } from '../utils/log';\nimport type { paths } from './schema';\nimport type { components } from './schema';\n\ntype Options = {\n baseUrl: string;\n onRequest?: Middleware['onRequest'];\n onResponse?: Middleware['onResponse'];\n onError?: Middleware['onError'];\n};\n\nconst defaultOnError: Middleware['onError'] = (onErrorOptions) => {\n log.error('request failed', onErrorOptions.error);\n};\n\nexport const basicClient = (options: Options) => {\n const client = createClient<paths>({\n baseUrl: options.baseUrl,\n });\n\n const middlewares: Middleware = {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n onError: options.onError || defaultOnError,\n };\n\n client.use(middlewares);\n return client;\n};\n\nexport type Endpoint = keyof paths;\nexport type Dto = components['schemas'];\n","import { type Dto, type Endpoint, basicClient } from './client';\nimport type { DictationMint } from '../dictation/dictation-session';\nimport type { WidgetConfig } from '../types/widget-config';\nimport type {\n AgentTurnMessagesDto,\n ResolveSessionDto,\n SendMessageDto,\n VoteInputDto,\n} from '../types/dtos';\nimport { log } from '../utils/log';\n\n/**\n * The two stream endpoints the AI SDK transport hits directly (it needs raw\n * URLs, not the typed client). Everything else goes through `this.client`.\n */\nconst STREAM_PATH = '/backend/widget/v5/chat/stream' satisfies Endpoint;\nconst RECONNECT_PATH =\n '/backend/widget/v5/chat/{sessionId}/stream' satisfies Endpoint;\n\nconst streamUrl = (baseUrl: string, path: string, sessionId?: string) =>\n `${baseUrl.replace(/\\/$/, '')}${\n sessionId\n ? path.replace('{sessionId}', encodeURIComponent(sessionId))\n : path\n }`;\n\nexport class ApiCaller {\n private client: ReturnType<typeof basicClient>;\n private config: WidgetConfig;\n private userToken: string | null = null;\n\n constructor({ config }: { config: WidgetConfig }) {\n this.config = config;\n this.userToken = config.user?.token || null;\n\n const { baseUrl, headers } = this.constructClientOptions(\n config.user?.token,\n );\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n }\n\n private constructClientOptions = (token: string | null | undefined) => {\n const baseUrl =\n import.meta.env.MODE === 'test'\n ? 'http://localhost:8080'\n : this.config.apiUrl || 'https://api.open.cx';\n const headers = {\n 'X-Bot-Token': this.config.token,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: token ? `Bearer ${token}` : undefined,\n };\n\n return { baseUrl, headers };\n };\n\n private createOpenAPIClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n return basicClient({\n baseUrl,\n onRequest: ({ request }) => {\n Object.entries(headers).forEach(([key, value]) => {\n if (value) {\n request.headers.set(key, value);\n }\n });\n },\n });\n };\n\n setAuthToken = (token: string) => {\n this.userToken = token;\n const { baseUrl, headers } = this.constructClientOptions(token);\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n };\n\n /**\n * AUTH headers only (X-Bot-Token / Authorization), stripped of\n * content-type/accept. The transport sets its own Content-Type, and a second\n * (case-differing) copy gets COMBINED by the Headers init into\n * \"application/json, application/json\" — which the server rejects (415). Also\n * reused for the reconnect/stop control calls (empty-body POST/GET).\n */\n private getStreamAuthContext = (): {\n baseUrl: string;\n headers: Record<string, string>;\n } => {\n const { baseUrl, headers } = this.constructClientOptions(this.userToken);\n const definedHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value !== 'string') continue;\n if (['content-type', 'accept'].includes(key.toLowerCase())) continue;\n definedHeaders[key] = value;\n }\n return { baseUrl, headers: definedHeaders };\n };\n\n /**\n * Wiring for the agent-chat streaming adapter: the send endpoint, the\n * session-scoped reconnect endpoint, and the shared auth headers.\n * Computed lazily so a later `setAuthToken` is always reflected.\n */\n getStreamTransportOptions = (): {\n api: string;\n reconnectApi: (sessionId: string) => string;\n headers: Record<string, string>;\n } => {\n const { baseUrl, headers } = this.getStreamAuthContext();\n return {\n api: streamUrl(baseUrl, STREAM_PATH),\n reconnectApi: (sessionId: string) =>\n streamUrl(baseUrl, RECONNECT_PATH, sessionId),\n headers,\n };\n };\n\n /**\n * Stop / interrupt the session's in-flight streamed turn. With resumable\n * streams on, a client abort is treated as a disconnect (the stream\n * survives), so a real \"stop\" is this explicit call — the backend cancels\n * generation and clears the resume pointer. Throws on failure — the caller\n * decides how to react, so a failed cancel is never mistaken for an ACKed\n * one.\n */\n stopStream = async (sessionId: string): Promise<void> => {\n const { response } = await this.client.POST(\n '/backend/widget/v5/chat/{sessionId}/stop',\n { params: { path: { sessionId } } },\n );\n if (!response.ok) {\n throw new Error(`Failed to stop stream: ${response.status}`);\n }\n };\n\n /**\n * The session's settled agent turns with their final UIMessage parts and\n * the transcript rows each produced — the reload-fidelity read (widget v5).\n * Returns null on any failure: the caller then keeps the plain-row\n * rendering, exactly the pre-feature behavior.\n */\n getAgentTurnMessages = async (\n sessionId: string,\n presentation?: WidgetConfig['presentation'],\n ): Promise<AgentTurnMessagesDto | null> => {\n const { data, response } = await this.client.GET(\n '/backend/widget/v5/chat/{sessionId}/messages',\n {\n params: {\n path: { sessionId },\n query: {\n toolActivity: presentation?.toolActivity,\n reasoning:\n presentation?.reasoning === undefined\n ? undefined\n : presentation.reasoning\n ? 'true'\n : 'false',\n },\n },\n },\n );\n if (!data) {\n log.warn('agent turn messages fetch failed', response.status);\n return null;\n }\n return data;\n };\n\n /**\n * Mint a short-lived transcription token for voice dictation (widget v5).\n * Org-gated server-side; throws on any failure so the caller can surface\n * \"dictation unavailable\" instead of hanging with an open mic.\n */\n createDictationSession = async ({\n language,\n }: {\n language?: string | undefined;\n }): Promise<DictationMint> => {\n const { data, response } = await this.client.POST(\n '/backend/widget/v5/dictation/sessions',\n { body: language ? { language } : {} },\n );\n if (!data) {\n throw new Error(`Failed to start dictation: ${response.status}`);\n }\n return data;\n };\n\n getExternalWidgetConfig = async () => {\n return await this.client.GET('/backend/widget/v2/config', {\n params: {\n header: { 'x-bot-token': this.config.token },\n },\n });\n };\n\n sendMessage = async (body: SendMessageDto, abortSignal?: AbortSignal) => {\n return await this.client.POST('/backend/widget/v2/chat/send', {\n body,\n signal: abortSignal,\n });\n };\n\n createUnverifiedContact = async (body: Dto['CreateUnverifiedContactDto']) => {\n return await this.client.POST(\n '/backend/widget/v2/contact/create-unverified',\n {\n params: { header: { 'x-bot-token': this.config.token } },\n body,\n },\n );\n };\n\n createSession = async (\n body: Dto['CreateWidgetSessionDto'],\n abortSignal?: AbortSignal,\n ) => {\n return await this.client.POST('/backend/widget/v2/create-session', {\n body,\n signal: abortSignal,\n });\n };\n\n pollSessionAndHistory = async ({\n sessionId,\n abortSignal,\n }: {\n sessionId: string;\n abortSignal: AbortSignal;\n }) => {\n return await this.client.GET('/backend/widget/v2/poll/{sessionId}', {\n params: { path: { sessionId } },\n signal: abortSignal,\n });\n };\n\n getSessions = async ({\n cursor,\n filters,\n abortSignal,\n }: {\n /** Opaque pagination token: the `next` value from the previous page (the backend paginates by `offset`). */\n cursor: string | undefined;\n filters: Record<string, string>;\n abortSignal?: AbortSignal;\n }) => {\n return await this.client.GET('/backend/widget/v2/sessions', {\n params: {\n query: {\n offset: cursor,\n filters: JSON.stringify(filters),\n },\n },\n signal: abortSignal,\n });\n };\n\n /**\n * openapi-fetch usually works fine for file uploads, but this time around it parses the payload in a weird way and results in 413 errors (payload too large)\n * Anyway, good old XHR even does it better with progress events\n */\n uploadFile = async ({\n file,\n abortSignal,\n onProgress,\n }: {\n file: File;\n abortSignal: AbortSignal;\n onProgress?: (percentage: number) => void;\n }): Promise<Dto['UploadWidgetFileResponseDto']> => {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('file', file);\n\n const xhr = new XMLHttpRequest();\n\n // Set up abort functionality\n if (abortSignal) {\n abortSignal.addEventListener('abort', () => {\n xhr.abort();\n reject(new DOMException('Aborted', 'AbortError'));\n });\n\n // If already aborted, reject immediately\n if (abortSignal.aborted) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n }\n\n xhr.upload.addEventListener('progress', (event) => {\n if (event.lengthComputable && onProgress) {\n const percentage = Math.round((event.loaded / event.total) * 100);\n onProgress(percentage);\n }\n });\n\n // Handle completion\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const data = JSON.parse(xhr.responseText);\n resolve(data);\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`));\n }\n } else {\n reject(new Error(`Upload failed with status: ${xhr.status}`));\n }\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Network error occurred'));\n });\n\n xhr.addEventListener('timeout', () => {\n reject(new Error('Upload timed out'));\n });\n\n const { baseUrl } = this.constructClientOptions(this.userToken);\n\n const path = '/backend/widget/v2/upload' satisfies Endpoint;\n const uploadUrl = `${baseUrl}${path}`;\n xhr.open('POST', uploadUrl);\n\n xhr.setRequestHeader('X-Bot-Token', this.config.token);\n const userToken = this.userToken ?? this.config.user?.token;\n if (userToken) {\n xhr.setRequestHeader('Authorization', `Bearer ${this.userToken}`);\n } else {\n log.error('user token not set');\n }\n\n xhr.send(formData);\n });\n };\n\n vote = async (body: VoteInputDto) => {\n return await this.client.POST('/backend/widget/v2/chat/vote', { body });\n };\n\n resolveSession = async (\n body: ResolveSessionDto,\n abortSignal?: AbortSignal,\n ) => {\n return await this.client.POST('/backend/widget/v2/session/resolve', {\n body,\n signal: abortSignal,\n });\n };\n\n createStateCheckpoint = async (\n body: Dto['WidgetCreateStateCheckpointInputDto'],\n ) => {\n return await this.client.POST('/backend/widget/v2/checkpoint', {\n body,\n });\n };\n\n submitCsat = async (body: Dto['WidgetSubmitCsatInputDto']) => {\n return await this.client.POST('/backend/widget/v2/submit-csat', { body });\n };\n}\n","import { log } from './log';\nexport function isExhaustive(value: never, funcName: string) {\n log.error(`missing case for ${value} in ${funcName}`);\n}\n","import isEqual from 'lodash.isequal';\nimport { log } from './log';\n\nexport type Subscriber<T> = (data: T) => void;\n\nexport class PrimitiveState<S> {\n private subscribers = new Set<Subscriber<S>>();\n private state: S;\n private initialState: S;\n\n constructor(state: S) {\n this.state = state;\n this.initialState = state;\n }\n\n get = (): S => this.state;\n\n set = (newState: S): void => {\n if (!isEqual(this.state, newState)) {\n this.state = newState;\n this.notifySubscribers(newState);\n }\n };\n\n setPartial = (_s: Partial<S>): void => {\n if (_s === undefined || _s === null) return;\n const newState = { ...this.state, ..._s };\n this.set(newState);\n };\n\n reset = (): void => {\n this.set(this.initialState);\n };\n\n private notifySubscribers = (state: S) => {\n const subscribersArray = Array.from(this.subscribers);\n subscribersArray.forEach((callback) => {\n try {\n callback(state);\n } catch (error) {\n if (import.meta.env.MODE !== 'test') {\n log.error('state subscriber threw', error);\n }\n }\n });\n };\n\n subscribe = (callback: Subscriber<S>): (() => void) => {\n this.subscribers.add(callback);\n\n return () => {\n this.subscribers.delete(callback);\n };\n };\n}\n","import { PrimitiveState } from './PrimitiveState';\nimport { log } from './log';\n\nexport type PollingState = {\n isPolling: boolean;\n isError: boolean;\n};\n\nexport class Poller {\n state = new PrimitiveState<PollingState>({\n isPolling: false,\n isError: false,\n });\n private abortController = new AbortController();\n\n reset = () => {\n this.abortController.abort('Resetting poller');\n this.stopPolling?.();\n this.stopPolling = null;\n };\n\n private stopPolling: (() => void) | null = null;\n\n startPolling = (\n cb: (abortSignal: AbortSignal) => Promise<void>,\n intervalMs: number,\n ) => {\n if (this.stopPolling) return;\n\n const timeouts: NodeJS.Timeout[] = [];\n\n const poll = async () => {\n this.abortController = new AbortController();\n this.state.setPartial({ isPolling: true });\n\n try {\n await cb(this.abortController.signal);\n } catch (error) {\n if (this.abortController.signal.aborted) {\n // If aborted, just return and do not schedule the nest poll\n return;\n }\n log.error('failed to poll', error);\n this.state.setPartial({ isError: true });\n } finally {\n this.state.setPartial({ isPolling: false });\n }\n\n // Do not reschedule after a reset, including when the callback handles\n // cancellation without throwing.\n if (!this.abortController.signal.aborted) {\n timeouts.push(setTimeout(poll, intervalMs));\n }\n };\n\n poll();\n\n this.stopPolling = () => {\n timeouts.forEach(clearTimeout);\n this.state.reset();\n };\n };\n}\n","export function run<T>(fn: () => T): T {\n return fn();\n}\n\nexport type Result<T, E> =\n | { data: T; error?: undefined }\n | { data?: undefined; error: E };\n\n/**\n * Many thanks to @m-tabaza for this utility... Kotlin vibes\n */\nexport function runCatching<T, E = unknown>(\n callback: () => Promise<T>,\n): Promise<Result<T, E>>;\nexport function runCatching<T, E = unknown>(callback: () => T): Result<T, E>;\nexport function runCatching<T, E = unknown>(\n callback: () => T | Promise<T>,\n): Result<T, E> | Promise<Result<T, E>> {\n try {\n const result = callback();\n\n if (result instanceof Promise) {\n return result.then((data) => ({ data })).catch((error: E) => ({ error }));\n }\n\n return { data: result };\n } catch (error) {\n return { error: error as E };\n }\n}\n","import type { ApiCaller } from '../api/api-caller';\nimport type { ActionCallDto, MessageDto } from '../types/dtos';\nimport {\n type WidgetMessageU,\n type WidgetSystemMessageU,\n} from '../types/messages';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { isExhaustive } from '../utils/is-exhaustive';\nimport { Poller } from '../utils/Poller';\nimport { runCatching } from '../utils/run-catching';\nimport type { MessageCtx } from './message.ctx';\nimport type { SessionCtx } from './session.ctx';\nimport { log } from '../utils/log';\n\nexport class ActiveSessionPollingCtx {\n private api: ApiCaller;\n private config: WidgetConfig;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n private sessionPollingIntervalSeconds: number;\n\n private poller = new Poller();\n private fetchSessionAndFullHistoryAbortController = new AbortController();\n private reconcileAbortController = new AbortController();\n /** Session the in-flight post-stream reconcile belongs to, if any. */\n private reconcilingSessionId: string | null = null;\n\n constructor({\n api,\n config,\n sessionCtx,\n messageCtx,\n sessionPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n sessionPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.config = config;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n this.sessionPollingIntervalSeconds = sessionPollingIntervalSeconds;\n\n this.registerPolling();\n }\n\n private registerPolling = () => {\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n this.fetchSessionAndHistory({ sessionId: session.id, abortSignal });\n }, this.sessionPollingIntervalSeconds * 1000);\n } else {\n this.poller.reset();\n }\n });\n\n /**\n * When the session is closed, fetch immediately instead of waiting for the\n * next poll tick, so closing messages (e.g. csat_requested) show up right away.\n */\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id && !session.isOpened) {\n try {\n this.fetchSessionAndFullHistoryAbortController =\n new AbortController();\n this.fetchSessionAndHistory({\n sessionId: session.id,\n abortSignal: this.fetchSessionAndFullHistoryAbortController.signal,\n });\n } catch (error) {\n if (!this.fetchSessionAndFullHistoryAbortController.signal.aborted) {\n log.error('failed to fetch session and full history', error);\n }\n }\n } else {\n this.fetchSessionAndFullHistoryAbortController.abort();\n }\n });\n\n /**\n * A post-stream reconcile still in flight when the active session stops\n * being the one it was started for (new chat, session switch) must not\n * land: its rows belong to the old conversation and would be appended to\n * the fresh transcript.\n */\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (this.reconcilingSessionId === null) return;\n if (session?.id === this.reconcilingSessionId) return;\n this.reconcileAbortController.abort();\n });\n };\n\n /**\n * Ingest the canonical rows the backend persisted for a just-settled\n * streamed turn. Owns a REAL abort controller — cancelled on the session\n * boundary (see `registerPolling`), which is the whole point: the signal\n * this passes must be one somebody can actually fire.\n */\n reconcileAfterStream = async (sessionId: string): Promise<void> => {\n this.reconcileAbortController.abort();\n this.reconcileAbortController = new AbortController();\n const { signal } = this.reconcileAbortController;\n this.reconcilingSessionId = sessionId;\n try {\n await this.fetchSessionAndHistory({ sessionId, abortSignal: signal });\n } catch (error) {\n // An abort is this method doing its job, not a failure.\n if (!signal.aborted) throw error;\n } finally {\n if (this.reconcilingSessionId === sessionId) {\n this.reconcilingSessionId = null;\n }\n }\n };\n\n fetchSessionAndHistory = async ({\n sessionId,\n abortSignal,\n }: {\n sessionId: string;\n abortSignal: AbortSignal;\n }): Promise<void> => {\n /**\n * This is a bit of an implicit contract... there are two cases here\n * 1. If there are no messages in state, it means the user selected a previous session from the sessions screen and got routed to the chat,\n * in this case, we want to show a loading indicator until the initial fetch is done\n * 2. There is a single message in state, which is the optimistically rendered user message,\n * in this case, we don't want to show a loading indicator\n */\n const isInitialFetch = this.messageCtx.state.get().messages.length === 0;\n if (isInitialFetch) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: true });\n }\n\n const { data } = await this.api.pollSessionAndHistory({\n sessionId,\n abortSignal,\n });\n\n if (data?.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n this.sessionCtx.setSessions([data.session]);\n }\n\n if (data?.history && data.history.length > 0) {\n // Get a fresh reference to current messages after the poll is done\n const prevMessages = this.messageCtx.state.get().messages;\n const newMessages = data.history\n .map(this.mapHistoryToMessage)\n .filter((msg): msg is WidgetMessageU => msg !== null)\n .filter(\n (newMsg) =>\n !prevMessages.some((existingMsg) => existingMsg.id === newMsg.id),\n );\n // Only commit when the poll actually surfaced NEW rows. A poll that\n // returns only already-known messages must NOT replace the array with a\n // fresh reference — that re-renders the whole transcript on every tick\n // (visible flicker during a stream, and it remounts the lazy recharts\n // chart into an empty 0-measured ResponsiveContainer). The steady state\n // of an idle/streaming session is \"poll returns the same rows\", so this\n // guard is what keeps the surface still between real updates.\n if (newMessages.length > 0) {\n this.messageCtx.state.setPartial({\n messages: [...prevMessages, ...newMessages],\n });\n if (isInitialFetch) {\n // Opening an existing session: history flows in as one batch. The user\n // is loading context, not receiving new messages — suppress the hook\n // but seed the dedup set so later polls don't re-fire these ids.\n this.messageCtx.markAsDispatchedToOnMessageReceivedHook(\n newMessages.map((m) => m.id),\n );\n } else {\n for (const newMessage of newMessages) {\n this.messageCtx.dispatchToOnMessageReceivedHook(newMessage);\n }\n }\n }\n }\n\n if (this.messageCtx.state.get().isInitialFetchLoading) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: false });\n }\n };\n\n mapHistoryToMessage = (history: MessageDto): WidgetMessageU | null => {\n const commonFields = {\n id: history.publicId,\n timestamp: history.sentAt || '',\n attachments: history.attachments || undefined,\n };\n\n if (history.sender.kind === 'user') {\n return {\n ...commonFields,\n type: 'USER',\n content: history.content.text || '',\n // Backend field name (schema.ts) → widget vocabulary.\n markedElements: history.pickedElements,\n };\n }\n\n if (history.sender.kind === 'agent') {\n return {\n ...commonFields,\n type: 'AGENT',\n component: 'agent_message',\n data: {\n message: history.content.text || '',\n },\n agent: {\n name: history.sender.name || '',\n // Do not set avatarUrl from config here... let it be taken from the config at render time\n // Only set avatar url from the backend's response\n avatarUrl: history.sender.avatar || null,\n avatar: history.sender.avatar || null,\n id: null,\n isAi: false,\n },\n };\n }\n\n if (history.sender.kind === 'ai') {\n const action =\n history.actionCalls && history.actionCalls.length > 0\n ? history.actionCalls[history.actionCalls.length - 1]\n : undefined;\n\n return {\n ...commonFields,\n type: 'AI',\n component: 'bot_message',\n agent: {\n id: null,\n name: this.config.bot?.name || '',\n isAi: true,\n // Do not set avatarUrl from config here... let it be taken from the config at render time\n avatarUrl: null,\n avatar: null,\n },\n data: {\n message: history.content.text || '',\n action: action\n ? {\n name: action.actionName,\n data: this.extractActionResult(action),\n }\n : undefined,\n },\n };\n }\n\n if (history.sender.kind === 'system') {\n const message = this.constructSystemMessage(history);\n if (message === null) return null;\n\n return { ...message };\n }\n\n return null;\n };\n\n constructSystemMessage = (\n history: MessageDto,\n ): WidgetSystemMessageU | null => {\n if (!history || !history.systemMessagePayload) return null;\n switch (history.systemMessagePayload.type) {\n case 'state_checkpoint':\n return {\n id: history.publicId,\n type: 'SYSTEM',\n subtype: 'state_checkpoint',\n data: { payload: history.systemMessagePayload.payload },\n timestamp: history.sentAt || '',\n attachments: undefined,\n };\n case 'csat_requested':\n return {\n id: history.publicId,\n type: 'SYSTEM',\n subtype: 'csat_requested',\n data: { payload: undefined },\n timestamp: history.sentAt || '',\n attachments: undefined,\n };\n case 'csat_submitted':\n return {\n id: history.publicId,\n type: 'SYSTEM',\n subtype: 'csat_submitted',\n data: {\n payload: {\n score: history.systemMessagePayload.payload.score ?? undefined,\n feedback:\n history.systemMessagePayload.payload.feedback ?? undefined,\n },\n },\n timestamp: history.sentAt || '',\n attachments: undefined,\n };\n case 'none':\n return null;\n default:\n isExhaustive(\n history.systemMessagePayload,\n this.constructSystemMessage.name,\n );\n return null;\n }\n };\n\n extractActionResult = (action: ActionCallDto) => {\n const result = action.result;\n\n if (result === null) return result;\n if (typeof result !== 'object') return result;\n\n if (\n 'responseBodyText' in result &&\n typeof result.responseBodyText === 'string'\n ) {\n const responseBodyText = result.responseBodyText;\n const parsed = runCatching(() => JSON.parse(responseBodyText)).data;\n if (parsed) return parsed;\n }\n\n return action.result;\n };\n}\n","import { PrimitiveState } from '../utils/PrimitiveState';\nimport { ApiCaller } from '../api/api-caller';\nimport { type WidgetConfig } from '../types/widget-config';\nimport { type Dto } from '../api/client';\nimport type { StorageCtx } from './storage.ctx';\nimport { v4 } from 'uuid';\nimport { log } from '../utils/log';\n\ntype ContactState = {\n contact: {\n token: string;\n externalId: string | undefined;\n } | null;\n extraCollectedData: Record<string, string> | undefined;\n isCreatingUnverifiedContact: boolean;\n isErrorCreatingUnverifiedContact: boolean;\n};\n\nexport class ContactCtx {\n private config: WidgetConfig;\n private storageCtx?: StorageCtx;\n private api: ApiCaller;\n state: PrimitiveState<ContactState>;\n\n constructor({\n config,\n api,\n storageCtx,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n storageCtx?: StorageCtx;\n }) {\n this.config = config;\n this.storageCtx = storageCtx;\n this.api = api;\n\n this.state = new PrimitiveState<ContactState>({\n contact: config.user?.token\n ? {\n token: config.user.token,\n // Set optional externalId from config... not local storage\n externalId: config.user.externalId,\n }\n : null,\n extraCollectedData: undefined,\n isCreatingUnverifiedContact: false,\n isErrorCreatingUnverifiedContact: false,\n });\n\n this.autoCreateUnverifiedUserIfNotExists();\n }\n\n shouldCollectData = (): boolean => {\n if (!this.state.get().contact?.token && this.config.collectUserData) {\n return true;\n }\n return false;\n };\n\n private autoCreateUnverifiedUserIfNotExists = async () => {\n /**\n * If token is passed in config... we consider it as a verified user and do nothing (we don't force generate an externalId)\n * If a non-verified user take their token and place it in the config... the backend will refuse their requests saying that a non-verified token must have an externalId to create and get sessions\n */\n if (this.config.user?.token) return;\n\n /**\n * If collectUserData is true... we check if the user entered their credentials before, otherwise, show them the welcome screen so they can enter their credentials\n */\n if (this.config.collectUserData && !this.config.user?.data?.email) {\n /**\n * If extra data collection fields are passed,\n * we do not check for a persisted token.\n * This will force the contact to enter the extra data fields every time they visit the page.\n */\n if (this.config.extraDataCollectionFields?.length) {\n return;\n }\n\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n }\n // return early whether there is a persisted token or not\n return;\n }\n\n /**\n * If there is no email, then it is an anonymous contact, we check if the contact is persisted or we create a new one\n */\n if (!this.config.user?.data?.email) {\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n // return early only if there is a persisted token\n return;\n }\n }\n\n /**\n * If we reach here... then it is one of two\n * 1. There is an email passed in the config, let's just upsert the unverified contact without checking for persistence; maybe the email in the config did change.\n * 2. It is an anonymous contact (without an email) using this device for the first time.\n *\n * This is still safe even if the email in the config is tampered with by the contact, because there is a client-side externalId that will be generated for the current device...\n * So, only sessions created on this device will be accessible.\n */\n await this.createUnverifiedContact({\n email: this.config.user?.data?.email,\n non_verified_name: this.config.user?.data?.name,\n non_verified_custom_data: this.config.user?.data?.customData,\n });\n };\n\n createUnverifiedContact = async (\n payload: Dto['CreateUnverifiedContactDto'],\n extraCollectedData?: Record<string, string>,\n ): Promise<void> => {\n this.state.setPartial({ extraCollectedData });\n\n try {\n this.state.setPartial({\n isCreatingUnverifiedContact: true,\n isErrorCreatingUnverifiedContact: false,\n });\n\n const { data } = await this.api.createUnverifiedContact(payload);\n if (data?.token) {\n await this.setUnverifiedContact(data.token);\n } else {\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n }\n } catch (e) {\n // A THROWN failure (offline, DNS, 5xx) must land on the same state as a\n // response that carried no token — callers read the flag, not an\n // exception. Without this catch the rejection escapes to the widget's\n // fire-and-forget send (`void sendMessage(...)`) and surfaces as an\n // unhandled promise rejection in the EMBEDDER's page, while the flag\n // stays false so nothing in the UI ever reports the failure.\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n log.error('failed to create an unverified contact', {\n _e: e instanceof Error ? e.message : String(e),\n });\n } finally {\n this.state.setPartial({ isCreatingUnverifiedContact: false });\n }\n };\n\n /**\n * A persisted contact token can go stale — it no longer resolves to a\n * contact and the backend answers 401 \"Invalid token\". Drop the dead token,\n * clear auth, and mint a fresh anonymous contact so the widget self-heals\n * instead of getting stuck on create-session. No-op for a config-provided\n * verified token (authoritative — re-minting it is not ours to do).\n * Returns true if a fresh contact token was obtained.\n */\n recoverFromStaleToken = async (): Promise<boolean> => {\n if (this.config.user?.token) return false;\n this.api.setAuthToken('');\n // `null`, not `undefined` — `ContactState.contact` declares `| null` as its\n // one \"no contact\" sentinel, and a second representation eventually\n // disagrees with a `=== null` check somewhere downstream.\n this.state.setPartial({ contact: null });\n try {\n await this.storageCtx?.clearContactToken();\n // The remembered conversation belonged to the dead contact — the fresh\n // one must never be handed a pointer into somebody else's session.\n await this.storageCtx?.clearActiveSessionId();\n } catch (error) {\n // Storage is an embedder-provided adapter. A broken adapter must not keep\n // the runtime authenticated with a token the server already rejected.\n log.warn('failed to clear a stale contact token', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n await this.createUnverifiedContact({\n email: this.config.user?.data?.email,\n non_verified_name: this.config.user?.data?.name,\n non_verified_custom_data: this.config.user?.data?.customData,\n });\n return Boolean(this.state.get().contact?.token);\n };\n\n setUnverifiedContact = async (token: string) => {\n const persistedExternalId = await this.storageCtx?.getExternalContactId();\n /** Give priority to `externalId` from the config */\n const externalId: string =\n this.config.user?.externalId || persistedExternalId || v4();\n this.api.setAuthToken(token);\n // Set token in state after setting the token in the api handler\n await this.storageCtx?.setContactToken(token);\n await this.storageCtx?.setExternalContactId(externalId);\n this.state.setPartial({ contact: { token, externalId } });\n };\n}\n","import { v4 } from 'uuid';\nimport type { ApiCaller } from '../api/api-caller';\nimport { PrimitiveState } from '../utils/PrimitiveState';\n\nexport interface FileWithProgress {\n status: 'pending' | 'uploading' | 'success' | 'error';\n id: string;\n file: File;\n fileUrl?: string;\n progress: number;\n error?: string;\n}\n\n/** Attachments belong to their conversation, not the mounted composer. */\nexport class UploadCtx {\n state = new PrimitiveState<FileWithProgress[]>([]);\n private controllers = new Map<string, AbortController>();\n constructor(private api: ApiCaller) {}\n\n appendFiles = (files: File[]) => {\n const pending = files.map(\n (file): FileWithProgress => ({\n file,\n id: v4(),\n status: 'pending',\n progress: 0,\n }),\n );\n this.state.set([...this.state.get(), ...pending]);\n pending.forEach((file) => void this.upload(file));\n };\n\n private update(id: string, update: Partial<FileWithProgress>) {\n this.state.set(\n this.state\n .get()\n .map((file) => (file.id === id ? { ...file, ...update } : file)),\n );\n }\n\n private async upload(file: FileWithProgress) {\n const controller = new AbortController();\n this.controllers.set(file.id, controller);\n this.update(file.id, { status: 'uploading' });\n try {\n const response = await this.api.uploadFile({\n file: file.file,\n abortSignal: controller.signal,\n onProgress: (progress) => this.update(file.id, { progress }),\n });\n this.update(file.id, {\n status: 'success',\n fileUrl: response.fileUrl,\n progress: 100,\n });\n } catch (error) {\n if (!controller.signal.aborted)\n this.update(file.id, {\n status: 'error',\n progress: 0,\n error: error instanceof Error ? error.message : 'Upload failed',\n });\n } finally {\n this.controllers.delete(file.id);\n }\n }\n\n cancel = (id: string) => {\n this.controllers.get(id)?.abort();\n this.controllers.delete(id);\n this.state.set(this.state.get().filter((file) => file.id !== id));\n };\n\n reset = () => {\n this.controllers.forEach((controller) => controller.abort());\n this.controllers.clear();\n this.state.reset();\n };\n}\n","import { v4 as uuidv4 } from 'uuid';\n\nexport function genUuid() {\n return uuidv4();\n}\n","import type { ApiCaller } from '../api/api-caller';\nimport type { Dto } from '../api/client';\nimport { genUuid } from '../utils/uuid';\nimport type { MessageCtx } from './message.ctx';\nimport type { SessionCtx } from './session.ctx';\n\nexport class CsatCtx {\n private api: ApiCaller;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n\n constructor({\n api,\n sessionCtx,\n messageCtx,\n }: {\n api: ApiCaller;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n }) {\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n }\n\n submitCsat = async (\n body: Pick<Dto['WidgetSubmitCsatInputDto'], 'score' | 'feedback'>,\n ) => {\n const currentSessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!currentSessionId) {\n return { data: null, error: 'No session id found' };\n }\n\n const uuid = genUuid();\n this.messageCtx.state.setPartial({\n messages: [\n ...this.messageCtx.state.get().messages,\n {\n id: uuid,\n type: 'SYSTEM',\n subtype: 'csat_submitted',\n timestamp: new Date().toISOString(),\n data: {\n payload: {\n score: body.score,\n feedback: body.feedback,\n },\n },\n },\n ],\n });\n\n const { data, error } = await this.api.submitCsat({\n ...body,\n system_message_uuid: uuid,\n session_id: currentSessionId,\n });\n return { data, error };\n };\n}\n","/**\n * Spoken-command grammar for voice dictation.\n *\n * The transcription model already auto-punctuates and capitalizes, so spoken\n * punctuation (\"comma\", \"period\") is deliberately NOT converted — saying\n * punctuation aloud is optional and the words stay literal unless they form a\n * standalone command sentence. What IS recognized (Dragon-style) are\n * structural and control commands spoken as their own utterance:\n *\n * \"new line\" → line break\n * \"new paragraph\" → paragraph break\n * \"bullet point\"/\"next item\" → start a list item (\"- …\")\n * \"scratch that\"/\"delete that\"→ remove the previous sentence\n * \"stop dictation\"/\"stop listening\" → end the session\n * \"send message\"/\"send it\" → end the session and submit (composers)\n *\n * Precision guards:\n * - A phrase only counts as a command when the model rendered it as its own\n * sentence: preceded by start-of-text or sentence-ending punctuation, and\n * FOLLOWED by punctuation (the model punctuates a spoken pause — the pause\n * IS the signal, exactly like Dragon). \". Send it to the team\" never fires.\n * - A completed phrase at stream end with no punctuation yet stays PENDING\n * until the next delta disambiguates it — except in `final` mode (the user\n * stopped: stopping is the pause, so the phrase resolves as a command).\n * - Command phrases are scoped to English + the session's UI language, so an\n * Italian speaker's ordinary \"Cancella.\" can't fire scratch-that in an\n * English session and vice versa.\n */\n\nexport type DictationControlAction = 'stop' | 'send';\n\nexport interface ProcessedDictation {\n /** Text ready for insertion, with commands applied. */\n text: string;\n /**\n * Trailing raw characters withheld from insertion because they could still\n * grow into a command phrase (\"New paragr…\"), or ARE a completed phrase\n * awaiting its terminator (\"Send it\"). Empty in `final` mode.\n */\n pendingTail: string;\n /** Control command encountered (processing stops at that point). */\n control: DictationControlAction | null;\n}\n\nexport interface ProcessOptions {\n /** ISO language hint (same value sent to the transcription session). */\n language?: string | undefined;\n /**\n * End-of-stream semantics: the user stopped, so a completed command phrase\n * at the very end fires without waiting for punctuation, and no text is\n * withheld — partial phrases are released as literal words.\n */\n final?: boolean;\n}\n\ntype CommandAction =\n | 'newline'\n | 'newparagraph'\n | 'bullet'\n | 'scratch'\n | 'stop'\n | 'send';\n\ntype CommandLanguage = 'en' | 'es' | 'fr' | 'de' | 'pt' | 'it';\n\n// Latin-script languages with reliable word boundaries. Other languages still\n// dictate perfectly — they just use the composer's buttons instead of spoken\n// control phrases.\nconst COMMANDS: Array<{\n action: CommandAction;\n phrases: Record<CommandLanguage, string[]>;\n}> = [\n {\n action: 'newparagraph',\n phrases: {\n en: ['new paragraph'],\n es: ['nuevo párrafo', 'nuevo parrafo'],\n fr: ['nouveau paragraphe'],\n de: ['neuer absatz'],\n pt: ['novo parágrafo', 'novo paragrafo'],\n it: ['nuovo paragrafo'],\n },\n },\n {\n action: 'newline',\n phrases: {\n en: ['new line', 'newline'],\n es: ['nueva línea', 'nueva linea'],\n fr: ['nouvelle ligne', 'à la ligne', 'a la ligne'],\n de: ['neue zeile'],\n pt: ['nova linha'],\n it: ['nuova riga'],\n },\n },\n {\n action: 'bullet',\n phrases: {\n en: [\n 'bullet point',\n 'new bullet',\n 'next bullet',\n 'bullet list',\n 'list item',\n 'next item',\n 'new item',\n ],\n es: ['nuevo punto', 'nueva viñeta', 'nueva vineta'],\n fr: ['nouvelle puce'],\n de: ['neuer punkt', 'aufzählungspunkt'],\n pt: ['novo item', 'novo marcador'],\n it: ['nuovo punto', 'nuovo elenco'],\n },\n },\n {\n action: 'scratch',\n phrases: {\n en: ['scratch that', 'delete that'],\n es: ['bórralo', 'borra eso'],\n fr: ['efface ça', 'efface ca'],\n de: ['lösch das', 'losch das'],\n pt: ['apaga isso'],\n it: ['cancella'],\n },\n },\n {\n action: 'stop',\n phrases: {\n en: ['stop dictation', 'stop dictating', 'stop listening'],\n es: ['detener dictado'],\n fr: ['arrête la dictée', 'arrete la dictee'],\n de: ['diktat beenden'],\n pt: ['parar ditado'],\n it: ['stop dettatura'],\n },\n },\n {\n action: 'send',\n phrases: {\n en: ['send message', 'send it'],\n es: ['enviar mensaje'],\n fr: ['envoie le message'],\n de: ['nachricht senden'],\n pt: ['enviar mensagem'],\n it: ['invia messaggio'],\n },\n },\n];\n\nconst SUPPORTED_LANGUAGES: CommandLanguage[] = [\n 'en',\n 'es',\n 'fr',\n 'de',\n 'pt',\n 'it',\n];\n\nfunction isCommandLanguage(value: string): value is CommandLanguage {\n return (SUPPORTED_LANGUAGES as string[]).includes(value);\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\ninterface Grammar {\n /** Standalone-utterance matcher (terminator REQUIRED). */\n regex: RegExp;\n /** End-of-stream matcher (terminator optional — `$` counts as the pause). */\n finalRegex: RegExp;\n phraseToAction: Map<string, CommandAction>;\n longestPhrase: number;\n}\n\n// One alternation per language set, longest phrase first so \"new paragraph\"\n// wins over a shorter overlap. Boundaries:\n// before: start of text (tolerating leading whitespace — realtime deltas\n// are space-prefixed tokens), newline, or sentence-ending punctuation, as a\n// LOOKBEHIND so a command's own terminator stays available as the boundary\n// of a directly following command (\"…New line. New paragraph.\")\n// after: [.,!?;:] then (lookahead) whitespace or end.\nfunction buildGrammar(languages: CommandLanguage[]): Grammar {\n const entries = COMMANDS.flatMap((c) =>\n languages.flatMap((lang) =>\n c.phrases[lang].map((phrase) => ({ phrase, action: c.action })),\n ),\n );\n const alternation = entries\n .map((e) => escapeRegex(e.phrase))\n .sort((a, b) => b.length - a.length)\n .join('|');\n const before = String.raw`(?<=^\\s{0,3}|[.!?\\n]\\s{0,3})`;\n return {\n regex: new RegExp(\n `${before}(${alternation})` + String.raw`([.,!?;:])(?=\\s|$)`,\n 'giu',\n ),\n finalRegex: new RegExp(\n `${before}(${alternation})` + String.raw`([.,!?;:]?)(?=\\s|$)`,\n 'giu',\n ),\n phraseToAction: new Map(\n entries.map((e) => [e.phrase.toLowerCase(), e.action]),\n ),\n longestPhrase: Math.max(...entries.map((e) => e.phrase.length)),\n };\n}\n\nconst grammarCache = new Map<string, Grammar>();\n\nfunction grammarFor(language: string | undefined): Grammar {\n const lang =\n language && isCommandLanguage(language) && language !== 'en'\n ? language\n : null;\n const key = lang ?? 'en';\n let grammar = grammarCache.get(key);\n if (!grammar) {\n grammar = buildGrammar(lang ? ['en', lang] : ['en']);\n grammarCache.set(key, grammar);\n }\n return grammar;\n}\n\n/** Remove the last sentence (or last line when no terminator) from `text`. */\nfunction deleteLastSentence(text: string): string {\n const trimmed = text.replace(/\\s+$/, '');\n if (!trimmed) return '';\n // Ignore a terminator that ends the text itself, then cut after the previous one.\n const body = trimmed.replace(/[.!?]+$/, '');\n let cut = -1;\n for (let i = body.length - 1; i >= 0; i--) {\n const ch = body[i];\n if (ch === '.' || ch === '!' || ch === '?' || ch === '\\n') {\n cut = i + 1;\n break;\n }\n }\n if (cut === -1) return '';\n return `${body.slice(0, cut)} `.replace(/\\n $/, '\\n');\n}\n\n// After a break (optionally into a bullet), or a bullet at the very start —\n// but never the plain first word: dictation may continue an existing sentence.\n// Constructor form: the `u`-flag literal trips TS1501 under the app's ts target.\nconst LOWERCASE_AFTER_BREAK_REGEX = new RegExp(\n String.raw`(^- |\\n(?:- )?)(\\p{Ll})`,\n 'gu',\n);\n\nfunction capitalizeAfterBreaks(text: string): string {\n return text.replace(\n LOWERCASE_AFTER_BREAK_REGEX,\n (_m, brk: string, ch: string) => brk + ch.toUpperCase(),\n );\n}\n\n/** Sentence-boundary check for a phrase starting where `before` ends — only\n * the trailing few characters matter (bounded: never scans the transcript). */\nfunction endsAtSentenceBoundary(before: string): boolean {\n // Start of text, tolerating a short space prefix (realtime deltas arrive\n // as space-prefixed tokens).\n if (before.length <= 3 && /^\\s*$/.test(before)) return true;\n return /[.!?\\n]\\s{0,3}$/.test(before.slice(-6));\n}\n\nexport class DictationCommandUtils {\n /**\n * Process the full raw transcript accumulated so far into insertable text.\n * Pure and deterministic: always called with the entire raw string so the\n * result never depends on delta chunking.\n */\n static process(raw: string, options?: ProcessOptions): ProcessedDictation {\n const grammar = grammarFor(options?.language);\n const pendingTail = options?.final\n ? ''\n : DictationCommandUtils.commandPrefixTail(raw, options?.language);\n const consumable = raw.slice(0, raw.length - pendingTail.length);\n const regex = options?.final ? grammar.finalRegex : grammar.regex;\n\n let out = '';\n let control: DictationControlAction | null = null;\n let cursor = 0;\n\n for (const match of Array.from(consumable.matchAll(regex))) {\n const [, phrase = ''] = match;\n const action = grammar.phraseToAction.get(phrase.toLowerCase());\n if (!action) continue;\n\n // Keep everything before the command (the boundary terminator is a\n // lookbehind, so it's part of the kept text), drop the phrase itself.\n out += consumable.slice(cursor, match.index);\n cursor = match.index + match[0].length;\n\n if (action === 'newline') out = `${out.replace(/[ \\t]+$/, '')}\\n`;\n else if (action === 'newparagraph')\n out = `${out.replace(/[ \\t]+$/, '')}\\n\\n`;\n else if (action === 'bullet') {\n const trimmed = out.replace(/[ \\t]+$/, '');\n out =\n trimmed === '' || trimmed.endsWith('\\n')\n ? `${trimmed}- `\n : `${trimmed}\\n- `;\n } else if (action === 'scratch') out = deleteLastSentence(out);\n else {\n control = action === 'send' ? 'send' : 'stop';\n break;\n }\n }\n if (control === null) out += consumable.slice(cursor);\n\n // Tidy: no leading whitespace, no spaces flanking breaks, single spacing\n // (commands leave doubled gaps behind), max double break, sentences after\n // a break start uppercase.\n const text = capitalizeAfterBreaks(\n out\n .replace(/^\\s+/, '')\n .replace(/[ \\t]+\\n/g, '\\n')\n .replace(/\\n[ \\t]+/g, '\\n')\n .replace(/(^|\\n)- +/g, '$1- ')\n .replace(/ {2,}/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n'),\n );\n\n return { text, pendingTail, control };\n }\n\n /**\n * Longest suffix of `raw` that could still become a command — a proper\n * prefix of a phrase (\"New paragr…\") OR a COMPLETED phrase with no\n * terminator yet (\"…Send it\"). Both are withheld from insertion: the next\n * delta either brings punctuation (the phrase was a spoken command) or more\n * words (\"Send it to the team\" — released as ordinary text). Firing a\n * control command from an intermediate delta would stop or submit\n * mid-sentence.\n */\n static commandPrefixTail(raw: string, language?: string | undefined): string {\n const grammar = grammarFor(language);\n const maxLen = Math.min(raw.length, grammar.longestPhrase + 2);\n for (let len = maxLen; len > 0; len--) {\n const start = raw.length - len;\n // Candidate must begin at a sentence boundary (same guard as matching).\n if (!endsAtSentenceBoundary(raw.slice(0, start))) continue;\n const tail = raw.slice(start).toLowerCase();\n const candidate = tail.replace(/^\\s+/, '');\n if (!candidate) continue;\n for (const phrase of Array.from(grammar.phraseToAction.keys())) {\n if (phrase.startsWith(candidate)) {\n // Exclude the leading whitespace — it belongs to the consumable text.\n return raw.slice(start + (tail.length - candidate.length));\n }\n }\n }\n return '';\n }\n\n /**\n * True when the current pending tail is a COMPLETED phrase (not a partial\n * prefix) — i.e. a silence pause would resolve it into a command. Used by\n * the manager's silence timer.\n */\n static pendingTailIsCompletePhrase(\n raw: string,\n language?: string | undefined,\n ): boolean {\n const tail = DictationCommandUtils.commandPrefixTail(raw, language)\n .trim()\n .toLowerCase();\n if (!tail) return false;\n return grammarFor(language).phraseToAction.has(tail);\n }\n}\n","/**\n * Pure helpers for the dictation hook: paced text reveal (\"drip\") and the\n * transcription language hint.\n */\n\n/** Cadence of the word-drip renderer (ms per step). */\nexport const DRIP_INTERVAL_MS = 55;\n/** When the backlog grows past this, step faster instead of falling behind. */\nconst DRIP_BACKLOG_CHARS = 90;\n\nexport class DictationDripUtils {\n /**\n * Next paced step toward `processed`: normally one word per tick so text\n * flows evenly instead of landing in bursty chunks; proportionally larger\n * steps when a burst put us far behind. Assumes `processed` extends\n * `displayed` (callers reconcile immediately otherwise).\n */\n static nextDripText({\n displayed,\n processed,\n }: {\n displayed: string;\n processed: string;\n }): string {\n if (processed.length <= displayed.length) return processed;\n const backlog = processed.length - displayed.length;\n if (backlog > DRIP_BACKLOG_CHARS) {\n return processed.slice(0, displayed.length + Math.ceil(backlog / 3));\n }\n // Advance past leading whitespace, then to the end of the next word.\n let i = displayed.length;\n while (i < processed.length && /\\s/.test(processed.charAt(i))) i++;\n while (i < processed.length && !/\\s/.test(processed.charAt(i))) i++;\n // Unspaced scripts (CJK): cap the step so it still drips.\n if (i - displayed.length > 12) i = displayed.length + 6;\n return processed.slice(0, Math.max(i, displayed.length + 1));\n }\n\n /** Normalize a BCP-47 browser locale into the hint OpenAI accepts. */\n static languageHint(locale: string | undefined): string | undefined {\n if (!locale) return undefined;\n const lower = locale.toLowerCase();\n // Regional Chinese forms are meaningful to the model; everything else uses\n // the primary subtag (\"en-US\" → \"en\").\n if (/^zh-(cn|tw|hk)$/.test(lower)) return lower;\n const primary = lower.split('-')[0];\n return primary && /^[a-z]{2,3}$/.test(primary) ? primary : undefined;\n }\n}\n","import type { DictationMint } from './dictation-session';\n\n/** Don't reuse a token that could expire mid-handshake. */\nconst REUSE_SAFETY_MARGIN_MS = 20_000;\n\n/**\n * Session-token reuse: an ephemeral client secret can open multiple realtime\n * sessions until it expires (120s TTL), so re-minting on every activation\n * wastes a full backend round trip. The cache holds the latest mint and\n * hands it back while comfortably inside its TTL; hovering the mic\n * pre-warms it so the first click starts instantly too.\n *\n * One instance per widget (owned by DictationCtx), never module state — two\n * widgets on one page must not share a mint across orgs.\n */\nexport class DictationMintCache {\n private cached: DictationMint | null = null;\n private inflight: Promise<DictationMint> | null = null;\n\n /** Valid cached mint, or null. */\n get(): DictationMint | null {\n if (!this.cached) return null;\n const expiresAtMs = Date.parse(this.cached.expiresAt);\n if (\n Number.isNaN(expiresAtMs) ||\n expiresAtMs - Date.now() < REUSE_SAFETY_MARGIN_MS\n ) {\n this.cached = null;\n return null;\n }\n return this.cached;\n }\n\n /**\n * Resolve a mint, deduping concurrent requests (hover-prewarm racing a\n * click reuses the same in-flight promise instead of double-minting).\n */\n async resolve(\n mintFresh: () => Promise<DictationMint>,\n ): Promise<DictationMint> {\n const valid = this.get();\n if (valid) return valid;\n if (!this.inflight) {\n this.inflight = mintFresh()\n .then((mint) => {\n this.cached = mint;\n return mint;\n })\n .finally(() => {\n this.inflight = null;\n });\n }\n return this.inflight;\n }\n\n /** Drop the cache (e.g. after a failed handshake — token may be stale). */\n clear() {\n this.cached = null;\n }\n}\n","/** A plain object read off the wire (not null, not an array). */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { isRecord } from '../utils/is-record';\nimport { log } from '../utils/log';\n/**\n * One live dictation session: microphone → WebRTC → realtime transcription.\n * The browser talks to the transcription service directly with a short-lived\n * ephemeral token minted by the backend — audio and transcripts never touch\n * OpenCX servers, and the real API key never reaches the browser.\n *\n * WebRTC (not WebSocket) because the browser stack handles Opus encoding,\n * jitter buffering and echo cancellation natively — no PCM plumbing, lowest\n * practical latency.\n *\n * Errors are CODES (the widget renders them through its translation table).\n */\n\nexport type DictationSessionState =\n | 'idle'\n | 'connecting'\n | 'listening'\n | 'stopped'\n | 'error';\n\nexport type DictationErrorCode =\n /** No getUserMedia, permission denied, or no device. */\n | 'microphone'\n /** Mint, handshake, or transport failure. */\n | 'unavailable';\n\nexport interface DictationMint {\n token: string;\n expiresAt: string;\n model: string;\n}\n\ntype ServerEvent = {\n type: string;\n delta: string | undefined;\n errorMessage: string | undefined;\n};\n\n/** The three fields dictation reads off a realtime server event. */\nfunction parseServerEvent(value: unknown): ServerEvent | null {\n if (!isRecord(value) || typeof value.type !== 'string') return null;\n const error = isRecord(value.error) ? value.error : null;\n return {\n type: value.type,\n delta: typeof value.delta === 'string' ? value.delta : undefined,\n errorMessage:\n error && typeof error.message === 'string' ? error.message : undefined,\n };\n}\n\nconst REALTIME_CALLS_URL = 'https://api.openai.com/v1/realtime/calls';\n\n/** Hard cap so an abandoned tab never leaves the mic streaming forever. */\nconst MAX_SESSION_MS = 10 * 60 * 1000;\n/** If the session isn't live shortly after starting (mint + mic + handshake\n * all included), bail out — never leave a mic open on a hung connect. */\nconst CONNECT_TIMEOUT_MS = 15_000;\n/** How long a transient WebRTC 'disconnected' may last before giving up. */\nconst DISCONNECT_GRACE_MS = 5_000;\n\nclass DictationMicrophoneError extends Error {}\n\nexport class DictationSession {\n private readonly mintToken: () => Promise<DictationMint>;\n private readonly onDelta: (delta: string) => void;\n private readonly onState: (state: DictationSessionState) => void;\n private readonly onError: (code: DictationErrorCode) => void;\n private readonly onLevel: ((level: number) => void) | undefined;\n\n private state: DictationSessionState = 'idle';\n private pc: RTCPeerConnection | null = null;\n private dc: RTCDataChannel | null = null;\n private stream: MediaStream | null = null;\n private audioContext: AudioContext | null = null;\n private levelRaf = 0;\n private timers: ReturnType<typeof setTimeout>[] = [];\n private loggedParseFailure = false;\n\n constructor({\n mintToken,\n onDelta,\n onState,\n onError,\n onLevel,\n }: {\n mintToken: () => Promise<DictationMint>;\n onDelta: (delta: string) => void;\n onState: (state: DictationSessionState) => void;\n onError: (code: DictationErrorCode) => void;\n onLevel?: (level: number) => void;\n }) {\n this.mintToken = mintToken;\n this.onDelta = onDelta;\n this.onState = onState;\n this.onError = onError;\n this.onLevel = onLevel;\n }\n\n async start() {\n if (this.state !== 'idle') return;\n this.setState('connecting');\n\n // Watchdogs arm IMMEDIATELY — mint, permission prompt, or the SDP fetch\n // can all hang, and none of them may leave the mic open forever.\n this.timers.push(\n setTimeout(() => {\n if (this.state === 'connecting') this.fail('unavailable');\n }, CONNECT_TIMEOUT_MS),\n );\n this.timers.push(setTimeout(() => this.stop(), MAX_SESSION_MS));\n\n try {\n // Mic first — the permission prompt is the slowest step; mint in parallel.\n // If mint rejects while the permission prompt is still open, the\n // eventually-resolved stream must not stay hot: drain it on arrival.\n const micPromise = this.requestMicrophone();\n void micPromise\n .then((stream) => {\n if (this.isTornDown() || (this.stream && this.stream !== stream)) {\n stream.getTracks().forEach((t) => t.stop());\n }\n })\n .catch(() => undefined); // surfaced via the await below\n const [stream, mint] = await Promise.all([micPromise, this.mintToken()]);\n if (this.isTornDown()) {\n stream.getTracks().forEach((t) => t.stop());\n return;\n }\n this.stream = stream;\n this.startLevelMeter(stream);\n\n const pc = new RTCPeerConnection();\n this.pc = pc;\n const [track] = stream.getAudioTracks();\n if (!track) throw new DictationMicrophoneError('No audio track');\n pc.addTrack(track, stream);\n\n const dc = pc.createDataChannel('oai-events');\n this.dc = dc;\n dc.addEventListener('message', (event) =>\n this.handleServerEvent(event.data),\n );\n // The mic track is already flowing once the connection is up — don't\n // make the user wait for the first server event to start speaking.\n dc.addEventListener('open', () => {\n if (this.state === 'connecting') this.setState('listening');\n });\n\n pc.addEventListener('connectionstatechange', () => {\n if (pc.connectionState === 'failed') {\n this.fail('unavailable');\n return;\n }\n // 'disconnected' is transient and routinely self-recovers — only give\n // up if it doesn't come back within a grace period.\n if (pc.connectionState === 'disconnected') {\n this.timers.push(\n setTimeout(() => {\n if (this.pc === pc && pc.connectionState !== 'connected') {\n this.fail('unavailable');\n }\n }, DISCONNECT_GRACE_MS),\n );\n }\n });\n\n const offer = await pc.createOffer();\n await pc.setLocalDescription(offer);\n\n const sdpResponse = await fetch(REALTIME_CALLS_URL, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${mint.token}`,\n 'Content-Type': 'application/sdp',\n },\n body: offer.sdp,\n });\n if (!sdpResponse.ok) {\n throw new Error(`Realtime handshake failed (${sdpResponse.status})`);\n }\n const answerSdp = await sdpResponse.text();\n if (this.isTornDown()) return;\n await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });\n } catch (e) {\n if (e instanceof DictationMicrophoneError) {\n this.fail('microphone');\n } else {\n log.error('dictation session failed to start', {\n _e: e instanceof Error ? e.message : String(e),\n });\n this.fail('unavailable');\n }\n }\n }\n\n stop() {\n if (this.state === 'stopped') return;\n this.teardown();\n this.setState('stopped');\n }\n\n private async requestMicrophone(): Promise<MediaStream> {\n if (!navigator.mediaDevices?.getUserMedia) {\n throw new DictationMicrophoneError('Microphone is not supported');\n }\n try {\n return await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n });\n } catch (e) {\n throw new DictationMicrophoneError(\n e instanceof DOMException ? e.name : 'Could not access the microphone',\n );\n }\n }\n\n private handleServerEvent(raw: unknown) {\n if (typeof raw !== 'string') return;\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n if (!this.loggedParseFailure) {\n this.loggedParseFailure = true;\n log.error('dictation server event was not valid JSON', {\n snippet: raw.slice(0, 120),\n });\n }\n return;\n }\n const event = parseServerEvent(parsed);\n if (!event) return;\n\n const { type, delta } = event;\n if (\n type === 'session.created' ||\n type === 'transcription_session.created'\n ) {\n this.setState('listening');\n return;\n }\n if (type === 'conversation.item.input_audio_transcription.delta' && delta) {\n // First delta can arrive before we noticed session.created.\n if (this.state === 'connecting') this.setState('listening');\n this.onDelta(delta);\n return;\n }\n if (type === 'error') {\n log.error('dictation server event error', {\n _e: event.errorMessage ?? 'unknown',\n });\n this.fail('unavailable');\n }\n }\n\n private startLevelMeter(stream: MediaStream) {\n if (!this.onLevel) return;\n try {\n const audioContext = new AudioContext();\n this.audioContext = audioContext;\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 512;\n source.connect(analyser);\n const data = new Uint8Array(analyser.frequencyBinCount);\n const tick = () => {\n analyser.getByteTimeDomainData(data);\n let sum = 0;\n for (let i = 0; i < data.length; i++) {\n const centered = ((data[i] ?? 128) - 128) / 128;\n sum += centered * centered;\n }\n const rms = Math.sqrt(sum / data.length);\n this.onLevel?.(Math.min(1, rms * 4));\n this.levelRaf = requestAnimationFrame(tick);\n };\n this.levelRaf = requestAnimationFrame(tick);\n } catch (e) {\n // Level meter is decorative — dictation works without it.\n log.error('dictation level meter unavailable', {\n _e: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n private isTornDown() {\n return this.state === 'stopped' || this.state === 'error';\n }\n\n private fail(code: DictationErrorCode) {\n if (this.isTornDown()) return;\n this.teardown();\n this.setState('error');\n this.onError(code);\n }\n\n private teardown() {\n this.timers.forEach((t) => clearTimeout(t));\n this.timers = [];\n if (this.levelRaf) cancelAnimationFrame(this.levelRaf);\n this.levelRaf = 0;\n this.dc?.close();\n this.dc = null;\n this.pc?.close();\n this.pc = null;\n this.stream?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n void this.audioContext?.close().catch((e) => {\n log.error('failed to close dictation audio context', {\n _e: String(e),\n });\n });\n this.audioContext = null;\n }\n\n private setState(state: DictationSessionState) {\n if (this.state === state) return;\n this.state = state;\n this.onState(state);\n }\n}\n","import type { ApiCaller } from '../api/api-caller';\nimport { DictationCommandUtils } from '../dictation/dictation-commands.utils';\nimport {\n DRIP_INTERVAL_MS,\n DictationDripUtils,\n} from '../dictation/dictation-drip.utils';\nimport { DictationMintCache } from '../dictation/dictation-mint-cache';\nimport {\n DictationSession,\n type DictationErrorCode,\n type DictationMint,\n type DictationSessionState,\n} from '../dictation/dictation-session';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport { log } from '../utils/log';\n\nexport type DictationStatus = 'idle' | 'connecting' | 'listening';\n\nexport type DictationCtxState = {\n status: DictationStatus;\n /** Last failure, cleared on the next start. */\n error: DictationErrorCode | null;\n};\n\n/**\n * Where dictated text lands. The widget composer is a plain textarea whose\n * value is React state, so the target is just \"what is there now\" and \"set\n * it\". Text is appended after whatever the visitor already typed; a manual\n * edit inside the dictated region ends the session (their edit wins).\n */\nexport interface DictationTarget {\n getValue: () => string;\n setValue: (value: string) => void;\n /** Fired for the spoken \"send message\" command, after the text is final. */\n onSend?: (() => void) | undefined;\n}\n\n/** A completed command phrase left hanging this long resolves as spoken\n * (the pause IS the command terminator when the model hasn't punctuated). */\nconst SILENCE_COMMAND_MS = 1_300;\n\nconst IDLE: DictationCtxState = { status: 'idle', error: null };\n\n/**\n * Voice dictation for the composer: mic → realtime transcription → the\n * textarea, with the spoken-command grammar (\"new line\",\n * \"scratch that\", \"send it\") and paced word reveal. One session per widget;\n * `start` on a live session restarts it against the new target.\n */\nexport class DictationCtx {\n public state = new PrimitiveState<DictationCtxState>(IDLE);\n /** 0..1 mic level — read inside a rAF loop, never during render. */\n public readonly levelRef = { current: 0 };\n\n private readonly api: ApiCaller;\n private readonly config: WidgetConfig;\n private readonly mintCache = new DictationMintCache();\n\n private session: DictationSession | null = null;\n private target: DictationTarget | null = null;\n private language: string | undefined;\n /** Composer content when dictation started — dictated text follows it. */\n private prefix = '';\n private raw = '';\n private processed = '';\n private displayed = '';\n private dripTimer: ReturnType<typeof setInterval> | null = null;\n private silenceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor({ api, config }: { api: ApiCaller; config: WidgetConfig }) {\n this.api = api;\n this.config = config;\n }\n\n isActive = (): boolean => this.session !== null;\n\n /** Fire-and-forget token pre-mint (mic hover) so the click starts instantly. */\n prewarm = () => {\n void this.mintToken().catch((e) => {\n this.mintCache.clear();\n log.error('dictation token prewarm failed', {\n _e: e instanceof Error ? e.message : String(e),\n });\n });\n };\n\n start = (target: DictationTarget) => {\n if (this.session) this.teardown();\n\n this.target = target;\n this.language = DictationDripUtils.languageHint(\n this.config.language ?? navigator.language,\n );\n this.prefix = target.getValue();\n this.raw = '';\n this.processed = '';\n this.displayed = '';\n\n const session = new DictationSession({\n mintToken: this.mintToken,\n onLevel: (level) => {\n this.levelRef.current = level;\n },\n onState: (sessionState: DictationSessionState) => {\n if (session !== this.session) return;\n if (sessionState === 'connecting') {\n this.state.set({ status: 'connecting', error: null });\n }\n if (sessionState === 'listening') {\n this.state.set({ status: 'listening', error: null });\n }\n // The session can end itself (max-duration cap): mirror it, or the UI\n // keeps showing a live mic that is actually closed.\n if (sessionState === 'stopped') this.teardown();\n },\n onError: (code) => {\n if (session !== this.session) return;\n // The token may have been the stale part — next attempt mints fresh.\n this.mintCache.clear();\n this.teardown({ error: code, executeFinalCommand: false });\n },\n onDelta: (delta) => {\n if (session !== this.session || !this.target) return;\n if (!this.isConsistent()) {\n // The visitor edited the field mid-dictation — their edit wins.\n this.teardown();\n return;\n }\n this.raw += delta;\n const control = this.ingest();\n if (control === 'stop') {\n this.teardown();\n return;\n }\n if (control === 'send') {\n this.teardown({ send: true });\n return;\n }\n // A completed command phrase waiting for punctuation resolves after a\n // silent pause — the model may never emit the terminator once the\n // user stops talking.\n this.stopSilenceTimer();\n if (\n DictationCommandUtils.pendingTailIsCompletePhrase(\n this.raw,\n this.language,\n )\n ) {\n this.silenceTimer = setTimeout(() => {\n if (session !== this.session) return;\n this.raw = `${this.raw}.`;\n const silenceControl = this.ingest();\n if (silenceControl === 'stop') this.teardown();\n else if (silenceControl === 'send') this.teardown({ send: true });\n }, SILENCE_COMMAND_MS);\n }\n },\n });\n this.session = session;\n this.state.set({ status: 'connecting', error: null });\n\n this.dripTimer = setInterval(() => {\n if (!this.target) return;\n if (this.processed === this.displayed) return;\n if (!this.isConsistent()) {\n this.teardown();\n return;\n }\n this.applyDisplayed(\n DictationDripUtils.nextDripText({\n displayed: this.displayed,\n processed: this.processed,\n }),\n );\n }, DRIP_INTERVAL_MS);\n\n void session.start();\n };\n\n stop = () => {\n if (this.session) this.teardown();\n };\n\n private mintToken = async (): Promise<DictationMint> =>\n this.mintCache.resolve(() =>\n this.api.createDictationSession({ language: this.language }),\n );\n\n /** Applied text = prefix + dictated. A mismatch means the visitor edited. */\n private isConsistent(): boolean {\n if (!this.target) return false;\n return this.target.getValue() === this.prefix + this.displayed;\n }\n\n private applyDisplayed(text: string) {\n if (!this.target) return;\n this.target.setValue(this.prefix + text);\n this.displayed = text;\n }\n\n /** Process the transcript and apply the outcome. Shared by the delta path,\n * the silence timer, and (with `final`) teardown. Returns the control. */\n private ingest(options?: { final?: boolean }) {\n const result = DictationCommandUtils.process(this.raw, {\n language: this.language,\n final: options?.final,\n });\n this.processed = result.text;\n // Rewrites (scratch-that, retro-capitalization) apply instantly; plain\n // appends flow through the paced drip.\n if (!result.text.startsWith(this.displayed)) {\n this.applyDisplayed(result.text);\n }\n return result.control;\n }\n\n private stopSilenceTimer() {\n if (this.silenceTimer) clearTimeout(this.silenceTimer);\n this.silenceTimer = null;\n }\n\n private teardown(options?: {\n send?: boolean;\n error?: DictationErrorCode;\n /** Manual/normal stops execute a trailing spoken command (\"…send it\").\n * Error teardowns only release the words as text. */\n executeFinalCommand?: boolean;\n }) {\n const endingSession = this.session;\n const endingTarget = this.target;\n if (this.dripTimer) clearInterval(this.dripTimer);\n this.dripTimer = null;\n this.stopSilenceTimer();\n\n // End-of-stream semantics: stopping IS the pause, so the withheld tail\n // resolves — a completed command phrase fires (unless this is an error\n // teardown), and partial phrases land as literal words instead of\n // vanishing. Consistency-guarded like every other write.\n let send = options?.send ?? false;\n if (endingTarget && this.isConsistent()) {\n const control = this.ingest({ final: true });\n if (options?.executeFinalCommand !== false && control === 'send') {\n send = true;\n }\n if (this.processed !== this.displayed) {\n this.applyDisplayed(this.processed);\n }\n }\n\n this.session = null;\n this.target = null;\n endingSession?.stop();\n this.levelRef.current = 0;\n this.state.set({ status: 'idle', error: options?.error ?? null });\n if (send) endingTarget?.onSend?.();\n }\n}\n","import type { TranslationInterface } from '.';\n\nexport const ArabicLanguage: TranslationInterface = {\n write_a_message_placeholder: 'اكتب رسالة...',\n your_issue_has_been_resolved: 'تم حل مشكلتك!',\n new_conversation: 'محادثة جديدة',\n welcome_screen_title: 'مرحبًا بك في دردشة الدعم الخاصة بنا',\n welcome_screen_description:\n 'نحن هنا للمساعدة! ابدأ محادثة وسنرد عليك في أقرب وقت ممكن.',\n your_name_placeholder: 'اسمك',\n your_email_placeholder: 'عنوان بريدك الإلكتروني',\n start_chat_button: 'تحدث إلى الدعم',\n start_chat_button_loading: 'جاري الاتصال...',\n i_need_more_help: 'أحتاج المزيد من المساعدة',\n this_was_helpful: 'كان هذا مفيدًا',\n optional: 'اختياري',\n no_conversations_yet: 'لا يوجد محادثات',\n back_to_conversations: 'العودة إلى المحادثات',\n closed_conversations: 'المحادثات المغلقة',\n csat_title: 'كيف كانت محادثتك؟',\n csat_submitted_title: 'لقد قيّمت المحادثة بـ',\n csat_feedback_placeholder: 'أخبرنا المزيد... (اختياري)',\n follow_up_placeholder: 'تابع المحادثة…',\n companion_layout_label: 'التخطيط',\n companion_layout_floating: 'عائم',\n companion_layout_sidebar: 'الشريط الجانبي',\n companion_layout_fullscreen: 'ملء الشاشة',\n companion_close_chat: 'إغلاق {title}',\n companion_close: 'إغلاق',\n companion_switch_chat: 'تبديل المحادثة',\n companion_viewing: 'تعرض الآن',\n companion_working: 'قيد العمل',\n companion_open: 'مفتوحة',\n companion_closed: 'مغلقة',\n companion_draft: 'مسودة',\n companion_chats: 'الجلسات النشطة',\n companion_chat_number: 'محادثة {count}',\n companion_active_chats: '{count} جلسات نشطة',\n companion_other_sessions: 'الجلسات المفتوحة الأخرى: {count}',\n companion_working_chats: '{count} قيد العمل',\n companion_history: 'سجل المحادثات',\n companion_expand_chat: 'توسيع المحادثة',\n companion_sidebar_dock_label: 'الإرساء',\n companion_sidebar_side_label: 'الجانب',\n companion_sidebar_left: 'يسار',\n companion_sidebar_right: 'يمين',\n companion_resize_chat: 'تغيير حجم المحادثة',\n scroll_to_bottom: 'التمرير إلى الأسفل',\n thinking: 'جارٍ التفكير…',\n running: 'جارٍ التنفيذ…',\n steps: 'خطوات',\n step_arguments: 'الوسائط',\n step_result: 'النتيجة',\n attach_files:\n 'إرفاق صور أو مقاطع فيديو أو ملفات PDF أو جداول بيانات (الحد الأقصى 25 ميغابايت)',\n mark_page_active: 'انقر على أي شيء في الصفحة لتحديده — اضغط Esc للإلغاء',\n mark_page: 'حدّد شيئًا في الصفحة لطرح سؤال عنه',\n stop_response: 'إيقاف الرد',\n copy_reply: 'نسخ الرد',\n mentions_empty: 'لا توجد نتائج',\n copied: 'تم النسخ',\n send_message: 'إرسال الرسالة',\n upload_failed: 'فشل الرفع: {error}',\n remove_attachment: 'إزالة المرفق',\n json_no_items: 'لا توجد عناصر',\n json_no_data: 'لا توجد بيانات',\n json_no_chart_data: 'لا توجد بيانات لعرضها في الرسم البياني',\n json_unsupported: 'غير مدعوم: {type}',\n json_see_less: 'عرض أقل',\n json_phone_agent: 'وكيل هاتفي',\n json_phone_agent_test: 'اختبار عبر الويب',\n page_context_remove: 'إزالة سياق الصفحة',\n json_see_more: 'عرض {count} إضافية',\n queued_label: '{count} في الانتظار',\n remove_queued_message: 'إزالة الرسالة من قائمة الانتظار',\n send_queued_now: 'إرسال الرسائل في قائمة الانتظار الآن',\n turn_failed_message: 'حدث خطأ ما ولم يصل الرد.',\n turn_failed_retry: 'حاول مرة أخرى',\n page_mark_hint: 'انقر على أي شيء لتحديده',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'مربع',\n page_mark_shape_circle: 'دائرة',\n page_mark_shape_arrow: 'سهم',\n page_mark_shape_bracket: 'قوس',\n page_mark_shape_underline: 'تسطير',\n page_mark_shape_highlight: 'تمييز',\n page_mark_shape_strike_through: 'شطب',\n page_mark_shape_crossed_off: 'علامة تقاطع',\n page_mark_shape_aria: 'شكل التحديد: {shape}',\n page_mark_note_placeholder: 'أضف ملاحظة… (Enter للإرفاق)',\n page_mark_attach: 'إرفاق التحديد',\n page_mark_remove: 'إزالة {label}',\n page_mark_region: 'منطقة محددة',\n page_mark_default_message: 'ما هذا؟',\n file_rejected: 'نوع الملف غير مدعوم أو أن الملف كبير جدًا.',\n dictate: 'إملاء صوتي',\n stop_dictation: 'إيقاف الإملاء',\n dictation_mic_blocked: 'اسمح بالوصول إلى الميكروفون للإملاء',\n dictation_unavailable: 'الإملاء غير متاح حاليًا',\n questions_back: 'رجوع',\n questions_next: 'التالي',\n questions_send: 'إرسال',\n questions_type_answer: 'سأكتبها بنفسي',\n questions_answer_placeholder: 'اكتب إجابتك…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const BengaliLanguage: TranslationInterface = {\n write_a_message_placeholder: 'একটি বার্তা লিখুন...',\n your_issue_has_been_resolved: 'আপনার সমস্যা সমাধান হয়েছে!',\n new_conversation: 'নতুন কথোপকথন',\n welcome_screen_title: 'আমাদের সাপোর্ট চ্যাটে স্বাগতম',\n welcome_screen_description:\n 'আমরা সাহায্য করতে এখানে আছি! একটি কথোপকথন শুরু করুন এবং আমরা যত তাড়াতাড়ি সম্ভব আপনার কাছে ফিরে আসব।',\n your_name_placeholder: 'আপনার নাম',\n your_email_placeholder: 'আপনার ইমেইল ঠিকানা',\n start_chat_button: 'সাপোর্টের সাথে কথা বলুন',\n start_chat_button_loading: 'সংযোগ হচ্ছে...',\n i_need_more_help: 'আমার আরও সাহায্য দরকার',\n this_was_helpful: 'এটি সহায়ক ছিল',\n optional: 'ঐচ্ছিক',\n no_conversations_yet: 'এখনো কোনো কথোপকথন নেই',\n back_to_conversations: 'কথোপকথনে ফিরে যান',\n closed_conversations: 'বন্ধ কথোপকথন',\n csat_title: 'আপনার কথোপকথন কেমন ছিল?',\n csat_submitted_title: 'আপনি কথোপকথনটি মূল্যায়ন করেছেন',\n csat_feedback_placeholder: 'আমাদের আরও বলুন... (ঐচ্ছিক)',\n follow_up_placeholder: 'আরও জিজ্ঞাসা করুন…',\n companion_layout_label: 'লেআউট',\n companion_layout_floating: 'ভাসমান',\n companion_layout_sidebar: 'সাইডবার',\n companion_layout_fullscreen: 'পূর্ণ পর্দা',\n companion_close: 'বন্ধ করুন',\n companion_history: 'কথোপকথনের ইতিহাস',\n companion_expand_chat: 'চ্যাট প্রসারিত করুন',\n companion_sidebar_dock_label: 'ডক',\n companion_sidebar_side_label: 'পাশ',\n companion_sidebar_left: 'বাম',\n companion_sidebar_right: 'ডান',\n companion_resize_chat: 'চ্যাটের আকার পরিবর্তন করুন',\n scroll_to_bottom: 'নিচে স্ক্রল করুন',\n thinking: 'ভাবছি…',\n running: 'চলছে…',\n steps: 'ধাপ',\n step_arguments: 'আর্গুমেন্ট',\n step_result: 'ফলাফল',\n attach_files:\n 'ছবি, ভিডিও, PDF বা স্প্রেডশিট সংযুক্ত করুন (সর্বোচ্চ আকার 25 MB)',\n mark_page_active:\n 'চিহ্নিত করতে পৃষ্ঠার যেকোনো কিছুতে ক্লিক করুন — বাতিল করতে Esc চাপুন',\n mark_page: 'পৃষ্ঠার কোনো কিছু সম্পর্কে জিজ্ঞাসা করতে সেটি চিহ্নিত করুন',\n stop_response: 'উত্তর থামান',\n copy_reply: 'উত্তর কপি করুন',\n mentions_empty: 'কোনো মিল নেই',\n copied: 'কপি করা হয়েছে',\n send_message: 'বার্তা পাঠান',\n upload_failed: 'আপলোড ব্যর্থ হয়েছে: {error}',\n remove_attachment: 'সংযুক্তি সরান',\n json_no_items: 'কোনো আইটেম নেই',\n json_no_data: 'কোনো ডেটা নেই',\n json_no_chart_data: 'চার্টের জন্য কোনো ডেটা নেই',\n json_unsupported: 'সমর্থিত নয়: {type}',\n json_see_less: 'কম দেখুন',\n json_phone_agent: 'ফোন এজেন্ট',\n json_phone_agent_test: 'ওয়েবে পরীক্ষা করুন',\n page_context_remove: 'পেজ প্রসঙ্গ সরান',\n json_see_more: 'আরও {count}টি দেখুন',\n queued_label: '{count} সারিতে আছে',\n remove_queued_message: 'সারি থেকে বার্তা সরান',\n send_queued_now: 'সারির বার্তাগুলি এখনই পাঠান',\n turn_failed_message: 'কিছু ভুল হয়েছে এবং উত্তরটি আসেনি।',\n turn_failed_retry: 'আবার চেষ্টা করুন',\n page_mark_hint: 'চিহ্নিত করতে যেকোনো কিছুতে ক্লিক করুন',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'বাক্স',\n page_mark_shape_circle: 'বৃত্ত',\n page_mark_shape_arrow: 'তীর',\n page_mark_shape_bracket: 'বন্ধনী',\n page_mark_shape_underline: 'নিম্নরেখা',\n page_mark_shape_highlight: 'হাইলাইট',\n page_mark_shape_strike_through: 'মাঝে দাগ',\n page_mark_shape_crossed_off: 'ক্রস করে কাটা',\n page_mark_shape_aria: 'চিহ্নের আকৃতি: {shape}',\n page_mark_note_placeholder: 'একটি নোট যোগ করুন… (সংযুক্ত করতে Enter চাপুন)',\n page_mark_attach: 'চিহ্ন সংযুক্ত করুন',\n page_mark_remove: '{label} সরান',\n page_mark_region: 'চিহ্নিত অঞ্চল',\n page_mark_default_message: 'এটি কী?',\n file_rejected: 'ফাইলের ধরন সমর্থিত নয় অথবা ফাইলটি খুব বড়।',\n dictate: 'ডিক্টেট করুন',\n stop_dictation: 'ডিক্টেশন বন্ধ করুন',\n dictation_mic_blocked: 'ডিক্টেট করতে মাইক্রোফোন অ্যাক্সেসের অনুমতি দিন',\n dictation_unavailable: 'ডিক্টেশন এখন উপলব্ধ নয়',\n questions_back: 'পেছনে',\n questions_next: 'পরবর্তী',\n questions_send: 'পাঠান',\n questions_type_answer: 'আমি লিখে দিচ্ছি',\n questions_answer_placeholder: 'আপনার উত্তর লিখুন…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const BulgarianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Напишете съобщение...',\n your_issue_has_been_resolved: 'Вашият проблем е разрешен!',\n new_conversation: 'Нов разговор',\n welcome_screen_title: 'Добре дошли в нашия чат за поддръжка',\n welcome_screen_description:\n 'Тук сме, за да помогнем! Започнете разговор и ще ви отговорим възможно най-скоро.',\n your_name_placeholder: 'Вашето име',\n your_email_placeholder: 'Вашият имейл адрес',\n start_chat_button: 'Свържете се с поддръжка',\n start_chat_button_loading: 'Свързване...',\n i_need_more_help: 'Имам нужда от повече помощ',\n this_was_helpful: 'Това беше полезно',\n optional: 'По избор',\n no_conversations_yet: 'Все още няма разговори',\n back_to_conversations: 'Назад към разговорите',\n closed_conversations: 'Затворени разговори',\n csat_title: 'Как мина разговорът ви?',\n csat_submitted_title: 'Оценихте разговора като',\n csat_feedback_placeholder: 'Кажете ни повече... (по желание)',\n follow_up_placeholder: 'Продължете…',\n companion_layout_label: 'Оформление',\n companion_layout_floating: 'Плаващ',\n companion_layout_sidebar: 'Странична лента',\n companion_layout_fullscreen: 'На цял екран',\n companion_close: 'Затвори',\n companion_history: 'История на разговорите',\n companion_expand_chat: 'Разгъване на чата',\n companion_sidebar_dock_label: 'Закачване',\n companion_sidebar_side_label: 'Страна',\n companion_sidebar_left: 'Ляво',\n companion_sidebar_right: 'Дясно',\n companion_resize_chat: 'Преоразмеряване на чата',\n scroll_to_bottom: 'Превъртане до края',\n thinking: 'Мисля…',\n running: 'Изпълнява се…',\n steps: 'стъпки',\n step_arguments: 'Аргументи',\n step_result: 'Резултат',\n attach_files:\n 'Прикачете изображения, видеоклипове, PDF файлове или електронни таблици (максимален размер 25 MB)',\n mark_page_active:\n 'Щракнете върху нещо на страницата, за да го маркирате — Esc за отказ',\n mark_page: 'Маркирайте нещо на страницата, за да попитате за него',\n stop_response: 'Спиране на отговора',\n copy_reply: 'Копирай отговора',\n mentions_empty: 'Няма съвпадения',\n copied: 'Копирано',\n send_message: 'Изпращане на съобщение',\n upload_failed: 'Неуспешно качване: {error}',\n remove_attachment: 'Премахване на прикачения файл',\n json_no_items: 'Няма елементи',\n json_no_data: 'Няма данни',\n json_no_chart_data: 'Няма данни за диаграма',\n json_unsupported: 'Не се поддържа: {type}',\n json_see_less: 'Покажи по-малко',\n json_phone_agent: 'Телефонен агент',\n json_phone_agent_test: 'Тест през уеб',\n page_context_remove: 'Премахни контекста на страницата',\n json_see_more: 'Покажи още {count}',\n queued_label: '{count} На опашката',\n remove_queued_message: 'Премахване на съобщението от опашката',\n send_queued_now: 'Изпрати съобщенията от опашката сега',\n turn_failed_message: 'Нещо се обърка и отговорът не пристигна.',\n turn_failed_retry: 'Опитайте отново',\n page_mark_hint: 'Щракнете върху нещо, за да го маркирате',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Правоъгълник',\n page_mark_shape_circle: 'Кръг',\n page_mark_shape_arrow: 'Стрелка',\n page_mark_shape_bracket: 'Скоба',\n page_mark_shape_underline: 'Подчертаване',\n page_mark_shape_highlight: 'Маркиране',\n page_mark_shape_strike_through: 'Зачертаване',\n page_mark_shape_crossed_off: 'Кръстосано зачертаване',\n page_mark_shape_aria: 'Форма на маркировката: {shape}',\n page_mark_note_placeholder: 'Добавете бележка… (Enter за прикачване)',\n page_mark_attach: 'Прикачване на маркировката',\n page_mark_remove: 'Премахване на {label}',\n page_mark_region: 'Маркирана област',\n page_mark_default_message: 'Какво е това?',\n file_rejected: 'Типът на файла не се поддържа или файлът е твърде голям.',\n dictate: 'Диктувай',\n stop_dictation: 'Спри диктуването',\n dictation_mic_blocked: 'Разрешете достъп до микрофона, за да диктувате',\n dictation_unavailable: 'Диктуването не е налично в момента',\n questions_back: 'Назад',\n questions_next: 'Напред',\n questions_send: 'Изпрати',\n questions_type_answer: 'Ще напиша сам',\n questions_answer_placeholder: 'Напишете отговора си…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const CzechLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napište zprávu...',\n your_issue_has_been_resolved: 'Váš problém byl vyřešen!',\n new_conversation: 'Nová konverzace',\n welcome_screen_title: 'Vítejte v našem chatu podpory',\n welcome_screen_description:\n 'Jsme tu, abychom vám pomohli! Zahajte konverzaci a ozveme se vám co nejdříve.',\n your_name_placeholder: 'Vaše jméno',\n your_email_placeholder: 'Vaše e-mailová adresa',\n start_chat_button: 'Kontaktovat podporu',\n start_chat_button_loading: 'Připojování...',\n i_need_more_help: 'Potřebuji další pomoc',\n this_was_helpful: 'Toto bylo užitečné',\n optional: 'Volitelné',\n no_conversations_yet: 'Zatím žádné konverzace',\n back_to_conversations: 'Zpět na konverzace',\n closed_conversations: 'Uzavřené konverzace',\n csat_title: 'Jaká byla vaše konverzace?',\n csat_submitted_title: 'Konverzaci jste ohodnotili jako',\n csat_feedback_placeholder: 'Řekněte nám více... (nepovinné)',\n follow_up_placeholder: 'Pokračovat…',\n companion_layout_label: 'Rozvržení',\n companion_layout_floating: 'Plovoucí',\n companion_layout_sidebar: 'Postranní panel',\n companion_layout_fullscreen: 'Celá obrazovka',\n companion_close: 'Zavřít',\n companion_history: 'Historie konverzací',\n companion_expand_chat: 'Rozbalit chat',\n companion_sidebar_dock_label: 'Ukotvení',\n companion_sidebar_side_label: 'Strana',\n companion_sidebar_left: 'Vlevo',\n companion_sidebar_right: 'Vpravo',\n companion_resize_chat: 'Změnit velikost chatu',\n scroll_to_bottom: 'Posunout dolů',\n thinking: 'Přemýšlím…',\n running: 'Probíhá…',\n steps: 'kroky',\n step_arguments: 'Argumenty',\n step_result: 'Výsledek',\n attach_files:\n 'Připojit obrázky, videa, PDF nebo tabulky (maximální velikost 25 MB)',\n mark_page_active:\n 'Kliknutím na cokoli na stránce to označíte — klávesou Esc akci zrušíte',\n mark_page: 'Označte něco na stránce a zeptejte se na to',\n stop_response: 'Zastavit odpověď',\n copy_reply: 'Kopírovat odpověď',\n mentions_empty: 'Žádné shody',\n copied: 'Zkopírováno',\n send_message: 'Odeslat zprávu',\n upload_failed: 'Nahrání se nezdařilo: {error}',\n remove_attachment: 'Odebrat přílohu',\n json_no_items: 'Žádné položky',\n json_no_data: 'Žádná data',\n json_no_chart_data: 'Žádná data pro graf',\n json_unsupported: 'Nepodporováno: {type}',\n json_see_less: 'Zobrazit méně',\n json_phone_agent: 'Telefonní agent',\n json_phone_agent_test: 'Vyzkoušet na webu',\n page_context_remove: 'Odebrat kontext stránky',\n json_see_more: 'Zobrazit dalších {count}',\n queued_label: '{count} Ve frontě',\n remove_queued_message: 'Odebrat zprávu z fronty',\n send_queued_now: 'Odeslat zprávy ve frontě nyní',\n turn_failed_message: 'Něco se pokazilo a odpověď nedorazila.',\n turn_failed_retry: 'Zkusit znovu',\n page_mark_hint: 'Kliknutím na cokoli to označíte',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rámeček',\n page_mark_shape_circle: 'Kruh',\n page_mark_shape_arrow: 'Šipka',\n page_mark_shape_bracket: 'Závorka',\n page_mark_shape_underline: 'Podtržení',\n page_mark_shape_highlight: 'Zvýraznění',\n page_mark_shape_strike_through: 'Přeškrtnutí',\n page_mark_shape_crossed_off: 'Křížové přeškrtnutí',\n page_mark_shape_aria: 'Tvar označení: {shape}',\n page_mark_note_placeholder: 'Přidat poznámku… (Enter pro připojení)',\n page_mark_attach: 'Připojit označení',\n page_mark_remove: 'Odebrat {label}',\n page_mark_region: 'Označená oblast',\n page_mark_default_message: 'Co to je?',\n file_rejected: 'Typ souboru není podporován nebo je soubor příliš velký.',\n dictate: 'Diktovat',\n stop_dictation: 'Zastavit diktování',\n dictation_mic_blocked: 'Pro diktování povolte přístup k mikrofonu',\n dictation_unavailable: 'Diktování momentálně není k dispozici',\n questions_back: 'Zpět',\n questions_next: 'Další',\n questions_send: 'Odeslat',\n questions_type_answer: 'Napíšu to sám',\n questions_answer_placeholder: 'Napište svou odpověď…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const DanishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv en besked...',\n your_issue_has_been_resolved: 'Dit problem er løst!',\n new_conversation: 'Ny samtale',\n welcome_screen_title: 'Velkommen til vores support chat',\n welcome_screen_description:\n 'Vi er her for at hjælpe! Start en samtale, og vi vender tilbage til dig så hurtigt som muligt.',\n your_name_placeholder: 'Dit navn',\n your_email_placeholder: 'Din e-mailadresse',\n start_chat_button: 'Tal med support',\n start_chat_button_loading: 'Forbinder...',\n i_need_more_help: 'Jeg har brug for mere hjælp',\n this_was_helpful: 'Dette var nyttigt',\n optional: 'Valgfrit',\n no_conversations_yet: 'Ingen samtaler endnu',\n back_to_conversations: 'Tilbage til samtaler',\n closed_conversations: 'Lukkede samtaler',\n csat_title: 'Hvordan var din samtale?',\n csat_submitted_title: 'Du vurderede samtalen som',\n csat_feedback_placeholder: 'Fortæl os mere... (valgfrit)',\n follow_up_placeholder: 'Følg op…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Flydende',\n companion_layout_sidebar: 'Sidepanel',\n companion_layout_fullscreen: 'Fuld skærm',\n companion_close: 'Luk',\n companion_history: 'Samtalehistorik',\n companion_expand_chat: 'Udvid chat',\n companion_sidebar_dock_label: 'Dok',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Venstre',\n companion_sidebar_right: 'Højre',\n companion_resize_chat: 'Tilpas chatstørrelse',\n scroll_to_bottom: 'Rul til bunden',\n thinking: 'Tænker…',\n running: 'Kører…',\n steps: 'trin',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Vedhæft billeder, videoer, PDF-filer eller regneark (maksimal størrelse 25 MB)',\n mark_page_active:\n 'Klik på noget på siden for at markere det — Esc annullerer',\n mark_page: 'Markér noget på siden for at spørge om det',\n stop_response: 'Stop svar',\n copy_reply: 'Kopiér svar',\n mentions_empty: 'Ingen resultater',\n copied: 'Kopieret',\n send_message: 'Send besked',\n upload_failed: 'Upload mislykkedes: {error}',\n remove_attachment: 'Fjern vedhæftning',\n json_no_items: 'Ingen elementer',\n json_no_data: 'Ingen data',\n json_no_chart_data: 'Ingen data til diagram',\n json_unsupported: 'Ikke understøttet: {type}',\n json_see_less: 'Vis mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Test via web',\n page_context_remove: 'Fjern sidekontekst',\n json_see_more: 'Vis {count} mere',\n queued_label: '{count} I kø',\n remove_queued_message: 'Fjern besked fra køen',\n send_queued_now: 'Send beskeder i køen nu',\n turn_failed_message: 'Noget gik galt, og svaret kom ikke frem.',\n turn_failed_retry: 'Prøv igen',\n page_mark_hint: 'Klik på noget for at markere det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Firkant',\n page_mark_shape_circle: 'Cirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Kantparentes',\n page_mark_shape_underline: 'Understregning',\n page_mark_shape_highlight: 'Fremhævning',\n page_mark_shape_strike_through: 'Gennemstregning',\n page_mark_shape_crossed_off: 'Kryds ud',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Tilføj en note… (Enter for at vedhæfte)',\n page_mark_attach: 'Vedhæft markering',\n page_mark_remove: 'Fjern {label}',\n page_mark_region: 'Markeret område',\n page_mark_default_message: 'Hvad er det her?',\n file_rejected: 'Filtypen understøttes ikke, eller filen er for stor.',\n dictate: 'Dikter',\n stop_dictation: 'Stop diktering',\n dictation_mic_blocked: 'Tillad mikrofonadgang for at diktere',\n dictation_unavailable: 'Diktering er ikke tilgængelig lige nu',\n questions_back: 'Tilbage',\n questions_next: 'Næste',\n questions_send: 'Send',\n questions_type_answer: 'Jeg skriver det selv',\n questions_answer_placeholder: 'Skriv dit svar…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const GreekLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Γράψτε ένα μήνυμα...',\n your_issue_has_been_resolved: 'Το πρόβλημά σας επιλύθηκε!',\n new_conversation: 'Νέα συνομιλία',\n welcome_screen_title: 'Καλώς ήρθατε στη συνομιλία υποστήριξης',\n welcome_screen_description:\n 'Είμαστε εδώ για να βοηθήσουμε! Ξεκινήστε μια συνομιλία και θα σας απαντήσουμε το συντομότερο δυνατό.',\n your_name_placeholder: 'Το όνομά σας',\n your_email_placeholder: 'Η διεύθυνση email σας',\n start_chat_button: 'Επικοινωνία με την υποστήριξη',\n start_chat_button_loading: 'Σύνδεση...',\n i_need_more_help: 'Χρειάζομαι περισσότερη βοήθεια',\n this_was_helpful: 'Αυτό ήταν χρήσιμο',\n optional: 'Προαιρετικό',\n no_conversations_yet: 'Δεν υπάρχουν συνομιλίες ακόμα',\n back_to_conversations: 'Πίσω στις συνομιλίες',\n closed_conversations: 'Κλειστές συνομιλίες',\n csat_title: 'Πώς ήταν η συνομιλία σας;',\n csat_submitted_title: 'Βαθμολογήσατε τη συνομιλία ως',\n csat_feedback_placeholder: 'Πείτε μας περισσότερα... (προαιρετικό)',\n follow_up_placeholder: 'Συνέχεια…',\n companion_layout_label: 'Διάταξη',\n companion_layout_floating: 'Αιωρούμενο',\n companion_layout_sidebar: 'Πλευρική στήλη',\n companion_layout_fullscreen: 'Πλήρης οθόνη',\n companion_close: 'Κλείσιμο',\n companion_history: 'Ιστορικό συνομιλιών',\n companion_expand_chat: 'Ανάπτυξη συνομιλίας',\n companion_sidebar_dock_label: 'Αγκύρωση',\n companion_sidebar_side_label: 'Πλευρά',\n companion_sidebar_left: 'Αριστερά',\n companion_sidebar_right: 'Δεξιά',\n companion_resize_chat: 'Αλλαγή μεγέθους συνομιλίας',\n scroll_to_bottom: 'Κύλιση στο τέλος',\n thinking: 'Σκέψη…',\n running: 'Εκτελείται…',\n steps: 'βήματα',\n step_arguments: 'Ορίσματα',\n step_result: 'Αποτέλεσμα',\n attach_files:\n 'Επισύναψη εικόνων, βίντεο, PDF ή υπολογιστικών φύλλων (μέγιστο μέγεθος 25 MB)',\n mark_page_active:\n 'Κάντε κλικ σε οτιδήποτε στη σελίδα για να το επισημάνετε — Esc για ακύρωση',\n mark_page: 'Επισημάνετε κάτι στη σελίδα για να ρωτήσετε σχετικά με αυτό',\n stop_response: 'Διακοπή απάντησης',\n copy_reply: 'Αντιγραφή απάντησης',\n mentions_empty: 'Δεν βρέθηκαν αποτελέσματα',\n copied: 'Αντιγράφηκε',\n send_message: 'Αποστολή μηνύματος',\n upload_failed: 'Η μεταφόρτωση απέτυχε: {error}',\n remove_attachment: 'Αφαίρεση συνημμένου',\n json_no_items: 'Δεν υπάρχουν στοιχεία',\n json_no_data: 'Δεν υπάρχουν δεδομένα',\n json_no_chart_data: 'Δεν υπάρχουν δεδομένα για γράφημα',\n json_unsupported: 'Δεν υποστηρίζεται: {type}',\n json_see_less: 'Εμφάνιση λιγότερων',\n json_phone_agent: 'Τηλεφωνικός πράκτορας',\n json_phone_agent_test: 'Δοκιμή μέσω web',\n page_context_remove: 'Αφαίρεση περιβάλλοντος σελίδας',\n json_see_more: 'Εμφάνιση {count} ακόμη',\n queued_label: '{count} Σε αναμονή',\n remove_queued_message: 'Αφαίρεση μηνύματος από την ουρά',\n send_queued_now: 'Αποστολή μηνυμάτων ουράς τώρα',\n turn_failed_message: 'Κάτι πήγε στραβά και η απάντηση δεν έφτασε.',\n turn_failed_retry: 'Δοκιμάστε ξανά',\n page_mark_hint: 'Κάντε κλικ σε κάτι για να το επισημάνετε',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Πλαίσιο',\n page_mark_shape_circle: 'Κύκλος',\n page_mark_shape_arrow: 'Βέλος',\n page_mark_shape_bracket: 'Αγκύλη',\n page_mark_shape_underline: 'Υπογράμμιση',\n page_mark_shape_highlight: 'Επισήμανση',\n page_mark_shape_strike_through: 'Διακριτή διαγραφή',\n page_mark_shape_crossed_off: 'Χιαστή διαγραφή',\n page_mark_shape_aria: 'Σχήμα επισήμανσης: {shape}',\n page_mark_note_placeholder: 'Προσθέστε σημείωση… (Enter για επισύναψη)',\n page_mark_attach: 'Επισύναψη επισήμανσης',\n page_mark_remove: 'Αφαίρεση {label}',\n page_mark_region: 'Επισημασμένη περιοχή',\n page_mark_default_message: 'Τι είναι αυτό;',\n file_rejected:\n 'Ο τύπος αρχείου δεν υποστηρίζεται ή το αρχείο είναι πολύ μεγάλο.',\n dictate: 'Υπαγόρευση',\n stop_dictation: 'Διακοπή υπαγόρευσης',\n dictation_mic_blocked: 'Επιτρέψτε την πρόσβαση στο μικρόφωνο για υπαγόρευση',\n dictation_unavailable: 'Η υπαγόρευση δεν είναι διαθέσιμη αυτή τη στιγμή',\n questions_back: 'Πίσω',\n questions_next: 'Επόμενο',\n questions_send: 'Αποστολή',\n questions_type_answer: 'Θα το γράψω',\n questions_answer_placeholder: 'Γράψτε την απάντησή σας…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const GermanLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Nachricht schreiben...',\n your_issue_has_been_resolved: 'Ihr Problem wurde gelöst!',\n new_conversation: 'Neue Konversation',\n welcome_screen_title: 'Willkommen in unserem Support-Chat',\n welcome_screen_description:\n 'Wir sind hier, um zu helfen! Beginnen Sie ein Gesprách und wir werden so schnell wie mogelijk antworten.',\n your_name_placeholder: 'Ihr Name',\n your_email_placeholder: 'Ihre E-Mail-Adresse',\n start_chat_button: 'Mit dem Support sprechen',\n start_chat_button_loading: 'Verbindung wird hergestellt...',\n i_need_more_help: 'Ich brauche weitere Hilfe',\n this_was_helpful: 'Dies war hilfreich',\n optional: 'Optional',\n no_conversations_yet: 'noch keine Gespräche',\n back_to_conversations: 'Zurück zur Konversationen',\n closed_conversations: 'Geschlossene Konversationen',\n csat_title: 'Wie war Ihr Gespräch?',\n csat_submitted_title: 'Sie haben das Gespräch bewertet als',\n csat_feedback_placeholder: 'Erzählen Sie uns mehr... (optional)',\n follow_up_placeholder: 'Nachfragen…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Schwebend',\n companion_layout_sidebar: 'Seitenleiste',\n companion_layout_fullscreen: 'Vollbild',\n companion_close: 'Schließen',\n companion_history: 'Gesprächsverlauf',\n companion_expand_chat: 'Chat erweitern',\n companion_sidebar_dock_label: 'Andocken',\n companion_sidebar_side_label: 'Seite',\n companion_sidebar_left: 'Links',\n companion_sidebar_right: 'Rechts',\n companion_resize_chat: 'Chatgröße ändern',\n scroll_to_bottom: 'Nach unten scrollen',\n thinking: 'Denke nach…',\n running: 'Wird ausgeführt…',\n steps: 'Schritte',\n step_arguments: 'Argumente',\n step_result: 'Ergebnis',\n attach_files:\n 'Bilder, Videos, PDFs oder Tabellen anhängen (maximale Größe 25 MB)',\n mark_page_active:\n 'Klicken Sie auf etwas auf der Seite, um es zu markieren — Esc zum Abbrechen',\n mark_page: 'Markieren Sie etwas auf der Seite, um danach zu fragen',\n stop_response: 'Antwort stoppen',\n copy_reply: 'Antwort kopieren',\n mentions_empty: 'Keine Treffer',\n copied: 'Kopiert',\n send_message: 'Nachricht senden',\n upload_failed: 'Upload fehlgeschlagen: {error}',\n remove_attachment: 'Anhang entfernen',\n json_no_items: 'Keine Elemente',\n json_no_data: 'Keine Daten',\n json_no_chart_data: 'Keine Daten für das Diagramm',\n json_unsupported: 'Nicht unterstützt: {type}',\n json_see_less: 'Weniger anzeigen',\n json_phone_agent: 'Telefon-Agent',\n json_phone_agent_test: 'Im Web testen',\n page_context_remove: 'Seitenkontext entfernen',\n json_see_more: '{count} weitere anzeigen',\n queued_label: '{count} In Warteschlange',\n remove_queued_message: 'Nachricht aus der Warteschlange entfernen',\n send_queued_now: 'Wartende Nachrichten jetzt senden',\n turn_failed_message:\n 'Etwas ist schiefgelaufen und die Antwort ist nicht angekommen.',\n turn_failed_retry: 'Erneut versuchen',\n page_mark_hint: 'Klicken Sie auf etwas, um es zu markieren',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rahmen',\n page_mark_shape_circle: 'Kreis',\n page_mark_shape_arrow: 'Pfeil',\n page_mark_shape_bracket: 'Klammer',\n page_mark_shape_underline: 'Unterstreichen',\n page_mark_shape_highlight: 'Hervorheben',\n page_mark_shape_strike_through: 'Durchstreichen',\n page_mark_shape_crossed_off: 'Auskreuzen',\n page_mark_shape_aria: 'Markierungsform: {shape}',\n page_mark_note_placeholder: 'Notiz hinzufügen… (Enter zum Anhängen)',\n page_mark_attach: 'Markierung anhängen',\n page_mark_remove: '{label} entfernen',\n page_mark_region: 'Markierter Bereich',\n page_mark_default_message: 'Was ist das?',\n file_rejected:\n 'Der Dateityp wird nicht unterstützt oder die Datei ist zu groß.',\n dictate: 'Diktieren',\n stop_dictation: 'Diktat beenden',\n dictation_mic_blocked: 'Mikrofonzugriff erlauben, um zu diktieren',\n dictation_unavailable: 'Diktieren ist derzeit nicht verfügbar',\n questions_back: 'Zurück',\n questions_next: 'Weiter',\n questions_send: 'Senden',\n questions_type_answer: 'Ich schreibe es selbst',\n questions_answer_placeholder: 'Antwort eingeben…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const EnglishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Write a message...',\n your_issue_has_been_resolved: 'Your issue has been resolved!',\n new_conversation: 'New conversation',\n welcome_screen_title: 'Welcome to our support chat',\n welcome_screen_description:\n \"We're here to help! Start a conversation and we'll get back to you as soon as possible.\",\n your_name_placeholder: 'Your name',\n your_email_placeholder: 'Your email address',\n start_chat_button: 'Talk to support',\n start_chat_button_loading: 'Connecting...',\n i_need_more_help: 'I need more help',\n this_was_helpful: 'This was helpful',\n optional: 'Optional',\n no_conversations_yet: 'No conversations yet',\n back_to_conversations: 'Back to conversations',\n closed_conversations: 'Closed conversations',\n csat_title: 'How was your conversation?',\n csat_submitted_title: 'You rated the conversation as',\n csat_feedback_placeholder: 'Tell us more... (optional)',\n follow_up_placeholder: 'Follow up…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Floating',\n companion_layout_sidebar: 'Sidebar',\n companion_layout_fullscreen: 'Fullscreen',\n companion_close_chat: 'Close {title}',\n companion_close: 'Close',\n companion_switch_chat: 'Switch chat',\n companion_viewing: 'Viewing',\n companion_working: 'Working',\n companion_open: 'Open',\n companion_closed: 'Closed',\n companion_draft: 'Draft',\n companion_chats: 'Active sessions',\n companion_chat_number: 'Chat {count}',\n companion_active_chats: '{count} active sessions',\n companion_other_sessions: 'Other open sessions: {count}',\n companion_working_chats: '{count} working',\n companion_history: 'Conversation history',\n companion_expand_chat: 'Expand chat',\n companion_sidebar_dock_label: 'Dock',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Left',\n companion_sidebar_right: 'Right',\n companion_resize_chat: 'Resize chat',\n scroll_to_bottom: 'Scroll to bottom',\n thinking: 'Thinking…',\n running: 'Running…',\n steps: 'steps',\n step_arguments: 'Arguments',\n step_result: 'Result',\n attach_files:\n 'Attach images, videos, PDFs, or spreadsheets (maximum size 25 MB)',\n mark_page_active: 'Click anything on the page to mark it — Esc to cancel',\n mark_page: 'Mark something on the page to ask about it',\n stop_response: 'Stop response',\n copy_reply: 'Copy reply',\n mentions_empty: 'No matches',\n copied: 'Copied',\n send_message: 'Send message',\n upload_failed: 'Failed to upload: {error}',\n remove_attachment: 'Remove attachment',\n json_no_items: 'No items',\n json_no_data: 'No data',\n json_no_chart_data: 'No data to chart',\n json_unsupported: 'Unsupported: {type}',\n json_see_less: 'See less',\n json_phone_agent: 'Phone agent',\n json_phone_agent_test: 'Test via web',\n page_context_remove: 'Remove page context',\n json_see_more: 'See {count} more',\n queued_label: '{count} Queued',\n remove_queued_message: 'Remove queued message',\n send_queued_now: 'Send queued messages now',\n turn_failed_message: 'Something went wrong and the reply didn’t arrive.',\n turn_failed_retry: 'Try again',\n page_mark_hint: 'Click anything to mark it',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Box',\n page_mark_shape_circle: 'Circle',\n page_mark_shape_arrow: 'Arrow',\n page_mark_shape_bracket: 'Bracket',\n page_mark_shape_underline: 'Underline',\n page_mark_shape_highlight: 'Highlight',\n page_mark_shape_strike_through: 'Strike through',\n page_mark_shape_crossed_off: 'Cross out',\n page_mark_shape_aria: 'Mark shape: {shape}',\n page_mark_note_placeholder: 'Add a note… (Enter to attach)',\n page_mark_attach: 'Attach mark',\n page_mark_remove: 'Remove {label}',\n page_mark_region: 'Marked region',\n page_mark_default_message: 'What is this?',\n file_rejected: 'The file type is unsupported or the file is too large.',\n dictate: 'Dictate',\n stop_dictation: 'Stop dictating',\n dictation_mic_blocked: 'Allow microphone access to dictate',\n dictation_unavailable: 'Dictation is unavailable right now',\n questions_back: 'Back',\n questions_next: 'Next',\n questions_send: 'Send',\n questions_type_answer: \"I'll type it\",\n questions_answer_placeholder: 'Type your answer…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const SpanishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Escribe un mensaje...',\n your_issue_has_been_resolved: '¡Tu problema fue resuelto!',\n new_conversation: 'Nueva conversación',\n welcome_screen_title: 'Bienvenido a nuestro chat de soporte',\n welcome_screen_description:\n '¡Estamos aquí para ayudarte! Inicia una conversación y responderemos lo antes posible.',\n your_name_placeholder: 'Tu nombre',\n your_email_placeholder: 'Tu correo electrónico',\n start_chat_button: 'Hablar con soporte',\n start_chat_button_loading: 'Conectando...',\n i_need_more_help: 'Necesito más ayuda',\n this_was_helpful: 'Esto fue útil',\n optional: 'Opcional',\n no_conversations_yet: 'Sin conversaciones aún',\n back_to_conversations: 'Volver a conversaciones',\n closed_conversations: 'Conversaciones cerradas',\n csat_title: '¿Qué tal fue tu conversación?',\n csat_submitted_title: 'Valoraste la conversación como',\n csat_feedback_placeholder: 'Cuéntanos más... (opcional)',\n follow_up_placeholder: 'Continuar…',\n companion_layout_label: 'Diseño',\n companion_layout_floating: 'Flotante',\n companion_layout_sidebar: 'Barra lateral',\n companion_layout_fullscreen: 'Pantalla completa',\n companion_close: 'Cerrar',\n companion_history: 'Historial de conversaciones',\n companion_expand_chat: 'Ampliar chat',\n companion_sidebar_dock_label: 'Acople',\n companion_sidebar_side_label: 'Lado',\n companion_sidebar_left: 'Izquierda',\n companion_sidebar_right: 'Derecha',\n companion_resize_chat: 'Cambiar el tamaño del chat',\n scroll_to_bottom: 'Desplazarse al final',\n thinking: 'Pensando…',\n running: 'En curso…',\n steps: 'pasos',\n step_arguments: 'Argumentos',\n step_result: 'Resultado',\n attach_files:\n 'Adjuntar imágenes, vídeos, PDF u hojas de cálculo (tamaño máximo 25 MB)',\n mark_page_active:\n 'Haz clic en cualquier elemento de la página para marcarlo — Esc para cancelar',\n mark_page: 'Marca algo de la página para preguntar sobre ello',\n stop_response: 'Detener respuesta',\n copy_reply: 'Copiar respuesta',\n mentions_empty: 'Sin coincidencias',\n copied: 'Copiado',\n send_message: 'Enviar mensaje',\n upload_failed: 'Error al subir: {error}',\n remove_attachment: 'Quitar archivo adjunto',\n json_no_items: 'No hay elementos',\n json_no_data: 'No hay datos',\n json_no_chart_data: 'No hay datos para el gráfico',\n json_unsupported: 'No compatible: {type}',\n json_see_less: 'Ver menos',\n json_phone_agent: 'Agente telefónico',\n json_phone_agent_test: 'Probar en la web',\n page_context_remove: 'Quitar el contexto de la página',\n json_see_more: 'Ver {count} más',\n queued_label: '{count} En cola',\n remove_queued_message: 'Quitar mensaje de la cola',\n send_queued_now: 'Enviar los mensajes en cola ahora',\n turn_failed_message: 'Algo salió mal y la respuesta no llegó.',\n turn_failed_retry: 'Intentar de nuevo',\n page_mark_hint: 'Haz clic en algo para marcarlo',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Recuadro',\n page_mark_shape_circle: 'Círculo',\n page_mark_shape_arrow: 'Flecha',\n page_mark_shape_bracket: 'Corchete',\n page_mark_shape_underline: 'Subrayado',\n page_mark_shape_highlight: 'Resaltado',\n page_mark_shape_strike_through: 'Tachado',\n page_mark_shape_crossed_off: 'Tachado en cruz',\n page_mark_shape_aria: 'Forma de la marca: {shape}',\n page_mark_note_placeholder: 'Añade una nota… (Enter para adjuntar)',\n page_mark_attach: 'Adjuntar marca',\n page_mark_remove: 'Quitar {label}',\n page_mark_region: 'Región marcada',\n page_mark_default_message: '¿Qué es esto?',\n file_rejected:\n 'El tipo de archivo no es compatible o el archivo es demasiado grande.',\n dictate: 'Dictar',\n stop_dictation: 'Detener dictado',\n dictation_mic_blocked: 'Permite el acceso al micrófono para dictar',\n dictation_unavailable: 'El dictado no está disponible ahora mismo',\n questions_back: 'Atrás',\n questions_next: 'Siguiente',\n questions_send: 'Enviar',\n questions_type_answer: 'Lo escribo yo',\n questions_answer_placeholder: 'Escribe tu respuesta…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const FilipinoLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Magsulat ng mensahe...',\n your_issue_has_been_resolved: 'Nalutas na ang iyong isyu!',\n new_conversation: 'Bagong usapan',\n welcome_screen_title: 'Maligayang pagdating sa aming support chat',\n welcome_screen_description:\n 'Narito kami upang tumulong! Magsimula ng usapan at babalikan ka namin sa lalong madaling panahon.',\n your_name_placeholder: 'Iyong pangalan',\n your_email_placeholder: 'Iyong email address',\n start_chat_button: 'Makipag-usap sa support',\n start_chat_button_loading: 'Kumokonekta...',\n i_need_more_help: 'Kailangan ko pa ng tulong',\n this_was_helpful: 'Nakatulong ito',\n optional: 'Opsyonal',\n no_conversations_yet: 'Wala pang mga usapan',\n back_to_conversations: 'Bumalik sa mga usapan',\n closed_conversations: 'Mga saradong usapan',\n csat_title: 'Kumusta ang iyong usapan?',\n csat_submitted_title: 'Ni-rate mo ang usapan bilang',\n csat_feedback_placeholder: 'Sabihin pa sa amin... (opsyonal)',\n follow_up_placeholder: 'Magpatuloy…',\n companion_layout_label: 'Ayos',\n companion_layout_floating: 'Lumulutang',\n companion_layout_sidebar: 'Sidebar',\n companion_layout_fullscreen: 'Buong screen',\n companion_close: 'Isara',\n companion_history: 'Kasaysayan ng mga pag-uusap',\n companion_expand_chat: 'Palawakin ang chat',\n companion_sidebar_dock_label: 'Dock',\n companion_sidebar_side_label: 'Gilid',\n companion_sidebar_left: 'Kaliwa',\n companion_sidebar_right: 'Kanan',\n companion_resize_chat: 'Baguhin ang laki ng chat',\n scroll_to_bottom: 'Mag-scroll sa ibaba',\n thinking: 'Nag-iisip…',\n running: 'Isinasagawa…',\n steps: 'mga hakbang',\n step_arguments: 'Mga argumento',\n step_result: 'Resulta',\n attach_files:\n 'Mag-attach ng mga larawan, video, PDF, o spreadsheet (maximum na laki 25 MB)',\n mark_page_active:\n 'Mag-click ng kahit ano sa page para markahan ito — Esc para kanselahin',\n mark_page: 'Markahan ang isang bagay sa page para magtanong tungkol dito',\n stop_response: 'Ihinto ang sagot',\n copy_reply: 'Kopyahin ang sagot',\n mentions_empty: 'Walang tugma',\n copied: 'Nakopya',\n send_message: 'Ipadala ang mensahe',\n upload_failed: 'Hindi na-upload: {error}',\n remove_attachment: 'Alisin ang attachment',\n json_no_items: 'Walang mga item',\n json_no_data: 'Walang data',\n json_no_chart_data: 'Walang data para sa chart',\n json_unsupported: 'Hindi suportado: {type}',\n json_see_less: 'Tumingin ng mas kaunti',\n json_phone_agent: 'Phone agent',\n json_phone_agent_test: 'Subukan sa web',\n page_context_remove: 'Alisin ang konteksto ng page',\n json_see_more: 'Tumingin pa ng {count}',\n queued_label: '{count} Nakapila',\n remove_queued_message: 'Alisin ang mensahe sa pila',\n send_queued_now: 'Ipadala na ang mga mensahe sa pila',\n turn_failed_message: 'Nagkaproblema at hindi dumating ang sagot.',\n turn_failed_retry: 'Subukan muli',\n page_mark_hint: 'Mag-click ng kahit ano para markahan ito',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kahon',\n page_mark_shape_circle: 'Bilog',\n page_mark_shape_arrow: 'Palaso',\n page_mark_shape_bracket: 'Bracket',\n page_mark_shape_underline: 'Salungguhit',\n page_mark_shape_highlight: 'Highlight',\n page_mark_shape_strike_through: 'Guhit sa gitna',\n page_mark_shape_crossed_off: 'Ekis',\n page_mark_shape_aria: 'Hugis ng marka: {shape}',\n page_mark_note_placeholder: 'Magdagdag ng tala… (Enter para i-attach)',\n page_mark_attach: 'I-attach ang marka',\n page_mark_remove: 'Alisin ang {label}',\n page_mark_region: 'Minarkahang bahagi',\n page_mark_default_message: 'Ano ito?',\n file_rejected: 'Hindi suportado ang uri ng file o masyadong malaki ang file.',\n dictate: 'Mag-dictate',\n stop_dictation: 'Ihinto ang dictation',\n dictation_mic_blocked: 'Payagan ang access sa mikropono para mag-dictate',\n dictation_unavailable: 'Hindi available ang dictation ngayon',\n questions_back: 'Bumalik',\n questions_next: 'Susunod',\n questions_send: 'Ipadala',\n questions_type_answer: 'Ako na ang magta-type',\n questions_answer_placeholder: 'I-type ang iyong sagot…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const FinnishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Kirjoita viesti...',\n your_issue_has_been_resolved: 'Ongelmasi on ratkaistu!',\n new_conversation: 'Uusi keskustelu',\n welcome_screen_title: 'Tervetuloa tukichattiin',\n welcome_screen_description:\n 'Olemme täällä auttamassa! Aloita keskustelu ja palaamme sinulle mahdollisimman pian.',\n your_name_placeholder: 'Nimesi',\n your_email_placeholder: 'Sähköpostiosoitteesi',\n start_chat_button: 'Keskustele tuen kanssa',\n start_chat_button_loading: 'Yhdistetään...',\n i_need_more_help: 'Tarvitsen lisää apua',\n this_was_helpful: 'Tämä oli hyödyllistä',\n optional: 'Valinnainen',\n no_conversations_yet: 'Ei vielä keskusteluja',\n back_to_conversations: 'Takaisin keskusteluihin',\n closed_conversations: 'Suljetut keskustelut',\n csat_title: 'Millainen keskustelusi oli?',\n csat_submitted_title: 'Arvioit keskustelun',\n csat_feedback_placeholder: 'Kerro lisää... (valinnainen)',\n follow_up_placeholder: 'Jatka…',\n companion_layout_label: 'Asettelu',\n companion_layout_floating: 'Kelluva',\n companion_layout_sidebar: 'Sivupalkki',\n companion_layout_fullscreen: 'Koko näyttö',\n companion_close: 'Sulje',\n companion_history: 'Keskusteluhistoria',\n companion_expand_chat: 'Laajenna keskustelu',\n companion_sidebar_dock_label: 'Telakointi',\n companion_sidebar_side_label: 'Puoli',\n companion_sidebar_left: 'Vasen',\n companion_sidebar_right: 'Oikea',\n companion_resize_chat: 'Muuta keskustelun kokoa',\n scroll_to_bottom: 'Vieritä alas',\n thinking: 'Ajattelen…',\n running: 'Suoritetaan…',\n steps: 'vaihetta',\n step_arguments: 'Argumentit',\n step_result: 'Tulos',\n attach_files:\n 'Liitä kuvia, videoita, PDF-tiedostoja tai laskentataulukoita (enimmäiskoko 25 MB)',\n mark_page_active:\n 'Merkitse sivulta jotain napsauttamalla sitä — peruuta Esc-näppäimellä',\n mark_page: 'Merkitse sivulta jotain kysyäksesi siitä',\n stop_response: 'Pysäytä vastaus',\n copy_reply: 'Kopioi vastaus',\n mentions_empty: 'Ei osumia',\n copied: 'Kopioitu',\n send_message: 'Lähetä viesti',\n upload_failed: 'Lataus epäonnistui: {error}',\n remove_attachment: 'Poista liite',\n json_no_items: 'Ei kohteita',\n json_no_data: 'Ei tietoja',\n json_no_chart_data: 'Kaaviolle ei ole tietoja',\n json_unsupported: 'Ei tuettu: {type}',\n json_see_less: 'Näytä vähemmän',\n json_phone_agent: 'Puhelinagentti',\n json_phone_agent_test: 'Testaa verkossa',\n page_context_remove: 'Poista sivun konteksti',\n json_see_more: 'Näytä vielä {count}',\n queued_label: '{count} Jonossa',\n remove_queued_message: 'Poista viesti jonosta',\n send_queued_now: 'Lähetä jonossa olevat viestit nyt',\n turn_failed_message: 'Jokin meni pieleen, eikä vastaus saapunut.',\n turn_failed_retry: 'Yritä uudelleen',\n page_mark_hint: 'Merkitse jotain napsauttamalla sitä',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Laatikko',\n page_mark_shape_circle: 'Ympyrä',\n page_mark_shape_arrow: 'Nuoli',\n page_mark_shape_bracket: 'Hakasulje',\n page_mark_shape_underline: 'Alleviivaus',\n page_mark_shape_highlight: 'Korostus',\n page_mark_shape_strike_through: 'Yliviivaus',\n page_mark_shape_crossed_off: 'Rastita yli',\n page_mark_shape_aria: 'Merkinnän muoto: {shape}',\n page_mark_note_placeholder: 'Lisää huomautus… (Enter liittää)',\n page_mark_attach: 'Liitä merkintä',\n page_mark_remove: 'Poista {label}',\n page_mark_region: 'Merkitty alue',\n page_mark_default_message: 'Mikä tämä on?',\n file_rejected: 'Tiedostotyyppiä ei tueta tai tiedosto on liian suuri.',\n dictate: 'Sanele',\n stop_dictation: 'Lopeta sanelu',\n dictation_mic_blocked: 'Salli mikrofonin käyttö sanellaksesi',\n dictation_unavailable: 'Sanelu ei ole juuri nyt käytettävissä',\n questions_back: 'Takaisin',\n questions_next: 'Seuraava',\n questions_send: 'Lähetä',\n questions_type_answer: 'Kirjoitan itse',\n questions_answer_placeholder: 'Kirjoita vastauksesi…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const FrenchLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Écrivez un message...',\n your_issue_has_been_resolved: 'Votre problème a été résolu !',\n new_conversation: 'Nouvelle conversation',\n welcome_screen_title: 'Bienvenue dans notre chat de support',\n welcome_screen_description:\n 'Nous sommes là pour vous aider ! Commencez une conversation et nous vous répondrons dès que possible.',\n your_name_placeholder: 'Votre nom',\n your_email_placeholder: 'Votre adresse e-mail',\n start_chat_button: 'Parler au support',\n start_chat_button_loading: 'Connexion...',\n i_need_more_help: \"Je besoin d'aide plus\",\n this_was_helpful: \"C'était utile\",\n optional: 'Optionnel',\n no_conversations_yet: 'Aucune conversation pour le moment',\n back_to_conversations: 'Retour aux conversations',\n closed_conversations: 'Conversations fermées',\n csat_title: 'Comment s’est passée votre conversation ?',\n csat_submitted_title: 'Vous avez évalué la conversation comme',\n csat_feedback_placeholder: 'Dites-nous en plus... (facultatif)',\n follow_up_placeholder: 'Poser une autre question…',\n companion_layout_label: 'Disposition',\n companion_layout_floating: 'Flottant',\n companion_layout_sidebar: 'Barre latérale',\n companion_layout_fullscreen: 'Plein écran',\n companion_close: 'Fermer',\n companion_history: 'Historique des conversations',\n companion_expand_chat: 'Agrandir le chat',\n companion_sidebar_dock_label: 'Ancrage',\n companion_sidebar_side_label: 'Côté',\n companion_sidebar_left: 'Gauche',\n companion_sidebar_right: 'Droite',\n companion_resize_chat: 'Redimensionner le chat',\n scroll_to_bottom: 'Faire défiler vers le bas',\n thinking: 'Réflexion…',\n running: 'En cours…',\n steps: 'étapes',\n step_arguments: 'Arguments',\n step_result: 'Résultat',\n attach_files:\n 'Joindre des images, des vidéos, des PDF ou des feuilles de calcul (taille maximale 25 Mo)',\n mark_page_active:\n 'Cliquez sur un élément de la page pour le marquer — Échap pour annuler',\n mark_page:\n 'Marquez un élément de la page pour poser une question à son sujet',\n stop_response: 'Arrêter la réponse',\n copy_reply: 'Copier la réponse',\n mentions_empty: 'Aucun résultat',\n copied: 'Copié',\n send_message: 'Envoyer le message',\n upload_failed: 'Échec du téléversement : {error}',\n remove_attachment: 'Supprimer la pièce jointe',\n json_no_items: 'Aucun élément',\n json_no_data: 'Aucune donnée',\n json_no_chart_data: 'Aucune donnée à afficher dans le graphique',\n json_unsupported: 'Non pris en charge : {type}',\n json_see_less: 'Voir moins',\n json_phone_agent: 'Agent téléphonique',\n json_phone_agent_test: 'Tester via le web',\n page_context_remove: 'Retirer le contexte de la page',\n json_see_more: 'Voir {count} de plus',\n queued_label: '{count} En attente',\n remove_queued_message: 'Retirer le message de la file d’attente',\n send_queued_now: 'Envoyer les messages en attente maintenant',\n turn_failed_message:\n 'Un problème est survenu et la réponse n’est pas arrivée.',\n turn_failed_retry: 'Réessayer',\n page_mark_hint: 'Cliquez sur un élément pour le marquer',\n page_mark_escape: 'Échap',\n page_mark_shape_box: 'Encadré',\n page_mark_shape_circle: 'Cercle',\n page_mark_shape_arrow: 'Flèche',\n page_mark_shape_bracket: 'Crochet',\n page_mark_shape_underline: 'Soulignement',\n page_mark_shape_highlight: 'Surlignage',\n page_mark_shape_strike_through: 'Barré',\n page_mark_shape_crossed_off: 'Biffé',\n page_mark_shape_aria: 'Forme de la marque : {shape}',\n page_mark_note_placeholder: 'Ajouter une note… (Entrée pour joindre)',\n page_mark_attach: 'Joindre la marque',\n page_mark_remove: 'Supprimer {label}',\n page_mark_region: 'Zone marquée',\n page_mark_default_message: 'Qu’est-ce que c’est ?',\n file_rejected:\n 'Le type de fichier n’est pas pris en charge ou le fichier est trop volumineux.',\n dictate: 'Dicter',\n stop_dictation: 'Arrêter la dictée',\n dictation_mic_blocked: \"Autorisez l'accès au micro pour dicter\",\n dictation_unavailable: 'La dictée est indisponible pour le moment',\n questions_back: 'Retour',\n questions_next: 'Suivant',\n questions_send: 'Envoyer',\n questions_type_answer: 'Je préfère écrire',\n questions_answer_placeholder: 'Écrivez votre réponse…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const HindiLanguage: TranslationInterface = {\n write_a_message_placeholder: 'एक संदेश लिखें...',\n your_issue_has_been_resolved: 'आपकी समस्या हल हो गई है!',\n new_conversation: 'नई बातचीत',\n welcome_screen_title: 'हमारी सहायता चैट में आपका स्वागत है',\n welcome_screen_description:\n 'हम मदद के लिए यहाँ हैं! बातचीत शुरू करें और हम जल्द से जल्द आपसे संपर्क करेंगे।',\n your_name_placeholder: 'आपका नाम',\n your_email_placeholder: 'आपका ईमेल पता',\n start_chat_button: 'सहायता से बात करें',\n start_chat_button_loading: 'कनेक्ट हो रहा है...',\n i_need_more_help: 'मुझे और मदद चाहिए',\n this_was_helpful: 'यह मददगार था',\n optional: 'वैकल्पिक',\n no_conversations_yet: 'अभी तक कोई बातचीत नहीं',\n back_to_conversations: 'बातचीत पर वापस जाएं',\n closed_conversations: 'बंद बातचीत',\n csat_title: 'आपकी बातचीत कैसी रही?',\n csat_submitted_title: 'आपने बातचीत को आंका',\n csat_feedback_placeholder: 'हमें और बताएं... (वैकल्पिक)',\n follow_up_placeholder: 'आगे पूछें…',\n companion_layout_label: 'लेआउट',\n companion_layout_floating: 'फ़्लोटिंग',\n companion_layout_sidebar: 'साइडबार',\n companion_layout_fullscreen: 'पूर्ण स्क्रीन',\n companion_close: 'बंद करें',\n companion_history: 'बातचीत का इतिहास',\n companion_expand_chat: 'चैट फैलाएँ',\n companion_sidebar_dock_label: 'डॉक',\n companion_sidebar_side_label: 'ओर',\n companion_sidebar_left: 'बाएँ',\n companion_sidebar_right: 'दाएँ',\n companion_resize_chat: 'चैट का आकार बदलें',\n scroll_to_bottom: 'नीचे स्क्रॉल करें',\n thinking: 'सोच रहा है…',\n running: 'चल रहा है…',\n steps: 'चरण',\n step_arguments: 'आर्ग्युमेंट',\n step_result: 'परिणाम',\n attach_files:\n 'चित्र, वीडियो, PDF या स्प्रेडशीट संलग्न करें (अधिकतम आकार 25 MB)',\n mark_page_active:\n 'चिह्नित करने के लिए पेज पर किसी भी चीज़ पर क्लिक करें — रद्द करने के लिए Esc दबाएँ',\n mark_page: 'पेज पर किसी चीज़ के बारे में पूछने के लिए उसे चिह्नित करें',\n stop_response: 'जवाब रोकें',\n copy_reply: 'उत्तर कॉपी करें',\n mentions_empty: 'कोई मेल नहीं',\n copied: 'कॉपी हो गया',\n send_message: 'संदेश भेजें',\n upload_failed: 'अपलोड विफल: {error}',\n remove_attachment: 'अटैचमेंट हटाएँ',\n json_no_items: 'कोई आइटम नहीं',\n json_no_data: 'कोई डेटा नहीं',\n json_no_chart_data: 'चार्ट के लिए कोई डेटा नहीं',\n json_unsupported: 'समर्थित नहीं: {type}',\n json_see_less: 'कम देखें',\n json_phone_agent: 'फ़ोन एजेंट',\n json_phone_agent_test: 'वेब से परखें',\n page_context_remove: 'पेज संदर्भ हटाएँ',\n json_see_more: '{count} और देखें',\n queued_label: '{count} कतार में',\n remove_queued_message: 'संदेश को कतार से हटाएँ',\n send_queued_now: 'कतार के संदेश अभी भेजें',\n turn_failed_message: 'कुछ गलत हुआ और जवाब नहीं आया।',\n turn_failed_retry: 'फिर से कोशिश करें',\n page_mark_hint: 'चिह्नित करने के लिए किसी भी चीज़ पर क्लिक करें',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'बॉक्स',\n page_mark_shape_circle: 'वृत्त',\n page_mark_shape_arrow: 'तीर',\n page_mark_shape_bracket: 'कोष्ठक',\n page_mark_shape_underline: 'रेखांकन',\n page_mark_shape_highlight: 'हाइलाइट',\n page_mark_shape_strike_through: 'काटने की रेखा',\n page_mark_shape_crossed_off: 'क्रॉस से काटें',\n page_mark_shape_aria: 'चिह्न का आकार: {shape}',\n page_mark_note_placeholder: 'नोट जोड़ें… (संलग्न करने के लिए Enter दबाएँ)',\n page_mark_attach: 'चिह्न संलग्न करें',\n page_mark_remove: '{label} हटाएँ',\n page_mark_region: 'चिह्नित क्षेत्र',\n page_mark_default_message: 'यह क्या है?',\n file_rejected: 'फ़ाइल प्रकार समर्थित नहीं है या फ़ाइल बहुत बड़ी है।',\n dictate: 'बोलकर लिखें',\n stop_dictation: 'डिक्टेशन रोकें',\n dictation_mic_blocked: 'बोलकर लिखने के लिए माइक्रोफ़ोन की अनुमति दें',\n dictation_unavailable: 'डिक्टेशन अभी उपलब्ध नहीं है',\n questions_back: 'पीछे',\n questions_next: 'आगे',\n questions_send: 'भेजें',\n questions_type_answer: 'मैं खुद लिखूंगा',\n questions_answer_placeholder: 'अपना उत्तर लिखें…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const ItalianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Scrivi un messaggio...',\n your_issue_has_been_resolved: 'Il tuo problema è stato risolto!',\n new_conversation: 'Nuova conversazione',\n welcome_screen_title: 'Benvenuto nella nostra chat di supporto',\n welcome_screen_description:\n 'Siamo qui per aiutarti! Inizia una conversazione e ti risponderemo il prima possibile.',\n your_name_placeholder: 'Il tuo nome',\n your_email_placeholder: 'Il tuo indirizzo email',\n start_chat_button: 'Parla con il supporto',\n start_chat_button_loading: 'Connessione in corso...',\n i_need_more_help: 'Ho bisogno di ulteriore aiuto',\n this_was_helpful: 'Questo è stato utile',\n optional: 'Opzionale',\n no_conversations_yet: 'Nessuna conversazione ancora',\n back_to_conversations: 'Torna alle conversazioni',\n closed_conversations: 'Conversazioni chiuse',\n csat_title: 'Com’è andata la tua conversazione?',\n csat_submitted_title: 'Hai valutato la conversazione come',\n csat_feedback_placeholder: 'Dicci di più... (facoltativo)',\n follow_up_placeholder: 'Continua…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Mobile',\n companion_layout_sidebar: 'Barra laterale',\n companion_layout_fullscreen: 'Schermo intero',\n companion_close: 'Chiudi',\n companion_history: 'Cronologia conversazioni',\n companion_expand_chat: 'Espandi chat',\n companion_sidebar_dock_label: 'Aggancio',\n companion_sidebar_side_label: 'Lato',\n companion_sidebar_left: 'Sinistra',\n companion_sidebar_right: 'Destra',\n companion_resize_chat: 'Ridimensiona chat',\n scroll_to_bottom: 'Scorri fino in fondo',\n thinking: 'Sto pensando…',\n running: 'In esecuzione…',\n steps: 'passaggi',\n step_arguments: 'Argomenti',\n step_result: 'Risultato',\n attach_files:\n 'Allega immagini, video, PDF o fogli di calcolo (dimensione massima 25 MB)',\n mark_page_active:\n 'Fai clic su un elemento della pagina per contrassegnarlo — Esc per annullare',\n mark_page:\n 'Contrassegna un elemento della pagina per fare una domanda al riguardo',\n stop_response: 'Interrompi risposta',\n copy_reply: 'Copia risposta',\n mentions_empty: 'Nessun risultato',\n copied: 'Copiato',\n send_message: 'Invia messaggio',\n upload_failed: 'Caricamento non riuscito: {error}',\n remove_attachment: 'Rimuovi allegato',\n json_no_items: 'Nessun elemento',\n json_no_data: 'Nessun dato',\n json_no_chart_data: 'Nessun dato per il grafico',\n json_unsupported: 'Non supportato: {type}',\n json_see_less: 'Mostra meno',\n json_phone_agent: 'Agente telefonico',\n json_phone_agent_test: 'Prova via web',\n page_context_remove: 'Rimuovi il contesto della pagina',\n json_see_more: 'Mostra altri {count}',\n queued_label: '{count} In coda',\n remove_queued_message: 'Rimuovi messaggio dalla coda',\n send_queued_now: 'Invia ora i messaggi in coda',\n turn_failed_message:\n 'Si è verificato un problema e la risposta non è arrivata.',\n turn_failed_retry: 'Riprova',\n page_mark_hint: 'Fai clic su un elemento per contrassegnarlo',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Riquadro',\n page_mark_shape_circle: 'Cerchio',\n page_mark_shape_arrow: 'Freccia',\n page_mark_shape_bracket: 'Parentesi',\n page_mark_shape_underline: 'Sottolineatura',\n page_mark_shape_highlight: 'Evidenziazione',\n page_mark_shape_strike_through: 'Barrato',\n page_mark_shape_crossed_off: 'Cancellato con una croce',\n page_mark_shape_aria: 'Forma del segno: {shape}',\n page_mark_note_placeholder: 'Aggiungi una nota… (Invio per allegare)',\n page_mark_attach: 'Allega segno',\n page_mark_remove: 'Rimuovi {label}',\n page_mark_region: 'Area contrassegnata',\n page_mark_default_message: 'Che cos’è questo?',\n file_rejected: 'Il tipo di file non è supportato o il file è troppo grande.',\n dictate: 'Detta',\n stop_dictation: 'Interrompi dettatura',\n dictation_mic_blocked: \"Consenti l'accesso al microfono per dettare\",\n dictation_unavailable: 'La dettatura non è disponibile al momento',\n questions_back: 'Indietro',\n questions_next: 'Avanti',\n questions_send: 'Invia',\n questions_type_answer: 'Lo scrivo io',\n questions_answer_placeholder: 'Scrivi la tua risposta…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const JapaneseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'メッセージを入力...',\n your_issue_has_been_resolved: '問題が解決しました!',\n new_conversation: '新しい会話',\n welcome_screen_title: 'サポートチャットへようこそ',\n welcome_screen_description:\n 'お手伝いいたします!会話を開始していただければ、できるだけ早くご連絡いたします。',\n your_name_placeholder: 'お名前',\n your_email_placeholder: 'メールアドレス',\n start_chat_button: 'サポートに相談',\n start_chat_button_loading: '接続中...',\n i_need_more_help: 'さらにサポートが必要です',\n this_was_helpful: '役に立ちました',\n optional: '任意',\n no_conversations_yet: 'まだ会話がありません',\n back_to_conversations: '会話一覧に戻る',\n closed_conversations: '終了した会話',\n csat_title: '会話はいかがでしたか?',\n csat_submitted_title: '会話を次のように評価しました',\n csat_feedback_placeholder: '詳しく教えてください...(任意)',\n follow_up_placeholder: '続けて質問…',\n companion_layout_label: 'レイアウト',\n companion_layout_floating: 'フローティング',\n companion_layout_sidebar: 'サイドバー',\n companion_layout_fullscreen: '全画面',\n companion_close: '閉じる',\n companion_history: '会話履歴',\n companion_expand_chat: 'チャットを拡大',\n companion_sidebar_dock_label: 'ドック',\n companion_sidebar_side_label: '位置',\n companion_sidebar_left: '左',\n companion_sidebar_right: '右',\n companion_resize_chat: 'チャットのサイズを変更',\n scroll_to_bottom: '一番下までスクロール',\n thinking: '考えています…',\n running: '実行中…',\n steps: 'ステップ',\n step_arguments: '引数',\n step_result: '結果',\n attach_files: '画像、動画、PDF、スプレッドシートを添付(最大サイズ 25 MB)',\n mark_page_active: 'ページ上の項目をクリックしてマーク — Esc でキャンセル',\n mark_page: '質問したいページ上の項目をマーク',\n stop_response: '回答を停止',\n copy_reply: '返信をコピー',\n mentions_empty: '一致する項目はありません',\n copied: 'コピーしました',\n send_message: 'メッセージを送信',\n upload_failed: 'アップロードに失敗しました: {error}',\n remove_attachment: '添付ファイルを削除',\n json_no_items: '項目がありません',\n json_no_data: 'データがありません',\n json_no_chart_data: 'グラフ用のデータがありません',\n json_unsupported: '未対応: {type}',\n json_see_less: '表示を減らす',\n json_phone_agent: '電話エージェント',\n json_phone_agent_test: 'ウェブでテスト',\n page_context_remove: 'ページのコンテキストを削除',\n json_see_more: 'さらに {count} 件表示',\n queued_label: '{count} 送信待ち',\n remove_queued_message: '送信待ちのメッセージを削除',\n send_queued_now: '送信待ちのメッセージを今すぐ送信',\n turn_failed_message: '問題が発生し、回答を受信できませんでした。',\n turn_failed_retry: 'もう一度試す',\n page_mark_hint: 'クリックしてマーク',\n page_mark_escape: 'Esc',\n page_mark_shape_box: '枠',\n page_mark_shape_circle: '円',\n page_mark_shape_arrow: '矢印',\n page_mark_shape_bracket: 'かっこ',\n page_mark_shape_underline: '下線',\n page_mark_shape_highlight: 'ハイライト',\n page_mark_shape_strike_through: '取り消し線',\n page_mark_shape_crossed_off: '×印',\n page_mark_shape_aria: 'マークの形状: {shape}',\n page_mark_note_placeholder: 'メモを追加…(Enter で添付)',\n page_mark_attach: 'マークを添付',\n page_mark_remove: '{label}を削除',\n page_mark_region: 'マークした領域',\n page_mark_default_message: 'これは何ですか?',\n file_rejected: '対応していないファイル形式か、ファイルサイズが大きすぎます。',\n dictate: '音声入力',\n stop_dictation: '音声入力を停止',\n dictation_mic_blocked: '音声入力にはマイクへのアクセスを許可してください',\n dictation_unavailable: '音声入力は現在ご利用いただけません',\n questions_back: '戻る',\n questions_next: '次へ',\n questions_send: '送信',\n questions_type_answer: '自分で入力する',\n questions_answer_placeholder: '回答を入力してください…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const KoreanLanguage: TranslationInterface = {\n write_a_message_placeholder: '메시지를 입력하세요...',\n your_issue_has_been_resolved: '문제가 해결되었습니다!',\n new_conversation: '새 대화',\n welcome_screen_title: '고객 지원 채팅에 오신 것을 환영합니다',\n welcome_screen_description:\n '도움을 드리기 위해 여기 있습니다! 대화를 시작해 주시면 가능한 한 빨리 연락드리겠습니다.',\n your_name_placeholder: '이름',\n your_email_placeholder: '이메일 주소',\n start_chat_button: '상담원과 대화',\n start_chat_button_loading: '연결 중...',\n i_need_more_help: '추가 도움이 필요합니다',\n this_was_helpful: '도움이 되었습니다',\n optional: '선택 사항',\n no_conversations_yet: '아직 대화가 없습니다',\n back_to_conversations: '대화 목록으로 돌아가기',\n closed_conversations: '종료된 대화',\n csat_title: '대화는 어떠셨나요?',\n csat_submitted_title: '대화를 다음과 같이 평가했습니다',\n csat_feedback_placeholder: '더 알려주세요... (선택 사항)',\n follow_up_placeholder: '이어서 질문…',\n companion_layout_label: '레이아웃',\n companion_layout_floating: '플로팅',\n companion_layout_sidebar: '사이드바',\n companion_layout_fullscreen: '전체 화면',\n companion_close: '닫기',\n companion_history: '대화 기록',\n companion_expand_chat: '채팅 펼치기',\n companion_sidebar_dock_label: '도킹',\n companion_sidebar_side_label: '위치',\n companion_sidebar_left: '왼쪽',\n companion_sidebar_right: '오른쪽',\n companion_resize_chat: '채팅 크기 조절',\n scroll_to_bottom: '맨 아래로 스크롤',\n thinking: '생각 중…',\n running: '실행 중…',\n steps: '단계',\n step_arguments: '인수',\n step_result: '결과',\n attach_files: '이미지, 동영상, PDF 또는 스프레드시트 첨부(최대 크기 25 MB)',\n mark_page_active:\n '페이지에서 표시할 항목을 클릭하세요 — 취소하려면 Esc를 누르세요',\n mark_page: '질문할 페이지의 항목을 표시하세요',\n stop_response: '응답 중지',\n copy_reply: '답변 복사',\n mentions_empty: '일치하는 항목 없음',\n copied: '복사됨',\n send_message: '메시지 보내기',\n upload_failed: '업로드 실패: {error}',\n remove_attachment: '첨부 파일 삭제',\n json_no_items: '항목 없음',\n json_no_data: '데이터 없음',\n json_no_chart_data: '차트 데이터 없음',\n json_unsupported: '지원되지 않음: {type}',\n json_see_less: '간단히 보기',\n json_phone_agent: '전화 상담원',\n json_phone_agent_test: '웹에서 테스트',\n page_context_remove: '페이지 컨텍스트 제거',\n json_see_more: '{count}개 더 보기',\n queued_label: '{count} 대기 중',\n remove_queued_message: '대기열에서 메시지 삭제',\n send_queued_now: '대기 중인 메시지 지금 보내기',\n turn_failed_message: '문제가 발생하여 답변이 도착하지 않았습니다.',\n turn_failed_retry: '다시 시도',\n page_mark_hint: '표시할 항목을 클릭하세요',\n page_mark_escape: 'Esc',\n page_mark_shape_box: '상자',\n page_mark_shape_circle: '원',\n page_mark_shape_arrow: '화살표',\n page_mark_shape_bracket: '괄호',\n page_mark_shape_underline: '밑줄',\n page_mark_shape_highlight: '강조',\n page_mark_shape_strike_through: '취소선',\n page_mark_shape_crossed_off: 'X표',\n page_mark_shape_aria: '표시 모양: {shape}',\n page_mark_note_placeholder: '메모 추가…(Enter로 첨부)',\n page_mark_attach: '표시 첨부',\n page_mark_remove: '{label} 삭제',\n page_mark_region: '표시된 영역',\n page_mark_default_message: '이건 무엇인가요?',\n file_rejected: '지원되지 않는 파일 형식이거나 파일이 너무 큽니다.',\n dictate: '받아쓰기',\n stop_dictation: '받아쓰기 중지',\n dictation_mic_blocked: '받아쓰기를 하려면 마이크 접근을 허용하세요',\n dictation_unavailable: '지금은 받아쓰기를 사용할 수 없습니다',\n questions_back: '뒤로',\n questions_next: '다음',\n questions_send: '보내기',\n questions_type_answer: '직접 입력할게요',\n questions_answer_placeholder: '답변을 입력하세요…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const DutchLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Schrijf een bericht...',\n your_issue_has_been_resolved: 'Uw probleem is opgelost!',\n new_conversation: 'Nieuw gesprek',\n welcome_screen_title: 'Welkom bij onze supportchat',\n welcome_screen_description:\n 'We zijn hier om te helpen! Begin een gesprek en we nemen zo snel mogelijk contact met u op.',\n your_name_placeholder: 'Uw naam',\n your_email_placeholder: 'Uw e-mailadres',\n start_chat_button: 'Praat met ondersteuning',\n start_chat_button_loading: 'Verbinding maken...',\n i_need_more_help: 'Ik heb nog meer hulp nodig',\n this_was_helpful: 'Mijn vraag is opgelost',\n optional: 'Optioneel',\n no_conversations_yet: 'Nog geen gesprekken',\n back_to_conversations: 'Terug naar gesprekken',\n closed_conversations: 'Afgesloten gesprekken',\n csat_title: 'Hoe was je gesprek?',\n csat_submitted_title: 'Je hebt het gesprek beoordeeld als',\n csat_feedback_placeholder: 'Vertel ons meer... (optioneel)',\n follow_up_placeholder: 'Verder vragen…',\n companion_layout_label: 'Indeling',\n companion_layout_floating: 'Zwevend',\n companion_layout_sidebar: 'Zijbalk',\n companion_layout_fullscreen: 'Volledig scherm',\n companion_close: 'Sluiten',\n companion_history: 'Gespreksgeschiedenis',\n companion_expand_chat: 'Chat uitvouwen',\n companion_sidebar_dock_label: 'Vastzetten',\n companion_sidebar_side_label: 'Zijde',\n companion_sidebar_left: 'Links',\n companion_sidebar_right: 'Rechts',\n companion_resize_chat: 'Chatgrootte wijzigen',\n scroll_to_bottom: 'Naar beneden scrollen',\n thinking: 'Denkt na…',\n running: 'Wordt uitgevoerd…',\n steps: 'stappen',\n step_arguments: 'Argumenten',\n step_result: 'Resultaat',\n attach_files:\n \"Afbeeldingen, video's, pdf's of spreadsheets bijvoegen (maximale grootte 25 MB)\",\n mark_page_active:\n 'Klik op iets op de pagina om het te markeren — Esc om te annuleren',\n mark_page: 'Markeer iets op de pagina om er een vraag over te stellen',\n stop_response: 'Antwoord stoppen',\n copy_reply: 'Antwoord kopiëren',\n mentions_empty: 'Geen resultaten',\n copied: 'Gekopieerd',\n send_message: 'Bericht verzenden',\n upload_failed: 'Uploaden mislukt: {error}',\n remove_attachment: 'Bijlage verwijderen',\n json_no_items: 'Geen items',\n json_no_data: 'Geen gegevens',\n json_no_chart_data: 'Geen gegevens voor de grafiek',\n json_unsupported: 'Niet ondersteund: {type}',\n json_see_less: 'Minder weergeven',\n json_phone_agent: 'Telefoonagent',\n json_phone_agent_test: 'Testen via web',\n page_context_remove: 'Paginacontext verwijderen',\n json_see_more: 'Nog {count} weergeven',\n queued_label: '{count} In wachtrij',\n remove_queued_message: 'Bericht uit wachtrij verwijderen',\n send_queued_now: 'Berichten in wachtrij nu verzenden',\n turn_failed_message: 'Er ging iets mis en het antwoord is niet aangekomen.',\n turn_failed_retry: 'Opnieuw proberen',\n page_mark_hint: 'Klik op iets om het te markeren',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kader',\n page_mark_shape_circle: 'Cirkel',\n page_mark_shape_arrow: 'Pijl',\n page_mark_shape_bracket: 'Haakje',\n page_mark_shape_underline: 'Onderstrepen',\n page_mark_shape_highlight: 'Markeren',\n page_mark_shape_strike_through: 'Doorhalen',\n page_mark_shape_crossed_off: 'Doorkruisen',\n page_mark_shape_aria: 'Vorm van markering: {shape}',\n page_mark_note_placeholder: 'Voeg een notitie toe… (Enter om bij te voegen)',\n page_mark_attach: 'Markering bijvoegen',\n page_mark_remove: '{label} verwijderen',\n page_mark_region: 'Gemarkeerd gebied',\n page_mark_default_message: 'Wat is dit?',\n file_rejected:\n 'Het bestandstype wordt niet ondersteund of het bestand is te groot.',\n dictate: 'Dicteren',\n stop_dictation: 'Dicteren stoppen',\n dictation_mic_blocked: 'Sta microfoontoegang toe om te dicteren',\n dictation_unavailable: 'Dicteren is momenteel niet beschikbaar',\n questions_back: 'Terug',\n questions_next: 'Volgende',\n questions_send: 'Verzenden',\n questions_type_answer: 'Ik typ het zelf',\n questions_answer_placeholder: 'Typ je antwoord…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const NorwegianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv en melding...',\n your_issue_has_been_resolved: 'Problemet ditt er løst!',\n new_conversation: 'Ny samtale',\n welcome_screen_title: 'Velkommen til vår kundestøtte-chat',\n welcome_screen_description:\n 'Vi er her for å hjelpe! Start en samtale så kommer vi tilbake til deg så snart som mulig.',\n your_name_placeholder: 'Ditt navn',\n your_email_placeholder: 'Din e-postadresse',\n start_chat_button: 'Snakk med kundestøtte',\n start_chat_button_loading: 'Kobler til...',\n i_need_more_help: 'Jeg trenger mer hjelp',\n this_was_helpful: 'Dette var nyttig',\n optional: 'Valgfritt',\n no_conversations_yet: 'Ingen samtaler ennå',\n back_to_conversations: 'Tilbake til samtaler',\n closed_conversations: 'Lukkede samtaler',\n csat_title: 'Hvordan var samtalen din?',\n csat_submitted_title: 'Du vurderte samtalen som',\n csat_feedback_placeholder: 'Fortell oss mer... (valgfritt)',\n follow_up_placeholder: 'Følg opp…',\n companion_layout_label: 'Oppsett',\n companion_layout_floating: 'Flytende',\n companion_layout_sidebar: 'Sidepanel',\n companion_layout_fullscreen: 'Fullskjerm',\n companion_close: 'Lukk',\n companion_history: 'Samtalehistorikk',\n companion_expand_chat: 'Utvid chatten',\n companion_sidebar_dock_label: 'Dokking',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Venstre',\n companion_sidebar_right: 'Høyre',\n companion_resize_chat: 'Endre størrelsen på chatten',\n scroll_to_bottom: 'Rull til bunnen',\n thinking: 'Tenker…',\n running: 'Kjører…',\n steps: 'trinn',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Legg ved bilder, videoer, PDF-er eller regneark (maksimal størrelse 25 MB)',\n mark_page_active:\n 'Klikk på noe på siden for å markere det — Esc for å avbryte',\n mark_page: 'Marker noe på siden for å spørre om det',\n stop_response: 'Stopp svar',\n copy_reply: 'Kopier svar',\n mentions_empty: 'Ingen treff',\n copied: 'Kopiert',\n send_message: 'Send melding',\n upload_failed: 'Opplasting mislyktes: {error}',\n remove_attachment: 'Fjern vedlegg',\n json_no_items: 'Ingen elementer',\n json_no_data: 'Ingen data',\n json_no_chart_data: 'Ingen data for diagrammet',\n json_unsupported: 'Ikke støttet: {type}',\n json_see_less: 'Vis mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Test via nett',\n page_context_remove: 'Fjern sidekontekst',\n json_see_more: 'Vis {count} til',\n queued_label: '{count} I kø',\n remove_queued_message: 'Fjern meldingen fra køen',\n send_queued_now: 'Send meldinger i køen nå',\n turn_failed_message: 'Noe gikk galt, og svaret kom ikke fram.',\n turn_failed_retry: 'Prøv igjen',\n page_mark_hint: 'Klikk på noe for å markere det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ramme',\n page_mark_shape_circle: 'Sirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Klamme',\n page_mark_shape_underline: 'Understreking',\n page_mark_shape_highlight: 'Utheving',\n page_mark_shape_strike_through: 'Gjennomstreking',\n page_mark_shape_crossed_off: 'Kryss ut',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Legg til et notat… (Enter for å legge ved)',\n page_mark_attach: 'Legg ved markering',\n page_mark_remove: 'Fjern {label}',\n page_mark_region: 'Markert område',\n page_mark_default_message: 'Hva er dette?',\n file_rejected: 'Filtypen støttes ikke, eller filen er for stor.',\n dictate: 'Dikter',\n stop_dictation: 'Stopp diktering',\n dictation_mic_blocked: 'Tillat mikrofontilgang for å diktere',\n dictation_unavailable: 'Diktering er ikke tilgjengelig akkurat nå',\n questions_back: 'Tilbake',\n questions_next: 'Neste',\n questions_send: 'Send',\n questions_type_answer: 'Jeg skriver det selv',\n questions_answer_placeholder: 'Skriv svaret ditt…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const PolishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napisz wiadomość...',\n your_issue_has_been_resolved: 'Twój problem został rozwiązany!',\n new_conversation: 'Nowa rozmowa',\n welcome_screen_title: 'Witamy w naszym czacie wsparcia',\n welcome_screen_description:\n 'Jesteśmy tutaj, aby pomóc! Rozpocznij rozmowę, a odpowiemy jak najszybciej.',\n your_name_placeholder: 'Twoje imię',\n your_email_placeholder: 'Twój adres email',\n start_chat_button: 'Porozmawiaj ze wsparciem',\n start_chat_button_loading: 'Łączenie...',\n i_need_more_help: 'Potrzebuję więcej pomocy',\n this_was_helpful: 'To było pomocne',\n optional: 'Opcjonalne',\n no_conversations_yet: 'Jeszcze brak rozmów',\n back_to_conversations: 'Powrót do rozmów',\n closed_conversations: 'Zamknięte rozmowy',\n csat_title: 'Jak przebiegła Twoja rozmowa?',\n csat_submitted_title: 'Oceniłeś rozmowę jako',\n csat_feedback_placeholder: 'Powiedz nam więcej... (opcjonalnie)',\n follow_up_placeholder: 'Dopytaj…',\n companion_layout_label: 'Układ',\n companion_layout_floating: 'Pływający',\n companion_layout_sidebar: 'Pasek boczny',\n companion_layout_fullscreen: 'Pełny ekran',\n companion_close: 'Zamknij',\n companion_history: 'Historia rozmów',\n companion_expand_chat: 'Rozwiń czat',\n companion_sidebar_dock_label: 'Dokowanie',\n companion_sidebar_side_label: 'Strona',\n companion_sidebar_left: 'Lewa',\n companion_sidebar_right: 'Prawa',\n companion_resize_chat: 'Zmień rozmiar czatu',\n scroll_to_bottom: 'Przewiń na dół',\n thinking: 'Myślę…',\n running: 'W toku…',\n steps: 'kroki',\n step_arguments: 'Argumenty',\n step_result: 'Wynik',\n attach_files:\n 'Dołącz obrazy, filmy, pliki PDF lub arkusze kalkulacyjne (maksymalny rozmiar 25 MB)',\n mark_page_active:\n 'Kliknij coś na stronie, aby to oznaczyć — Esc, aby anulować',\n mark_page: 'Oznacz coś na stronie, aby o to zapytać',\n stop_response: 'Zatrzymaj odpowiedź',\n copy_reply: 'Kopiuj odpowiedź',\n mentions_empty: 'Brak wyników',\n copied: 'Skopiowano',\n send_message: 'Wyślij wiadomość',\n upload_failed: 'Przesyłanie nie powiodło się: {error}',\n remove_attachment: 'Usuń załącznik',\n json_no_items: 'Brak elementów',\n json_no_data: 'Brak danych',\n json_no_chart_data: 'Brak danych do wykresu',\n json_unsupported: 'Nieobsługiwane: {type}',\n json_see_less: 'Pokaż mniej',\n json_phone_agent: 'Agent telefoniczny',\n json_phone_agent_test: 'Przetestuj w sieci',\n page_context_remove: 'Usuń kontekst strony',\n json_see_more: 'Pokaż jeszcze {count}',\n queued_label: '{count} W kolejce',\n remove_queued_message: 'Usuń wiadomość z kolejki',\n send_queued_now: 'Wyślij wiadomości z kolejki teraz',\n turn_failed_message: 'Coś poszło nie tak i odpowiedź nie dotarła.',\n turn_failed_retry: 'Spróbuj ponownie',\n page_mark_hint: 'Kliknij coś, aby to oznaczyć',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ramka',\n page_mark_shape_circle: 'Okrąg',\n page_mark_shape_arrow: 'Strzałka',\n page_mark_shape_bracket: 'Nawias',\n page_mark_shape_underline: 'Podkreślenie',\n page_mark_shape_highlight: 'Wyróżnienie',\n page_mark_shape_strike_through: 'Przekreślenie',\n page_mark_shape_crossed_off: 'Skreślenie krzyżykiem',\n page_mark_shape_aria: 'Kształt oznaczenia: {shape}',\n page_mark_note_placeholder: 'Dodaj notatkę… (Enter, aby dołączyć)',\n page_mark_attach: 'Dołącz oznaczenie',\n page_mark_remove: 'Usuń {label}',\n page_mark_region: 'Oznaczony obszar',\n page_mark_default_message: 'Co to jest?',\n file_rejected: 'Typ pliku nie jest obsługiwany lub plik jest za duży.',\n dictate: 'Dyktuj',\n stop_dictation: 'Zatrzymaj dyktowanie',\n dictation_mic_blocked: 'Zezwól na dostęp do mikrofonu, aby dyktować',\n dictation_unavailable: 'Dyktowanie jest obecnie niedostępne',\n questions_back: 'Wstecz',\n questions_next: 'Dalej',\n questions_send: 'Wyślij',\n questions_type_answer: 'Napiszę sam',\n questions_answer_placeholder: 'Wpisz swoją odpowiedź…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const PortugueseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Escreva uma mensagem...',\n your_issue_has_been_resolved: 'Seu problema foi resolvido!',\n new_conversation: 'Nova conversa',\n welcome_screen_title: 'Bem-vindo ao nosso chat de suporte',\n welcome_screen_description:\n 'Estamos aqui para ajudar! Inicie uma conversa e responderemos o mais rápido possível.',\n your_name_placeholder: 'Seu nome',\n your_email_placeholder: 'Seu endereço de email',\n start_chat_button: 'Falar com o suporte',\n start_chat_button_loading: 'Conectando...',\n i_need_more_help: 'preciso de mais ajuda',\n this_was_helpful: 'Isso foi útil',\n optional: 'Opcional',\n no_conversations_yet: 'Nenhuma conversa ainda',\n back_to_conversations: 'Voltar para conversas',\n closed_conversations: 'Conversas fechadas',\n csat_title: 'Como foi a sua conversa?',\n csat_submitted_title: 'Você avaliou a conversa como',\n csat_feedback_placeholder: 'Conte-nos mais... (opcional)',\n follow_up_placeholder: 'Continuar…',\n companion_layout_label: 'Esquema',\n companion_layout_floating: 'Flutuante',\n companion_layout_sidebar: 'Barra lateral',\n companion_layout_fullscreen: 'Ecrã inteiro',\n companion_close: 'Fechar',\n companion_history: 'Histórico de conversas',\n companion_expand_chat: 'Expandir chat',\n companion_sidebar_dock_label: 'Ancoragem',\n companion_sidebar_side_label: 'Lado',\n companion_sidebar_left: 'Esquerda',\n companion_sidebar_right: 'Direita',\n companion_resize_chat: 'Redimensionar chat',\n scroll_to_bottom: 'Deslocar para o fim',\n thinking: 'A pensar…',\n running: 'Em execução…',\n steps: 'passos',\n step_arguments: 'Argumentos',\n step_result: 'Resultado',\n attach_files:\n 'Anexar imagens, vídeos, PDFs ou folhas de cálculo (tamanho máximo 25 MB)',\n mark_page_active:\n 'Clique em algo na página para o marcar — Esc para cancelar',\n mark_page: 'Marque algo na página para perguntar sobre isso',\n stop_response: 'Parar resposta',\n copy_reply: 'Copiar resposta',\n mentions_empty: 'Sem resultados',\n copied: 'Copiado',\n send_message: 'Enviar mensagem',\n upload_failed: 'Falha no carregamento: {error}',\n remove_attachment: 'Remover anexo',\n json_no_items: 'Sem itens',\n json_no_data: 'Sem dados',\n json_no_chart_data: 'Sem dados para o gráfico',\n json_unsupported: 'Não suportado: {type}',\n json_see_less: 'Ver menos',\n json_phone_agent: 'Agente telefónico',\n json_phone_agent_test: 'Testar via web',\n page_context_remove: 'Remover contexto da página',\n json_see_more: 'Ver mais {count}',\n queued_label: '{count} Na fila',\n remove_queued_message: 'Remover mensagem da fila',\n send_queued_now: 'Enviar mensagens da fila agora',\n turn_failed_message: 'Algo correu mal e a resposta não chegou.',\n turn_failed_retry: 'Tentar novamente',\n page_mark_hint: 'Clique em algo para o marcar',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Caixa',\n page_mark_shape_circle: 'Círculo',\n page_mark_shape_arrow: 'Seta',\n page_mark_shape_bracket: 'Parêntese',\n page_mark_shape_underline: 'Sublinhado',\n page_mark_shape_highlight: 'Realce',\n page_mark_shape_strike_through: 'Rasurado',\n page_mark_shape_crossed_off: 'Riscado em cruz',\n page_mark_shape_aria: 'Forma da marca: {shape}',\n page_mark_note_placeholder: 'Adicionar nota… (Enter para anexar)',\n page_mark_attach: 'Anexar marca',\n page_mark_remove: 'Remover {label}',\n page_mark_region: 'Área marcada',\n page_mark_default_message: 'O que é isto?',\n file_rejected:\n 'O tipo de ficheiro não é suportado ou o ficheiro é demasiado grande.',\n dictate: 'Ditar',\n stop_dictation: 'Parar ditado',\n dictation_mic_blocked: 'Permita o acesso ao microfone para ditar',\n dictation_unavailable: 'O ditado não está disponível agora',\n questions_back: 'Voltar',\n questions_next: 'Seguinte',\n questions_send: 'Enviar',\n questions_type_answer: 'Prefiro escrever',\n questions_answer_placeholder: 'Escreva a sua resposta…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const RomanianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Scrie un mesaj...',\n your_issue_has_been_resolved: 'Problema ta a fost rezolvată!',\n new_conversation: 'Conversație nouă',\n welcome_screen_title: 'Bine ai venit la chat-ul nostru de suport',\n welcome_screen_description:\n 'Suntem aici să te ajutăm! Începe o conversație și îți vom răspunde cât mai curând posibil.',\n your_name_placeholder: 'Numele tău',\n your_email_placeholder: 'Adresa ta de email',\n start_chat_button: 'Vorbește cu suportul',\n start_chat_button_loading: 'Se conectează...',\n i_need_more_help: 'Am nevoie de mai mult ajutor',\n this_was_helpful: 'Acest lucru a fost util',\n optional: 'Opțional',\n no_conversations_yet: 'Încă nu există conversații',\n back_to_conversations: 'Înapoi la conversații',\n closed_conversations: 'Conversații închise',\n csat_title: 'Cum a fost conversația ta?',\n csat_submitted_title: 'Ai evaluat conversația ca',\n csat_feedback_placeholder: 'Spune-ne mai multe... (opțional)',\n follow_up_placeholder: 'Continuă…',\n companion_layout_label: 'Aspect',\n companion_layout_floating: 'Flotant',\n companion_layout_sidebar: 'Bară laterală',\n companion_layout_fullscreen: 'Ecran complet',\n companion_close: 'Închide',\n companion_history: 'Istoricul conversațiilor',\n companion_expand_chat: 'Extinde chatul',\n companion_sidebar_dock_label: 'Andocare',\n companion_sidebar_side_label: 'Parte',\n companion_sidebar_left: 'Stânga',\n companion_sidebar_right: 'Dreapta',\n companion_resize_chat: 'Redimensionează chatul',\n scroll_to_bottom: 'Derulează în partea de jos',\n thinking: 'Mă gândesc…',\n running: 'În curs…',\n steps: 'pași',\n step_arguments: 'Argumente',\n step_result: 'Rezultat',\n attach_files:\n 'Atașează imagini, videoclipuri, PDF-uri sau foi de calcul (dimensiune maximă 25 MB)',\n mark_page_active:\n 'Dă clic pe ceva din pagină pentru a-l marca — Esc pentru anulare',\n mark_page: 'Marchează ceva din pagină pentru a întreba despre acel element',\n stop_response: 'Oprește răspunsul',\n copy_reply: 'Copiază răspunsul',\n mentions_empty: 'Niciun rezultat',\n copied: 'Copiat',\n send_message: 'Trimite mesajul',\n upload_failed: 'Încărcarea a eșuat: {error}',\n remove_attachment: 'Elimină atașamentul',\n json_no_items: 'Niciun element',\n json_no_data: 'Nu există date',\n json_no_chart_data: 'Nu există date pentru grafic',\n json_unsupported: 'Neacceptat: {type}',\n json_see_less: 'Vezi mai puțin',\n json_phone_agent: 'Agent telefonic',\n json_phone_agent_test: 'Testează pe web',\n page_context_remove: 'Elimină contextul paginii',\n json_see_more: 'Vezi încă {count}',\n queued_label: '{count} În așteptare',\n remove_queued_message: 'Elimină mesajul din coadă',\n send_queued_now: 'Trimite acum mesajele din coadă',\n turn_failed_message: 'Ceva nu a mers bine și răspunsul nu a sosit.',\n turn_failed_retry: 'Încearcă din nou',\n page_mark_hint: 'Dă clic pe ceva pentru a-l marca',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Chenar',\n page_mark_shape_circle: 'Cerc',\n page_mark_shape_arrow: 'Săgeată',\n page_mark_shape_bracket: 'Paranteză',\n page_mark_shape_underline: 'Subliniere',\n page_mark_shape_highlight: 'Evidențiere',\n page_mark_shape_strike_through: 'Tăiere',\n page_mark_shape_crossed_off: 'Tăiere în cruce',\n page_mark_shape_aria: 'Forma marcajului: {shape}',\n page_mark_note_placeholder: 'Adaugă o notă… (Enter pentru atașare)',\n page_mark_attach: 'Atașează marcajul',\n page_mark_remove: 'Elimină {label}',\n page_mark_region: 'Zonă marcată',\n page_mark_default_message: 'Ce este acesta?',\n file_rejected:\n 'Tipul de fișier nu este acceptat sau fișierul este prea mare.',\n dictate: 'Dictează',\n stop_dictation: 'Oprește dictarea',\n dictation_mic_blocked: 'Permite accesul la microfon pentru a dicta',\n dictation_unavailable: 'Dictarea nu este disponibilă momentan',\n questions_back: 'Înapoi',\n questions_next: 'Înainte',\n questions_send: 'Trimite',\n questions_type_answer: 'Scriu eu',\n questions_answer_placeholder: 'Scrieți răspunsul dvs.…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const SwedishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv ett meddelande...',\n your_issue_has_been_resolved: 'Ditt problem har lösts!',\n new_conversation: 'Ny konversation',\n welcome_screen_title: 'Välkommen till vår supportchatt',\n welcome_screen_description:\n 'Vi är här för att hjälpa! Starta en konversation så återkommer vi till dig så snart som möjligt.',\n your_name_placeholder: 'Ditt namn',\n your_email_placeholder: 'Din e-postadress',\n start_chat_button: 'Prata med support',\n start_chat_button_loading: 'Ansluter...',\n i_need_more_help: 'Jag behöver mer hjälp',\n this_was_helpful: 'Detta var användbart',\n optional: 'Frivilligt',\n no_conversations_yet: 'Inga konversationer ännu',\n back_to_conversations: 'Tillbaka till konversationer',\n closed_conversations: 'Stängda konversationer',\n csat_title: 'Hur var din konversation?',\n csat_submitted_title: 'Du betygsatte konversationen som',\n csat_feedback_placeholder: 'Berätta mer... (valfritt)',\n follow_up_placeholder: 'Följ upp…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Flytande',\n companion_layout_sidebar: 'Sidopanel',\n companion_layout_fullscreen: 'Helskärm',\n companion_close: 'Stäng',\n companion_history: 'Konversationshistorik',\n companion_expand_chat: 'Expandera chatten',\n companion_sidebar_dock_label: 'Dockning',\n companion_sidebar_side_label: 'Sida',\n companion_sidebar_left: 'Vänster',\n companion_sidebar_right: 'Höger',\n companion_resize_chat: 'Ändra chattens storlek',\n scroll_to_bottom: 'Rulla längst ned',\n thinking: 'Tänker…',\n running: 'Körs…',\n steps: 'steg',\n step_arguments: 'Argument',\n step_result: 'Resultat',\n attach_files:\n 'Bifoga bilder, videor, PDF-filer eller kalkylblad (maximal storlek 25 MB)',\n mark_page_active:\n 'Klicka på något på sidan för att markera det — Esc för att avbryta',\n mark_page: 'Markera något på sidan för att fråga om det',\n stop_response: 'Stoppa svaret',\n copy_reply: 'Kopiera svar',\n mentions_empty: 'Inga träffar',\n copied: 'Kopierat',\n send_message: 'Skicka meddelande',\n upload_failed: 'Uppladdningen misslyckades: {error}',\n remove_attachment: 'Ta bort bilaga',\n json_no_items: 'Inga objekt',\n json_no_data: 'Inga data',\n json_no_chart_data: 'Inga data för diagrammet',\n json_unsupported: 'Stöds inte: {type}',\n json_see_less: 'Visa mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Testa via webben',\n page_context_remove: 'Ta bort sidkontext',\n json_see_more: 'Visa ytterligare {count}',\n queued_label: '{count} I kö',\n remove_queued_message: 'Ta bort meddelandet från kön',\n send_queued_now: 'Skicka köade meddelanden nu',\n turn_failed_message: 'Något gick fel och svaret kom inte fram.',\n turn_failed_retry: 'Försök igen',\n page_mark_hint: 'Klicka på något för att markera det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ruta',\n page_mark_shape_circle: 'Cirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Hakparentes',\n page_mark_shape_underline: 'Understrykning',\n page_mark_shape_highlight: 'Markering',\n page_mark_shape_strike_through: 'Genomstrykning',\n page_mark_shape_crossed_off: 'Kryssa över',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Lägg till en anteckning… (Enter för att bifoga)',\n page_mark_attach: 'Bifoga markering',\n page_mark_remove: 'Ta bort {label}',\n page_mark_region: 'Markerat område',\n page_mark_default_message: 'Vad är det här?',\n file_rejected: 'Filtypen stöds inte eller filen är för stor.',\n dictate: 'Diktera',\n stop_dictation: 'Sluta diktera',\n dictation_mic_blocked: 'Tillåt mikrofonåtkomst för att diktera',\n dictation_unavailable: 'Diktering är inte tillgänglig just nu',\n questions_back: 'Tillbaka',\n questions_next: 'Nästa',\n questions_send: 'Skicka',\n questions_type_answer: 'Jag skriver själv',\n questions_answer_placeholder: 'Skriv ditt svar…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const RussianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Напишите сообщение...',\n your_issue_has_been_resolved: 'Ваша проблема решена!',\n new_conversation: 'Новый разговор',\n welcome_screen_title: 'Добро пожаловать в чат поддержки',\n welcome_screen_description:\n 'Мы здесь, чтобы помочь! Начните разговор, и мы ответим вам как можно скорее.',\n your_name_placeholder: 'Ваше имя',\n your_email_placeholder: 'Ваш адрес электронной почты',\n start_chat_button: 'Связаться с поддержкой',\n start_chat_button_loading: 'Подключение...',\n i_need_more_help: 'Мне нужна дополнительная помощь',\n this_was_helpful: 'Это было полезно',\n optional: 'Необязательно',\n no_conversations_yet: 'Пока нет разговоров',\n back_to_conversations: 'Назад к разговорам',\n closed_conversations: 'Закрытые разговоры',\n csat_title: 'Как прошёл ваш разговор?',\n csat_submitted_title: 'Вы оценили разговор как',\n csat_feedback_placeholder: 'Расскажите подробнее... (необязательно)',\n follow_up_placeholder: 'Уточнить…',\n companion_layout_label: 'Макет',\n companion_layout_floating: 'Плавающий',\n companion_layout_sidebar: 'Боковая панель',\n companion_layout_fullscreen: 'На весь экран',\n companion_close: 'Закрыть',\n companion_history: 'История разговоров',\n companion_expand_chat: 'Развернуть чат',\n companion_sidebar_dock_label: 'Закрепление',\n companion_sidebar_side_label: 'Сторона',\n companion_sidebar_left: 'Слева',\n companion_sidebar_right: 'Справа',\n companion_resize_chat: 'Изменить размер чата',\n scroll_to_bottom: 'Прокрутить вниз',\n thinking: 'Думаю…',\n running: 'Выполняется…',\n steps: 'шаги',\n step_arguments: 'Аргументы',\n step_result: 'Результат',\n attach_files:\n 'Прикрепить изображения, видео, PDF-файлы или таблицы (максимальный размер 25 МБ)',\n mark_page_active:\n 'Нажмите на элемент страницы, чтобы отметить его — Esc для отмены',\n mark_page: 'Отметьте элемент на странице, чтобы задать вопрос о нём',\n stop_response: 'Остановить ответ',\n copy_reply: 'Скопировать ответ',\n mentions_empty: 'Ничего не найдено',\n copied: 'Скопировано',\n send_message: 'Отправить сообщение',\n upload_failed: 'Не удалось загрузить: {error}',\n remove_attachment: 'Удалить вложение',\n json_no_items: 'Нет элементов',\n json_no_data: 'Нет данных',\n json_no_chart_data: 'Нет данных для диаграммы',\n json_unsupported: 'Не поддерживается: {type}',\n json_see_less: 'Показать меньше',\n json_phone_agent: 'Телефонный агент',\n json_phone_agent_test: 'Проверить через веб',\n page_context_remove: 'Убрать контекст страницы',\n json_see_more: 'Показать ещё {count}',\n queued_label: '{count} В очереди',\n remove_queued_message: 'Удалить сообщение из очереди',\n send_queued_now: 'Отправить сообщения из очереди сейчас',\n turn_failed_message: 'Что-то пошло не так, и ответ не пришёл.',\n turn_failed_retry: 'Повторить попытку',\n page_mark_hint: 'Нажмите на элемент, чтобы отметить его',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Рамка',\n page_mark_shape_circle: 'Круг',\n page_mark_shape_arrow: 'Стрелка',\n page_mark_shape_bracket: 'Скобка',\n page_mark_shape_underline: 'Подчёркивание',\n page_mark_shape_highlight: 'Выделение',\n page_mark_shape_strike_through: 'Зачёркивание',\n page_mark_shape_crossed_off: 'Перечёркивание крестом',\n page_mark_shape_aria: 'Форма отметки: {shape}',\n page_mark_note_placeholder: 'Добавить заметку… (Enter, чтобы прикрепить)',\n page_mark_attach: 'Прикрепить отметку',\n page_mark_remove: 'Удалить {label}',\n page_mark_region: 'Отмеченная область',\n page_mark_default_message: 'Что это?',\n file_rejected: 'Тип файла не поддерживается или файл слишком большой.',\n dictate: 'Диктовать',\n stop_dictation: 'Остановить диктовку',\n dictation_mic_blocked: 'Разрешите доступ к микрофону, чтобы диктовать',\n dictation_unavailable: 'Диктовка сейчас недоступна',\n questions_back: 'Назад',\n questions_next: 'Далее',\n questions_send: 'Отправить',\n questions_type_answer: 'Напишу сам',\n questions_answer_placeholder: 'Напишите ваш ответ…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const ThaiLanguage: TranslationInterface = {\n write_a_message_placeholder: 'เขียนข้อความ...',\n your_issue_has_been_resolved: 'ปัญหาของคุณได้รับการแก้ไขแล้ว!',\n new_conversation: 'การสนทนาใหม่',\n welcome_screen_title: 'ยินดีต้อนรับสู่แชทสนับสนุนของเรา',\n welcome_screen_description:\n 'เราพร้อมช่วยเหลือคุณ! เริ่มการสนทนาและเราจะติดต่อกลับโดยเร็วที่สุด',\n your_name_placeholder: 'ชื่อของคุณ',\n your_email_placeholder: 'ที่อยู่อีเมลของคุณ',\n start_chat_button: 'พูดคุยกับฝ่ายสนับสนุน',\n start_chat_button_loading: 'กำลังเชื่อมต่อ...',\n i_need_more_help: 'ฉันต้องการความช่วยเหลือเพิ่มเติม',\n this_was_helpful: 'สิ่งนี้เป็นประโยชน์',\n optional: 'ไม่บังคับ',\n no_conversations_yet: 'ยังไม่มีการสนทนา',\n back_to_conversations: 'กลับไปที่การสนทนา',\n closed_conversations: 'การสนทนาที่ปิดแล้ว',\n csat_title: 'การสนทนาของคุณเป็นอย่างไรบ้าง?',\n csat_submitted_title: 'คุณให้คะแนนการสนทนาว่า',\n csat_feedback_placeholder: 'บอกเราเพิ่มเติม... (ไม่บังคับ)',\n follow_up_placeholder: 'ถามต่อ…',\n companion_layout_label: 'เค้าโครง',\n companion_layout_floating: 'แบบลอย',\n companion_layout_sidebar: 'แถบด้านข้าง',\n companion_layout_fullscreen: 'เต็มหน้าจอ',\n companion_close: 'ปิด',\n companion_history: 'ประวัติการสนทนา',\n companion_expand_chat: 'ขยายแชต',\n companion_sidebar_dock_label: 'เชื่อมต่อ',\n companion_sidebar_side_label: 'ด้าน',\n companion_sidebar_left: 'ซ้าย',\n companion_sidebar_right: 'ขวา',\n companion_resize_chat: 'ปรับขนาดแชต',\n scroll_to_bottom: 'เลื่อนไปด้านล่าง',\n thinking: 'กำลังคิด…',\n running: 'กำลังทำงาน…',\n steps: 'ขั้นตอน',\n step_arguments: 'อาร์กิวเมนต์',\n step_result: 'ผลลัพธ์',\n attach_files: 'แนบรูปภาพ วิดีโอ PDF หรือสเปรดชีต (ขนาดสูงสุด 25 MB)',\n mark_page_active:\n 'คลิกสิ่งใดก็ได้บนหน้าเพื่อทำเครื่องหมาย — กด Esc เพื่อยกเลิก',\n mark_page: 'ทำเครื่องหมายสิ่งที่อยู่บนหน้าเพื่อถามเกี่ยวกับสิ่งนั้น',\n stop_response: 'หยุดการตอบ',\n copy_reply: 'คัดลอกคำตอบ',\n mentions_empty: 'ไม่พบรายการ',\n copied: 'คัดลอกแล้ว',\n send_message: 'ส่งข้อความ',\n upload_failed: 'อัปโหลดไม่สำเร็จ: {error}',\n remove_attachment: 'ลบไฟล์แนบ',\n json_no_items: 'ไม่มีรายการ',\n json_no_data: 'ไม่มีข้อมูล',\n json_no_chart_data: 'ไม่มีข้อมูลสำหรับแผนภูมิ',\n json_unsupported: 'ไม่รองรับ: {type}',\n json_see_less: 'ดูน้อยลง',\n json_phone_agent: 'เอเจนต์โทรศัพท์',\n json_phone_agent_test: 'ทดสอบผ่านเว็บ',\n page_context_remove: 'ลบบริบทของหน้า',\n json_see_more: 'ดูเพิ่มอีก {count} รายการ',\n queued_label: '{count} อยู่ในคิว',\n remove_queued_message: 'นำข้อความออกจากคิว',\n send_queued_now: 'ส่งข้อความในคิวตอนนี้',\n turn_failed_message: 'เกิดข้อผิดพลาดและไม่ได้รับคำตอบ',\n turn_failed_retry: 'ลองอีกครั้ง',\n page_mark_hint: 'คลิกสิ่งใดก็ได้เพื่อทำเครื่องหมาย',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'กรอบ',\n page_mark_shape_circle: 'วงกลม',\n page_mark_shape_arrow: 'ลูกศร',\n page_mark_shape_bracket: 'วงเล็บ',\n page_mark_shape_underline: 'ขีดเส้นใต้',\n page_mark_shape_highlight: 'ไฮไลต์',\n page_mark_shape_strike_through: 'ขีดฆ่า',\n page_mark_shape_crossed_off: 'กากบาท',\n page_mark_shape_aria: 'รูปร่างเครื่องหมาย: {shape}',\n page_mark_note_placeholder: 'เพิ่มหมายเหตุ… (กด Enter เพื่อแนบ)',\n page_mark_attach: 'แนบเครื่องหมาย',\n page_mark_remove: 'ลบ {label}',\n page_mark_region: 'บริเวณที่ทำเครื่องหมาย',\n page_mark_default_message: 'นี่คืออะไร',\n file_rejected: 'ไม่รองรับประเภทไฟล์หรือไฟล์มีขนาดใหญ่เกินไป',\n dictate: 'พูดเพื่อพิมพ์',\n stop_dictation: 'หยุดการพูดเพื่อพิมพ์',\n dictation_mic_blocked: 'อนุญาตการเข้าถึงไมโครโฟนเพื่อพูดเพื่อพิมพ์',\n dictation_unavailable: 'ไม่สามารถใช้การพูดเพื่อพิมพ์ได้ในขณะนี้',\n questions_back: 'ย้อนกลับ',\n questions_next: 'ถัดไป',\n questions_send: 'ส่ง',\n questions_type_answer: 'ขอพิมพ์เอง',\n questions_answer_placeholder: 'พิมพ์คำตอบของคุณ…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const TurkishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Bir mesaj yazın...',\n your_issue_has_been_resolved: 'Sorununuz çözüldü!',\n new_conversation: 'Yeni konuşma',\n welcome_screen_title: 'Destek sohbetimize hoş geldiniz',\n welcome_screen_description:\n 'Yardım etmek için buradayız! Bir konuşma başlatın, en kısa sürede size geri döneceğiz.',\n your_name_placeholder: 'Adınız',\n your_email_placeholder: 'E-posta adresiniz',\n start_chat_button: 'Destekle konuş',\n start_chat_button_loading: 'Bağlanıyor...',\n i_need_more_help: 'Daha fazla yardıma ihtiyacım var',\n this_was_helpful: 'Bu yardımcı oldu',\n optional: 'İsteğe bağlı',\n no_conversations_yet: 'Henüz konuşma yok',\n back_to_conversations: 'Konuşmalara geri dön',\n closed_conversations: 'Kapatılan konuşmalar',\n csat_title: 'Görüşmeniz nasıldı?',\n csat_submitted_title: 'Görüşmeyi şöyle değerlendirdiniz',\n csat_feedback_placeholder: 'Bize daha fazlasını anlatın... (isteğe bağlı)',\n follow_up_placeholder: 'Devam et…',\n companion_layout_label: 'Düzen',\n companion_layout_floating: 'Kayan',\n companion_layout_sidebar: 'Kenar çubuğu',\n companion_layout_fullscreen: 'Tam ekran',\n companion_close: 'Kapat',\n companion_history: 'Konuşma geçmişi',\n companion_expand_chat: 'Sohbeti genişlet',\n companion_sidebar_dock_label: 'Sabitleme',\n companion_sidebar_side_label: 'Taraf',\n companion_sidebar_left: 'Sol',\n companion_sidebar_right: 'Sağ',\n companion_resize_chat: 'Sohbeti yeniden boyutlandır',\n scroll_to_bottom: 'En alta kaydır',\n thinking: 'Düşünüyor…',\n running: 'Çalışıyor…',\n steps: 'adım',\n step_arguments: 'Bağımsız değişkenler',\n step_result: 'Sonuç',\n attach_files:\n 'Görsel, video, PDF veya elektronik tablo ekle (en fazla 25 MB)',\n mark_page_active:\n \"İşaretlemek için sayfadaki bir öğeye tıklayın — iptal etmek için Esc'ye basın\",\n mark_page: 'Hakkında soru sormak için sayfadaki bir öğeyi işaretleyin',\n stop_response: 'Yanıtı durdur',\n copy_reply: 'Yanıtı kopyala',\n mentions_empty: 'Eşleşme yok',\n copied: 'Kopyalandı',\n send_message: 'Mesaj gönder',\n upload_failed: 'Yükleme başarısız: {error}',\n remove_attachment: 'Eki kaldır',\n json_no_items: 'Öğe yok',\n json_no_data: 'Veri yok',\n json_no_chart_data: 'Grafik için veri yok',\n json_unsupported: 'Desteklenmiyor: {type}',\n json_see_less: 'Daha az göster',\n json_phone_agent: 'Telefon temsilcisi',\n json_phone_agent_test: 'Web üzerinden test et',\n page_context_remove: 'Sayfa bağlamını kaldır',\n json_see_more: '{count} tane daha göster',\n queued_label: '{count} Sırada',\n remove_queued_message: 'Mesajı sıradan kaldır',\n send_queued_now: 'Sıradaki mesajları şimdi gönder',\n turn_failed_message: 'Bir sorun oluştu ve yanıt ulaşmadı.',\n turn_failed_retry: 'Tekrar dene',\n page_mark_hint: 'İşaretlemek için bir öğeye tıklayın',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kutu',\n page_mark_shape_circle: 'Daire',\n page_mark_shape_arrow: 'Ok',\n page_mark_shape_bracket: 'Ayraç',\n page_mark_shape_underline: 'Alt çizgi',\n page_mark_shape_highlight: 'Vurgu',\n page_mark_shape_strike_through: 'Üstü çizili',\n page_mark_shape_crossed_off: 'Çarpı at',\n page_mark_shape_aria: 'İşaret şekli: {shape}',\n page_mark_note_placeholder: \"Not ekleyin… (Eklemek için Enter'a basın)\",\n page_mark_attach: 'İşareti ekle',\n page_mark_remove: '{label} öğesini kaldır',\n page_mark_region: 'İşaretli bölge',\n page_mark_default_message: 'Bu nedir?',\n file_rejected: 'Dosya türü desteklenmiyor veya dosya çok büyük.',\n dictate: 'Dikte et',\n stop_dictation: 'Dikteyi durdur',\n dictation_mic_blocked: 'Dikte etmek için mikrofon erişimine izin verin',\n dictation_unavailable: 'Dikte şu anda kullanılamıyor',\n questions_back: 'Geri',\n questions_next: 'İleri',\n questions_send: 'Gönder',\n questions_type_answer: 'Kendim yazayım',\n questions_answer_placeholder: 'Yanıtınızı yazın…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const UrduLanguage: TranslationInterface = {\n write_a_message_placeholder: 'پیغام لکھیں...',\n your_issue_has_been_resolved: 'آپ کا مسئلہ حل ہو گیا ہے!',\n new_conversation: 'نئی گفتگو',\n welcome_screen_title: 'ہماری سپورٹ چیٹ میں خوش آمدید',\n welcome_screen_description:\n 'ہم مدد کے لیے حاضر ہیں! گفتگو شروع کریں اور ہم جلد از جلد آپ سے رابطہ کریں گے۔',\n your_name_placeholder: 'آپ کا نام',\n your_email_placeholder: 'آپ کا ای میل پتہ',\n start_chat_button: 'سپورٹ سے بات کریں',\n start_chat_button_loading: 'جڑ رہا ہے...',\n i_need_more_help: 'مجھے مزید مدد چاہیے',\n this_was_helpful: 'یہ مددگار تھا',\n optional: 'اختیاری',\n no_conversations_yet: 'ابھی تک کوئی گفتگو نہیں',\n back_to_conversations: 'گفتگو پر واپس جائیں',\n closed_conversations: 'بند گفتگو',\n csat_title: 'آپ کی گفتگو کیسی رہی؟',\n csat_submitted_title: 'آپ نے گفتگو کو درجہ دیا',\n csat_feedback_placeholder: 'ہمیں مزید بتائیں... (اختیاری)',\n follow_up_placeholder: 'مزید پوچھیں…',\n companion_layout_label: 'لے آؤٹ',\n companion_layout_floating: 'فلوٹنگ',\n companion_layout_sidebar: 'سائیڈ بار',\n companion_layout_fullscreen: 'مکمل اسکرین',\n companion_close: 'بند کریں',\n companion_history: 'گفتگو کی سرگزشت',\n companion_expand_chat: 'چیٹ پھیلائیں',\n companion_sidebar_dock_label: 'ڈاک',\n companion_sidebar_side_label: 'طرف',\n companion_sidebar_left: 'بائیں',\n companion_sidebar_right: 'دائیں',\n companion_resize_chat: 'چیٹ کا سائز تبدیل کریں',\n scroll_to_bottom: 'نیچے تک اسکرول کریں',\n thinking: 'سوچ رہا ہے…',\n running: 'جاری ہے…',\n steps: 'مراحل',\n step_arguments: 'آرگیومنٹس',\n step_result: 'نتیجہ',\n attach_files:\n 'تصاویر، ویڈیوز، PDF یا اسپریڈشیٹس منسلک کریں (زیادہ سے زیادہ حجم 25 MB)',\n mark_page_active:\n 'نشان لگانے کے لیے صفحے پر کسی چیز پر کلک کریں — منسوخ کرنے کے لیے Esc دبائیں',\n mark_page: 'صفحے پر کسی چیز کے بارے میں پوچھنے کے لیے اس پر نشان لگائیں',\n stop_response: 'جواب روکیں',\n copy_reply: 'جواب کاپی کریں',\n mentions_empty: 'کوئی مماثلت نہیں',\n copied: 'کاپی ہو گیا',\n send_message: 'پیغام بھیجیں',\n upload_failed: 'اپ لوڈ ناکام: {error}',\n remove_attachment: 'منسلکہ ہٹائیں',\n json_no_items: 'کوئی آئٹم نہیں',\n json_no_data: 'کوئی ڈیٹا نہیں',\n json_no_chart_data: 'چارٹ کے لیے کوئی ڈیٹا نہیں',\n json_unsupported: 'تعاون یافتہ نہیں: {type}',\n json_see_less: 'کم دیکھیں',\n json_phone_agent: 'فون ایجنٹ',\n json_phone_agent_test: 'ویب کے ذریعے آزمائیں',\n page_context_remove: 'صفحے کا سیاق ہٹائیں',\n json_see_more: 'مزید {count} دیکھیں',\n queued_label: '{count} قطار میں',\n remove_queued_message: 'پیغام کو قطار سے ہٹائیں',\n send_queued_now: 'قطار میں موجود پیغامات ابھی بھیجیں',\n turn_failed_message: 'کچھ غلط ہو گیا اور جواب موصول نہیں ہوا۔',\n turn_failed_retry: 'دوبارہ کوشش کریں',\n page_mark_hint: 'نشان لگانے کے لیے کسی چیز پر کلک کریں',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'خانہ',\n page_mark_shape_circle: 'دائرہ',\n page_mark_shape_arrow: 'تیر',\n page_mark_shape_bracket: 'قوس',\n page_mark_shape_underline: 'خط کشیدہ',\n page_mark_shape_highlight: 'نمایاں',\n page_mark_shape_strike_through: 'کاٹنے کی لکیر',\n page_mark_shape_crossed_off: 'ضرب کا نشان',\n page_mark_shape_aria: 'نشان کی شکل: {shape}',\n page_mark_note_placeholder: 'نوٹ شامل کریں… (منسلک کرنے کے لیے Enter دبائیں)',\n page_mark_attach: 'نشان منسلک کریں',\n page_mark_remove: '{label} ہٹائیں',\n page_mark_region: 'نشان زدہ علاقہ',\n page_mark_default_message: 'یہ کیا ہے؟',\n file_rejected: 'فائل کی قسم تعاون یافتہ نہیں ہے یا فائل بہت بڑی ہے۔',\n dictate: 'بول کر لکھیں',\n stop_dictation: 'ڈکٹیشن روکیں',\n dictation_mic_blocked: 'بول کر لکھنے کے لیے مائیکروفون تک رسائی کی اجازت دیں',\n dictation_unavailable: 'ڈکٹیشن اس وقت دستیاب نہیں ہے',\n questions_back: 'واپس',\n questions_next: 'اگلا',\n questions_send: 'بھیجیں',\n questions_type_answer: 'میں خود لکھوں گا',\n questions_answer_placeholder: 'اپنا جواب لکھیں…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const VietnameseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Viết tin nhắn...',\n your_issue_has_been_resolved: 'Vấn đề của bạn đã được giải quyết!',\n new_conversation: 'Cuộc trò chuyện mới',\n welcome_screen_title: 'Chào mừng đến với hỗ trợ trò chuyện của chúng tôi',\n welcome_screen_description:\n 'Chúng tôi ở đây để giúp đỡ! Bắt đầu cuộc trò chuyện và chúng tôi sẽ phản hồi sớm nhất có thể.',\n your_name_placeholder: 'Tên của bạn',\n your_email_placeholder: 'Địa chỉ email của bạn',\n start_chat_button: 'Liên hệ hỗ trợ',\n start_chat_button_loading: 'Đang kết nối...',\n i_need_more_help: 'Tôi cần thêm trợ giúp',\n this_was_helpful: 'Điều này hữu ích',\n optional: 'Tùy chọn',\n no_conversations_yet: 'Chưa có cuộc trò chuyện nào',\n back_to_conversations: 'Quay lại cuộc trò chuyện',\n closed_conversations: 'Cuộc trò chuyện đã đóng',\n csat_title: 'Cuộc trò chuyện của bạn thế nào?',\n csat_submitted_title: 'Bạn đã đánh giá cuộc trò chuyện là',\n csat_feedback_placeholder: 'Cho chúng tôi biết thêm... (tùy chọn)',\n follow_up_placeholder: 'Hỏi thêm…',\n companion_layout_label: 'Bố cục',\n companion_layout_floating: 'Nổi',\n companion_layout_sidebar: 'Thanh bên',\n companion_layout_fullscreen: 'Toàn màn hình',\n companion_close: 'Đóng',\n companion_history: 'Lịch sử trò chuyện',\n companion_expand_chat: 'Mở rộng cuộc trò chuyện',\n companion_sidebar_dock_label: 'Ghim',\n companion_sidebar_side_label: 'Phía',\n companion_sidebar_left: 'Trái',\n companion_sidebar_right: 'Phải',\n companion_resize_chat: 'Đổi kích thước cuộc trò chuyện',\n scroll_to_bottom: 'Cuộn xuống dưới cùng',\n thinking: 'Đang suy nghĩ…',\n running: 'Đang chạy…',\n steps: 'bước',\n step_arguments: 'Đối số',\n step_result: 'Kết quả',\n attach_files:\n 'Đính kèm hình ảnh, video, PDF hoặc bảng tính (kích thước tối đa 25 MB)',\n mark_page_active:\n 'Nhấp vào bất kỳ nội dung nào trên trang để đánh dấu — nhấn Esc để hủy',\n mark_page: 'Đánh dấu nội dung trên trang để hỏi về nội dung đó',\n stop_response: 'Dừng trả lời',\n copy_reply: 'Sao chép câu trả lời',\n mentions_empty: 'Không có kết quả',\n copied: 'Đã sao chép',\n send_message: 'Gửi tin nhắn',\n upload_failed: 'Tải lên không thành công: {error}',\n remove_attachment: 'Xóa tệp đính kèm',\n json_no_items: 'Không có mục nào',\n json_no_data: 'Không có dữ liệu',\n json_no_chart_data: 'Không có dữ liệu cho biểu đồ',\n json_unsupported: 'Không được hỗ trợ: {type}',\n json_see_less: 'Hiện ít hơn',\n json_phone_agent: 'Tổng đài viên',\n json_phone_agent_test: 'Thử qua web',\n page_context_remove: 'Xóa ngữ cảnh trang',\n json_see_more: 'Hiện thêm {count}',\n queued_label: '{count} Đang chờ',\n remove_queued_message: 'Xóa tin nhắn khỏi hàng đợi',\n send_queued_now: 'Gửi tin nhắn trong hàng đợi ngay',\n turn_failed_message: 'Đã xảy ra lỗi và không nhận được câu trả lời.',\n turn_failed_retry: 'Thử lại',\n page_mark_hint: 'Nhấp vào nội dung bất kỳ để đánh dấu',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Khung',\n page_mark_shape_circle: 'Hình tròn',\n page_mark_shape_arrow: 'Mũi tên',\n page_mark_shape_bracket: 'Ngoặc',\n page_mark_shape_underline: 'Gạch chân',\n page_mark_shape_highlight: 'Tô sáng',\n page_mark_shape_strike_through: 'Gạch ngang',\n page_mark_shape_crossed_off: 'Gạch chéo',\n page_mark_shape_aria: 'Hình dạng dấu: {shape}',\n page_mark_note_placeholder: 'Thêm ghi chú… (Enter để đính kèm)',\n page_mark_attach: 'Đính kèm dấu',\n page_mark_remove: 'Xóa {label}',\n page_mark_region: 'Vùng đã đánh dấu',\n page_mark_default_message: 'Đây là gì?',\n file_rejected: 'Loại tệp không được hỗ trợ hoặc tệp quá lớn.',\n dictate: 'Đọc để nhập',\n stop_dictation: 'Dừng đọc',\n dictation_mic_blocked: 'Cho phép truy cập micrô để đọc nhập',\n dictation_unavailable: 'Hiện không thể dùng tính năng đọc để nhập',\n questions_back: 'Quay lại',\n questions_next: 'Tiếp theo',\n questions_send: 'Gửi',\n questions_type_answer: 'Tôi sẽ tự nhập',\n questions_answer_placeholder: 'Nhập câu trả lời của bạn…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const ChineseSimplifiedLanguage: TranslationInterface = {\n write_a_message_placeholder: '写一条消息...',\n your_issue_has_been_resolved: '您的问题已解决!',\n new_conversation: '新对话',\n welcome_screen_title: '欢迎使用我们的客服聊天',\n welcome_screen_description:\n '我们随时为您提供帮助!开始对话,我们会尽快回复您。',\n your_name_placeholder: '您的姓名',\n your_email_placeholder: '您的电子邮件地址',\n start_chat_button: '联系客服',\n start_chat_button_loading: '连接中...',\n i_need_more_help: '我需要更多帮助',\n this_was_helpful: '这很有帮助',\n optional: '可选',\n no_conversations_yet: '暂无对话',\n back_to_conversations: '返回对话',\n closed_conversations: '已关闭的对话',\n csat_title: '您的对话感觉如何?',\n csat_submitted_title: '您将此对话评价为',\n csat_feedback_placeholder: '告诉我们更多...(可选)',\n follow_up_placeholder: '继续提问…',\n companion_layout_label: '布局',\n companion_layout_floating: '浮动',\n companion_layout_sidebar: '侧边栏',\n companion_layout_fullscreen: '全屏',\n companion_close: '关闭',\n companion_history: '对话历史',\n companion_expand_chat: '展开聊天',\n companion_sidebar_dock_label: '停靠',\n companion_sidebar_side_label: '位置',\n companion_sidebar_left: '左侧',\n companion_sidebar_right: '右侧',\n companion_resize_chat: '调整聊天大小',\n scroll_to_bottom: '滚动到底部',\n thinking: '思考中…',\n running: '运行中…',\n steps: '步骤',\n step_arguments: '参数',\n step_result: '结果',\n attach_files: '附加图片、视频、PDF 或电子表格(最大 25 MB)',\n mark_page_active: '点击页面上的任意内容进行标记 — 按 Esc 取消',\n mark_page: '标记页面上的内容以便就此提问',\n stop_response: '停止回答',\n copy_reply: '复制回复',\n mentions_empty: '没有匹配项',\n copied: '已复制',\n send_message: '发送消息',\n upload_failed: '上传失败:{error}',\n remove_attachment: '移除附件',\n json_no_items: '没有项目',\n json_no_data: '没有数据',\n json_no_chart_data: '没有可用于图表的数据',\n json_unsupported: '不支持:{type}',\n json_see_less: '收起',\n json_phone_agent: '电话客服',\n json_phone_agent_test: '通过网页测试',\n page_context_remove: '移除页面上下文',\n json_see_more: '再显示 {count} 项',\n queued_label: '{count} 排队中',\n remove_queued_message: '从队列中移除消息',\n send_queued_now: '立即发送队列中的消息',\n turn_failed_message: '出现问题,未收到回答。',\n turn_failed_retry: '重试',\n page_mark_hint: '点击任意内容进行标记',\n page_mark_escape: 'Esc',\n page_mark_shape_box: '方框',\n page_mark_shape_circle: '圆形',\n page_mark_shape_arrow: '箭头',\n page_mark_shape_bracket: '括号',\n page_mark_shape_underline: '下划线',\n page_mark_shape_highlight: '高亮',\n page_mark_shape_strike_through: '删除线',\n page_mark_shape_crossed_off: '叉号',\n page_mark_shape_aria: '标记形状:{shape}',\n page_mark_note_placeholder: '添加备注…(按 Enter 附加)',\n page_mark_attach: '附加标记',\n page_mark_remove: '移除{label}',\n page_mark_region: '已标记区域',\n page_mark_default_message: '这是什么?',\n file_rejected: '不支持该文件类型,或文件过大。',\n dictate: '语音输入',\n stop_dictation: '停止语音输入',\n dictation_mic_blocked: '请允许访问麦克风以使用语音输入',\n dictation_unavailable: '语音输入暂时不可用',\n questions_back: '返回',\n questions_next: '下一步',\n questions_send: '发送',\n questions_type_answer: '我自己输入',\n questions_answer_placeholder: '输入你的回答…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const CroatianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napišite poruku...',\n your_issue_has_been_resolved: 'Vaš problem je riješen!',\n new_conversation: 'Novi razgovor',\n welcome_screen_title: 'Dobrodošli u naš chat za podršku',\n welcome_screen_description:\n 'Ovdje smo da pomognemo! Započnite razgovor i odgovorit ćemo vam što je prije moguće.',\n your_name_placeholder: 'Vaše ime',\n your_email_placeholder: 'Vaša e-mail adresa',\n start_chat_button: 'Razgovarajte s podrškom',\n start_chat_button_loading: 'Povezivanje...',\n i_need_more_help: 'Trebam dodatnu pomoć',\n this_was_helpful: 'Ovo je bilo korisno',\n optional: 'Neobavezno',\n no_conversations_yet: 'Još nema razgovora',\n back_to_conversations: 'Natrag na razgovore',\n closed_conversations: 'Zatvoreni razgovori',\n csat_title: 'Kakav je bio vaš razgovor?',\n csat_submitted_title: 'Ocijenili ste razgovor kao',\n csat_feedback_placeholder: 'Recite nam više... (neobavezno)',\n follow_up_placeholder: 'Nastavite…',\n companion_layout_label: 'Raspored',\n companion_layout_floating: 'Plutajući',\n companion_layout_sidebar: 'Bočna traka',\n companion_layout_fullscreen: 'Cijeli zaslon',\n companion_close: 'Zatvori',\n companion_history: 'Povijest razgovora',\n companion_expand_chat: 'Proširi razgovor',\n companion_sidebar_dock_label: 'Usidravanje',\n companion_sidebar_side_label: 'Strana',\n companion_sidebar_left: 'Lijevo',\n companion_sidebar_right: 'Desno',\n companion_resize_chat: 'Promijeni veličinu razgovora',\n scroll_to_bottom: 'Pomakni se na dno',\n thinking: 'Razmišljam…',\n running: 'Izvršava se…',\n steps: 'koraci',\n step_arguments: 'Argumenti',\n step_result: 'Rezultat',\n attach_files:\n 'Priložite slike, videozapise, PDF-ove ili proračunske tablice (najveća veličina 25 MB)',\n mark_page_active:\n 'Kliknite bilo što na stranici da biste to označili — Esc za odustajanje',\n mark_page: 'Označite nešto na stranici da biste pitali o tome',\n stop_response: 'Zaustavi odgovor',\n copy_reply: 'Kopiraj odgovor',\n mentions_empty: 'Nema rezultata',\n copied: 'Kopirano',\n send_message: 'Pošalji poruku',\n upload_failed: 'Prijenos nije uspio: {error}',\n remove_attachment: 'Ukloni privitak',\n json_no_items: 'Nema stavki',\n json_no_data: 'Nema podataka',\n json_no_chart_data: 'Nema podataka za grafikon',\n json_unsupported: 'Nije podržano: {type}',\n json_see_less: 'Prikaži manje',\n json_phone_agent: 'Telefonski agent',\n json_phone_agent_test: 'Testiraj putem weba',\n page_context_remove: 'Ukloni kontekst stranice',\n json_see_more: 'Prikaži još {count}',\n queued_label: '{count} Na čekanju',\n remove_queued_message: 'Ukloni poruku iz reda čekanja',\n send_queued_now: 'Pošalji poruke iz reda čekanja sada',\n turn_failed_message: 'Nešto je pošlo po zlu i odgovor nije stigao.',\n turn_failed_retry: 'Pokušaj ponovno',\n page_mark_hint: 'Kliknite nešto da biste to označili',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Okvir',\n page_mark_shape_circle: 'Krug',\n page_mark_shape_arrow: 'Strelica',\n page_mark_shape_bracket: 'Zagrada',\n page_mark_shape_underline: 'Podcrtavanje',\n page_mark_shape_highlight: 'Isticanje',\n page_mark_shape_strike_through: 'Precrtavanje',\n page_mark_shape_crossed_off: 'Križno precrtavanje',\n page_mark_shape_aria: 'Oblik oznake: {shape}',\n page_mark_note_placeholder: 'Dodajte bilješku… (Enter za prilaganje)',\n page_mark_attach: 'Priloži oznaku',\n page_mark_remove: 'Ukloni {label}',\n page_mark_region: 'Označeno područje',\n page_mark_default_message: 'Što je ovo?',\n file_rejected: 'Vrsta datoteke nije podržana ili je datoteka prevelika.',\n dictate: 'Diktiraj',\n stop_dictation: 'Zaustavi diktiranje',\n dictation_mic_blocked: 'Dopustite pristup mikrofonu za diktiranje',\n dictation_unavailable: 'Diktiranje trenutačno nije dostupno',\n questions_back: 'Natrag',\n questions_next: 'Dalje',\n questions_send: 'Pošalji',\n questions_type_answer: 'Napisat ću sam',\n questions_answer_placeholder: 'Napišite svoj odgovor…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const EstonianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Kirjuta sõnum...',\n your_issue_has_been_resolved: 'Teie probleem on lahendatud!',\n new_conversation: 'Uus vestlus',\n welcome_screen_title: 'Tere tulemast meie tugiteenusesse',\n welcome_screen_description:\n 'Oleme siin, et aidata! Alustage vestlust ja vastame teile esimesel võimalusel.',\n your_name_placeholder: 'Teie nimi',\n your_email_placeholder: 'Teie e-posti aadress',\n start_chat_button: 'Räägi toega',\n start_chat_button_loading: 'Ühendamine...',\n i_need_more_help: 'Vajan rohkem abi',\n this_was_helpful: 'See oli kasulik',\n optional: 'Valikuline',\n no_conversations_yet: 'Vestlusi pole veel',\n back_to_conversations: 'Tagasi vestluste juurde',\n closed_conversations: 'Suletud vestlused',\n csat_title: 'Milline oli teie vestlus?',\n csat_submitted_title: 'Hindasite vestlust kui',\n csat_feedback_placeholder: 'Rääkige meile rohkem... (valikuline)',\n follow_up_placeholder: 'Küsi juurde…',\n companion_layout_label: 'Paigutus',\n companion_layout_floating: 'Hõljuv',\n companion_layout_sidebar: 'Külgriba',\n companion_layout_fullscreen: 'Täisekraan',\n companion_close: 'Sulge',\n companion_history: 'Vestluste ajalugu',\n companion_expand_chat: 'Laienda vestlust',\n companion_sidebar_dock_label: 'Dokk',\n companion_sidebar_side_label: 'Külg',\n companion_sidebar_left: 'Vasak',\n companion_sidebar_right: 'Parem',\n companion_resize_chat: 'Muuda vestluse suurust',\n scroll_to_bottom: 'Keri alla',\n thinking: 'Mõtlen…',\n running: 'Töötab…',\n steps: 'sammud',\n step_arguments: 'Argumendid',\n step_result: 'Tulemus',\n attach_files:\n 'Lisa pilte, videoid, PDF-e või arvutustabeleid (maksimaalne suurus 25 MB)',\n mark_page_active:\n 'Märkimiseks klõpsa lehel ükskõik millel — tühistamiseks vajuta Esc',\n mark_page: 'Märgi lehel midagi, et selle kohta küsida',\n stop_response: 'Peata vastus',\n copy_reply: 'Kopeeri vastus',\n mentions_empty: 'Vasteid pole',\n copied: 'Kopeeritud',\n send_message: 'Saada sõnum',\n upload_failed: 'Üleslaadimine nurjus: {error}',\n remove_attachment: 'Eemalda manus',\n json_no_items: 'Üksusi pole',\n json_no_data: 'Andmeid pole',\n json_no_chart_data: 'Diagrammi jaoks pole andmeid',\n json_unsupported: 'Pole toetatud: {type}',\n json_see_less: 'Näita vähem',\n json_phone_agent: 'Telefoniagent',\n json_phone_agent_test: 'Testi veebis',\n page_context_remove: 'Eemalda lehe kontekst',\n json_see_more: 'Näita veel {count}',\n queued_label: '{count} Järjekorras',\n remove_queued_message: 'Eemalda sõnum järjekorrast',\n send_queued_now: 'Saada järjekorras olevad sõnumid kohe',\n turn_failed_message: 'Midagi läks valesti ja vastus ei saabunud.',\n turn_failed_retry: 'Proovi uuesti',\n page_mark_hint: 'Märkimiseks klõpsa millelgi',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kast',\n page_mark_shape_circle: 'Ring',\n page_mark_shape_arrow: 'Nool',\n page_mark_shape_bracket: 'Sulg',\n page_mark_shape_underline: 'Allajoonimine',\n page_mark_shape_highlight: 'Esiletõst',\n page_mark_shape_strike_through: 'Läbikriipsutus',\n page_mark_shape_crossed_off: 'Ristiga maha tõmbamine',\n page_mark_shape_aria: 'Märke kuju: {shape}',\n page_mark_note_placeholder: 'Lisa märkus… (Enter lisamiseks)',\n page_mark_attach: 'Lisa märge',\n page_mark_remove: 'Eemalda {label}',\n page_mark_region: 'Märgitud ala',\n page_mark_default_message: 'Mis see on?',\n file_rejected: 'Failitüüpi ei toetata või fail on liiga suur.',\n dictate: 'Dikteeri',\n stop_dictation: 'Lõpeta dikteerimine',\n dictation_mic_blocked: 'Dikteerimiseks luba mikrofoni kasutamine',\n dictation_unavailable: 'Dikteerimine pole praegu saadaval',\n questions_back: 'Tagasi',\n questions_next: 'Edasi',\n questions_send: 'Saada',\n questions_type_answer: 'Kirjutan ise',\n questions_answer_placeholder: 'Kirjutage oma vastus…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const HungarianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Írjon üzenetet...',\n your_issue_has_been_resolved: 'A problémája megoldódott!',\n new_conversation: 'Új beszélgetés',\n welcome_screen_title: 'Üdvözöljük az ügyfélszolgálati chatünkön',\n welcome_screen_description:\n 'Azért vagyunk itt, hogy segítsünk! Kezdjen beszélgetést, és mihamarabb válaszolunk.',\n your_name_placeholder: 'Az Ön neve',\n your_email_placeholder: 'Az Ön e-mail címe',\n start_chat_button: 'Beszélgetés az ügyfélszolgálattal',\n start_chat_button_loading: 'Csatlakozás...',\n i_need_more_help: 'További segítségre van szükségem',\n this_was_helpful: 'Ez hasznos volt',\n optional: 'Opcionális',\n no_conversations_yet: 'Még nincsenek beszélgetések',\n back_to_conversations: 'Vissza a beszélgetésekhez',\n closed_conversations: 'Lezárt beszélgetések',\n csat_title: 'Milyen volt a beszélgetése?',\n csat_submitted_title: 'A beszélgetést így értékelte',\n csat_feedback_placeholder: 'Mondjon többet... (opcionális)',\n follow_up_placeholder: 'További kérdés…',\n companion_layout_label: 'Elrendezés',\n companion_layout_floating: 'Lebegő',\n companion_layout_sidebar: 'Oldalsáv',\n companion_layout_fullscreen: 'Teljes képernyő',\n companion_close: 'Bezárás',\n companion_history: 'Beszélgetési előzmények',\n companion_expand_chat: 'Csevegés kibontása',\n companion_sidebar_dock_label: 'Dokkolás',\n companion_sidebar_side_label: 'Oldal',\n companion_sidebar_left: 'Bal',\n companion_sidebar_right: 'Jobb',\n companion_resize_chat: 'Csevegés átméretezése',\n scroll_to_bottom: 'Görgetés az aljára',\n thinking: 'Gondolkodás…',\n running: 'Folyamatban…',\n steps: 'lépés',\n step_arguments: 'Argumentumok',\n step_result: 'Eredmény',\n attach_files:\n 'Képek, videók, PDF-ek vagy táblázatok csatolása (legfeljebb 25 MB)',\n mark_page_active:\n 'Kattintson valamire az oldalon a megjelöléséhez — Esc a megszakításhoz',\n mark_page: 'Jelöljön meg valamit az oldalon, hogy kérdezhessen róla',\n stop_response: 'Válasz leállítása',\n copy_reply: 'Válasz másolása',\n mentions_empty: 'Nincs találat',\n copied: 'Másolva',\n send_message: 'Üzenet küldése',\n upload_failed: 'A feltöltés sikertelen: {error}',\n remove_attachment: 'Melléklet eltávolítása',\n json_no_items: 'Nincsenek elemek',\n json_no_data: 'Nincs adat',\n json_no_chart_data: 'Nincs megjeleníthető diagramadat',\n json_unsupported: 'Nem támogatott: {type}',\n json_see_less: 'Kevesebb megjelenítése',\n json_phone_agent: 'Telefonos ügynök',\n json_phone_agent_test: 'Tesztelés weben',\n page_context_remove: 'Oldalkontextus eltávolítása',\n json_see_more: 'További {count} megjelenítése',\n queued_label: '{count} Várólistán',\n remove_queued_message: 'Üzenet eltávolítása a várólistáról',\n send_queued_now: 'Várólistán lévő üzenetek küldése most',\n turn_failed_message: 'Hiba történt, és a válasz nem érkezett meg.',\n turn_failed_retry: 'Próbálja újra',\n page_mark_hint: 'Kattintson valamire a megjelöléséhez',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Keret',\n page_mark_shape_circle: 'Kör',\n page_mark_shape_arrow: 'Nyíl',\n page_mark_shape_bracket: 'Zárójel',\n page_mark_shape_underline: 'Aláhúzás',\n page_mark_shape_highlight: 'Kiemelés',\n page_mark_shape_strike_through: 'Áthúzás',\n page_mark_shape_crossed_off: 'Keresztezett áthúzás',\n page_mark_shape_aria: 'Jelölés alakja: {shape}',\n page_mark_note_placeholder: 'Megjegyzés hozzáadása… (Enter a csatoláshoz)',\n page_mark_attach: 'Jelölés csatolása',\n page_mark_remove: '{label} eltávolítása',\n page_mark_region: 'Megjelölt terület',\n page_mark_default_message: 'Mi ez?',\n file_rejected: 'A fájltípus nem támogatott, vagy a fájl túl nagy.',\n dictate: 'Diktálás',\n stop_dictation: 'Diktálás leállítása',\n dictation_mic_blocked: 'A diktáláshoz engedélyezze a mikrofon használatát',\n dictation_unavailable: 'A diktálás jelenleg nem érhető el',\n questions_back: 'Vissza',\n questions_next: 'Tovább',\n questions_send: 'Küldés',\n questions_type_answer: 'Inkább leírom',\n questions_answer_placeholder: 'Írja le a válaszát…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const IcelandicLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skrifaðu skilaboð...',\n your_issue_has_been_resolved: 'Málið þitt hefur verið leyst!',\n new_conversation: 'Nýtt samtal',\n welcome_screen_title: 'Velkomin í þjónustuverið okkar',\n welcome_screen_description:\n 'Við erum hér til að hjálpa! Byrjaðu samtal og við munum svara eins fljótt og auðið er.',\n your_name_placeholder: 'Nafnið þitt',\n your_email_placeholder: 'Netfangið þitt',\n start_chat_button: 'Tala við þjónustuver',\n start_chat_button_loading: 'Tengist...',\n i_need_more_help: 'Ég þarf meiri hjálp',\n this_was_helpful: 'Þetta var gagnlegt',\n optional: 'Valfrjálst',\n no_conversations_yet: 'Engin samtöl ennþá',\n back_to_conversations: 'Til baka í samtöl',\n closed_conversations: 'Lokuð samtöl',\n csat_title: 'Hvernig var samtalið þitt?',\n csat_submitted_title: 'Þú gafst samtalinu einkunnina',\n csat_feedback_placeholder: 'Segðu okkur meira... (valfrjálst)',\n follow_up_placeholder: 'Spyrja nánar…',\n companion_layout_label: 'Útlit',\n companion_layout_floating: 'Fljótandi',\n companion_layout_sidebar: 'Hliðarstika',\n companion_layout_fullscreen: 'Allur skjárinn',\n companion_close: 'Loka',\n companion_history: 'Samtalaferill',\n companion_expand_chat: 'Stækka spjall',\n companion_sidebar_dock_label: 'Kví',\n companion_sidebar_side_label: 'Hlið',\n companion_sidebar_left: 'Vinstri',\n companion_sidebar_right: 'Hægri',\n companion_resize_chat: 'Breyta stærð spjalls',\n scroll_to_bottom: 'Fara neðst',\n thinking: 'Hugsa…',\n running: 'Í vinnslu…',\n steps: 'skref',\n step_arguments: 'Viðföng',\n step_result: 'Niðurstaða',\n attach_files:\n 'Hengja við myndir, myndskeið, PDF-skjöl eða töflureikna (hámarksstærð 25 MB)',\n mark_page_active:\n 'Smelltu á eitthvað á síðunni til að merkja það — Esc til að hætta við',\n mark_page: 'Merktu eitthvað á síðunni til að spyrja um það',\n stop_response: 'Stöðva svar',\n copy_reply: 'Afrita svar',\n mentions_empty: 'Engar niðurstöður',\n copied: 'Afritað',\n send_message: 'Senda skilaboð',\n upload_failed: 'Upphleðsla mistókst: {error}',\n remove_attachment: 'Fjarlægja viðhengi',\n json_no_items: 'Engin atriði',\n json_no_data: 'Engin gögn',\n json_no_chart_data: 'Engin gögn fyrir myndrit',\n json_unsupported: 'Ekki stutt: {type}',\n json_see_less: 'Sýna minna',\n json_phone_agent: 'Símafulltrúi',\n json_phone_agent_test: 'Prófa á vefnum',\n page_context_remove: 'Fjarlægja samhengi síðu',\n json_see_more: 'Sýna {count} í viðbót',\n queued_label: '{count} Í biðröð',\n remove_queued_message: 'Fjarlægja skilaboð úr biðröð',\n send_queued_now: 'Senda skilaboð í biðröð núna',\n turn_failed_message: 'Eitthvað fór úrskeiðis og svarið barst ekki.',\n turn_failed_retry: 'Reyna aftur',\n page_mark_hint: 'Smelltu á eitthvað til að merkja það',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rammi',\n page_mark_shape_circle: 'Hringur',\n page_mark_shape_arrow: 'Ör',\n page_mark_shape_bracket: 'Hornklofi',\n page_mark_shape_underline: 'Undirstrikun',\n page_mark_shape_highlight: 'Áherslulitun',\n page_mark_shape_strike_through: 'Yfirstrikun',\n page_mark_shape_crossed_off: 'Krossa yfir',\n page_mark_shape_aria: 'Lögun merkingar: {shape}',\n page_mark_note_placeholder: 'Bæta við athugasemd… (Enter til að hengja við)',\n page_mark_attach: 'Hengja merkingu við',\n page_mark_remove: 'Fjarlægja {label}',\n page_mark_region: 'Merkt svæði',\n page_mark_default_message: 'Hvað er þetta?',\n file_rejected: 'Skráargerðin er ekki studd eða skráin er of stór.',\n dictate: 'Lesa fyrir',\n stop_dictation: 'Hætta að lesa fyrir',\n dictation_mic_blocked: 'Leyfðu aðgang að hljóðnema til að lesa fyrir',\n dictation_unavailable: 'Fyrirlestur er ekki í boði núna',\n questions_back: 'Til baka',\n questions_next: 'Áfram',\n questions_send: 'Senda',\n questions_type_answer: 'Ég skrifa það',\n questions_answer_placeholder: 'Skrifaðu svarið þitt…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const LatvianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Rakstiet ziņojumu...',\n your_issue_has_been_resolved: 'Jūsu problēma ir atrisināta!',\n new_conversation: 'Jauna saruna',\n welcome_screen_title: 'Laipni lūdzam mūsu atbalsta tērzēšanā',\n welcome_screen_description:\n 'Mēs esam šeit, lai palīdzētu! Sāciet sarunu, un mēs jums atbildēsim pēc iespējas ātrāk.',\n your_name_placeholder: 'Jūsu vārds',\n your_email_placeholder: 'Jūsu e-pasta adrese',\n start_chat_button: 'Sazināties ar atbalstu',\n start_chat_button_loading: 'Savienošana...',\n i_need_more_help: 'Man vajag vairāk palīdzības',\n this_was_helpful: 'Tas bija noderīgi',\n optional: 'Neobligāts',\n no_conversations_yet: 'Pagaidām nav sarunu',\n back_to_conversations: 'Atpakaļ pie sarunām',\n closed_conversations: 'Slēgtās sarunas',\n csat_title: 'Kāda bija jūsu saruna?',\n csat_submitted_title: 'Jūs novērtējāt sarunu kā',\n csat_feedback_placeholder: 'Pastāstiet mums vairāk... (neobligāti)',\n follow_up_placeholder: 'Turpināt…',\n companion_layout_label: 'Izkārtojums',\n companion_layout_floating: 'Peldošs',\n companion_layout_sidebar: 'Sānjosla',\n companion_layout_fullscreen: 'Pilnekrāns',\n companion_close: 'Aizvērt',\n companion_history: 'Sarunu vēsture',\n companion_expand_chat: 'Izvērst tērzēšanu',\n companion_sidebar_dock_label: 'Piestiprināšana',\n companion_sidebar_side_label: 'Puse',\n companion_sidebar_left: 'Pa kreisi',\n companion_sidebar_right: 'Pa labi',\n companion_resize_chat: 'Mainīt tērzēšanas izmēru',\n scroll_to_bottom: 'Ritināt uz leju',\n thinking: 'Domāju…',\n running: 'Notiek izpilde…',\n steps: 'darbības',\n step_arguments: 'Argumenti',\n step_result: 'Rezultāts',\n attach_files:\n 'Pievienot attēlus, video, PDF vai izklājlapas (maksimālais izmērs 25 MB)',\n mark_page_active:\n 'Noklikšķiniet uz kaut kā lapā, lai to atzīmētu — Esc, lai atceltu',\n mark_page: 'Atzīmējiet kaut ko lapā, lai par to pajautātu',\n stop_response: 'Apturēt atbildi',\n copy_reply: 'Kopēt atbildi',\n mentions_empty: 'Nav atbilstību',\n copied: 'Nokopēts',\n send_message: 'Sūtīt ziņu',\n upload_failed: 'Augšupielāde neizdevās: {error}',\n remove_attachment: 'Noņemt pielikumu',\n json_no_items: 'Nav vienumu',\n json_no_data: 'Nav datu',\n json_no_chart_data: 'Diagrammai nav datu',\n json_unsupported: 'Nav atbalstīts: {type}',\n json_see_less: 'Rādīt mazāk',\n json_phone_agent: 'Tālruņa aģents',\n json_phone_agent_test: 'Testēt tīmeklī',\n page_context_remove: 'Noņemt lapas kontekstu',\n json_see_more: 'Rādīt vēl {count}',\n queued_label: '{count} Rindā',\n remove_queued_message: 'Noņemt ziņu no rindas',\n send_queued_now: 'Nosūtīt rindā esošās ziņas tūlīt',\n turn_failed_message: 'Radās problēma, un atbilde nepienāca.',\n turn_failed_retry: 'Mēģināt vēlreiz',\n page_mark_hint: 'Noklikšķiniet uz kaut kā, lai to atzīmētu',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rāmis',\n page_mark_shape_circle: 'Aplis',\n page_mark_shape_arrow: 'Bulta',\n page_mark_shape_bracket: 'Iekava',\n page_mark_shape_underline: 'Pasvītrojums',\n page_mark_shape_highlight: 'Izcēlums',\n page_mark_shape_strike_through: 'Pārsvītrojums',\n page_mark_shape_crossed_off: 'Krustenisks svītrojums',\n page_mark_shape_aria: 'Atzīmes forma: {shape}',\n page_mark_note_placeholder: 'Pievienot piezīmi… (Enter, lai pievienotu)',\n page_mark_attach: 'Pievienot atzīmi',\n page_mark_remove: 'Noņemt {label}',\n page_mark_region: 'Atzīmēts apgabals',\n page_mark_default_message: 'Kas tas ir?',\n file_rejected: 'Faila tips netiek atbalstīts vai fails ir pārāk liels.',\n dictate: 'Diktēt',\n stop_dictation: 'Pārtraukt diktēšanu',\n dictation_mic_blocked: 'Atļaujiet piekļuvi mikrofonam, lai diktētu',\n dictation_unavailable: 'Diktēšana pašlaik nav pieejama',\n questions_back: 'Atpakaļ',\n questions_next: 'Tālāk',\n questions_send: 'Sūtīt',\n questions_type_answer: 'Rakstīšu pats',\n questions_answer_placeholder: 'Ierakstiet savu atbildi…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const LithuanianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Parašykite žinutę...',\n your_issue_has_been_resolved: 'Jūsų problema išspręsta!',\n new_conversation: 'Naujas pokalbis',\n welcome_screen_title: 'Sveiki atvykę į mūsų pagalbos pokalbį',\n welcome_screen_description:\n 'Mes čia, kad padėtume! Pradėkite pokalbį ir mes atsakysime kuo greičiau.',\n your_name_placeholder: 'Jūsų vardas',\n your_email_placeholder: 'Jūsų el. pašto adresas',\n start_chat_button: 'Kalbėti su pagalba',\n start_chat_button_loading: 'Jungiamasi...',\n i_need_more_help: 'Man reikia daugiau pagalbos',\n this_was_helpful: 'Tai buvo naudinga',\n optional: 'Neprivaloma',\n no_conversations_yet: 'Pokalbių dar nėra',\n back_to_conversations: 'Grįžti į pokalbius',\n closed_conversations: 'Uždaryti pokalbiai',\n csat_title: 'Koks buvo jūsų pokalbis?',\n csat_submitted_title: 'Pokalbį įvertinote kaip',\n csat_feedback_placeholder: 'Papasakokite daugiau... (neprivaloma)',\n follow_up_placeholder: 'Tęsti…',\n companion_layout_label: 'Išdėstymas',\n companion_layout_floating: 'Slankusis',\n companion_layout_sidebar: 'Šoninė juosta',\n companion_layout_fullscreen: 'Visas ekranas',\n companion_close: 'Uždaryti',\n companion_history: 'Pokalbių istorija',\n companion_expand_chat: 'Išplėsti pokalbį',\n companion_sidebar_dock_label: 'Prijungimas',\n companion_sidebar_side_label: 'Pusė',\n companion_sidebar_left: 'Kairė',\n companion_sidebar_right: 'Dešinė',\n companion_resize_chat: 'Keisti pokalbio dydį',\n scroll_to_bottom: 'Slinkti į apačią',\n thinking: 'Galvoju…',\n running: 'Vykdoma…',\n steps: 'žingsniai',\n step_arguments: 'Argumentai',\n step_result: 'Rezultatas',\n attach_files:\n 'Pridėti vaizdus, vaizdo įrašus, PDF ar skaičiuokles (didžiausias dydis 25 MB)',\n mark_page_active:\n 'Spustelėkite ką nors puslapyje, kad pažymėtumėte — Esc atšaukti',\n mark_page: 'Pažymėkite ką nors puslapyje, kad galėtumėte apie tai paklausti',\n stop_response: 'Stabdyti atsakymą',\n copy_reply: 'Kopijuoti atsakymą',\n mentions_empty: 'Atitikmenų nėra',\n copied: 'Nukopijuota',\n send_message: 'Siųsti žinutę',\n upload_failed: 'Įkelti nepavyko: {error}',\n remove_attachment: 'Pašalinti priedą',\n json_no_items: 'Elementų nėra',\n json_no_data: 'Duomenų nėra',\n json_no_chart_data: 'Diagramai nėra duomenų',\n json_unsupported: 'Nepalaikoma: {type}',\n json_see_less: 'Rodyti mažiau',\n json_phone_agent: 'Telefono agentas',\n json_phone_agent_test: 'Išbandyti internete',\n page_context_remove: 'Pašalinti puslapio kontekstą',\n json_see_more: 'Rodyti dar {count}',\n queued_label: '{count} Eilėje',\n remove_queued_message: 'Pašalinti žinutę iš eilės',\n send_queued_now: 'Išsiųsti eilėje esančias žinutes dabar',\n turn_failed_message: 'Kažkas nutiko ir atsakymas neatėjo.',\n turn_failed_retry: 'Bandyti dar kartą',\n page_mark_hint: 'Spustelėkite ką nors, kad pažymėtumėte',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rėmelis',\n page_mark_shape_circle: 'Apskritimas',\n page_mark_shape_arrow: 'Rodyklė',\n page_mark_shape_bracket: 'Skliaustas',\n page_mark_shape_underline: 'Pabraukimas',\n page_mark_shape_highlight: 'Paryškinimas',\n page_mark_shape_strike_through: 'Perbraukimas',\n page_mark_shape_crossed_off: 'Kryžminis perbraukimas',\n page_mark_shape_aria: 'Žymėjimo forma: {shape}',\n page_mark_note_placeholder: 'Pridėti pastabą… (Enter pridėti)',\n page_mark_attach: 'Pridėti žymėjimą',\n page_mark_remove: 'Pašalinti {label}',\n page_mark_region: 'Pažymėta sritis',\n page_mark_default_message: 'Kas tai?',\n file_rejected: 'Failo tipas nepalaikomas arba failas per didelis.',\n dictate: 'Diktuoti',\n stop_dictation: 'Sustabdyti diktavimą',\n dictation_mic_blocked: 'Leiskite naudoti mikrofoną, kad galėtumėte diktuoti',\n dictation_unavailable: 'Diktavimas šiuo metu nepasiekiamas',\n questions_back: 'Atgal',\n questions_next: 'Toliau',\n questions_send: 'Siųsti',\n questions_type_answer: 'Parašysiu pats',\n questions_answer_placeholder: 'Parašykite savo atsakymą…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const LuxembourgishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Schreift eng Noriicht...',\n your_issue_has_been_resolved: 'Äert Problem gouf geléist!',\n new_conversation: 'Nei Konversatioun',\n welcome_screen_title: 'Wëllkomm bei eisem Support-Chat',\n welcome_screen_description:\n 'Mir sinn hei fir ze hëllefen! Start eng Konversatioun a mir äntweren Iech esou séier wéi méiglech.',\n your_name_placeholder: 'Ären Numm',\n your_email_placeholder: 'Är E-Mail-Adress',\n start_chat_button: 'Mat dem Support schwätzen',\n start_chat_button_loading: 'Verbindung...',\n i_need_more_help: 'Ech brauch méi Hëllef',\n this_was_helpful: 'Dat war hëllefräich',\n optional: 'Fakultativ',\n no_conversations_yet: 'Nach keng Konversatiounen',\n back_to_conversations: 'Zréck zu de Konversatiounen',\n closed_conversations: 'Zougemaachte Konversatiounen',\n csat_title: 'Wéi war Är Konversatioun?',\n csat_submitted_title: 'Dir hutt d’Konversatioun bewäert als',\n csat_feedback_placeholder: 'Sot eis méi... (fakultativ)',\n follow_up_placeholder: 'Nofroen…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Schwebend',\n companion_layout_sidebar: 'Säitleeschte',\n companion_layout_fullscreen: 'Vollbild',\n companion_close: 'Zoumaachen',\n companion_history: 'Gespréichsverlaf',\n companion_expand_chat: 'Chat ausklappen',\n companion_sidebar_dock_label: 'Andocken',\n companion_sidebar_side_label: 'Säit',\n companion_sidebar_left: 'Lénks',\n companion_sidebar_right: 'Riets',\n companion_resize_chat: 'Chatgréisst änneren',\n scroll_to_bottom: 'No ënne scrollen',\n thinking: 'Ech denken no…',\n running: 'Gëtt ausgefouert…',\n steps: 'Schrëtt',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Biller, Videoen, PDFen oder Tabelle bäifügen (maximal Gréisst 25 MB)',\n mark_page_active:\n 'Klickt op eppes op der Säit, fir et ze markéieren — Esc fir ofzebriechen',\n mark_page: 'Markéiert eppes op der Säit, fir doriwwer ze froen',\n stop_response: 'Äntwert stoppen',\n copy_reply: 'Äntwert kopéieren',\n mentions_empty: 'Keng Treffer',\n copied: 'Kopéiert',\n send_message: 'Noriicht schécken',\n upload_failed: 'Eroplueden net gelongen: {error}',\n remove_attachment: 'Unhang ewechhuelen',\n json_no_items: 'Keng Elementer',\n json_no_data: 'Keng Donnéeën',\n json_no_chart_data: \"Keng Donnéeë fir d'Diagramm\",\n json_unsupported: 'Net ënnerstëtzt: {type}',\n json_see_less: 'Manner weisen',\n json_phone_agent: 'Telefonsagent',\n json_phone_agent_test: 'Am Web testen',\n page_context_remove: 'Säitekontext ewechhuelen',\n json_see_more: '{count} weider weisen',\n queued_label: '{count} An der Waardeschlaang',\n remove_queued_message: 'Noriicht aus der Waardeschlaang ewechhuelen',\n send_queued_now: 'Noriichten aus der Waardeschlaang elo schécken',\n turn_failed_message: \"Eppes ass schifgaangen an d'Äntwert ass net ukomm.\",\n turn_failed_retry: 'Nach eng Kéier probéieren',\n page_mark_hint: 'Klickt op eppes, fir et ze markéieren',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Këscht',\n page_mark_shape_circle: 'Krees',\n page_mark_shape_arrow: 'Pfeil',\n page_mark_shape_bracket: 'Klammer',\n page_mark_shape_underline: 'Ënnersträichen',\n page_mark_shape_highlight: 'Markéieren',\n page_mark_shape_strike_through: 'Duerchsträichen',\n page_mark_shape_crossed_off: 'Duerchkräizen',\n page_mark_shape_aria: 'Form vun der Markéierung: {shape}',\n page_mark_note_placeholder: 'Notiz derbäisetzen… (Enter fir bäizefügen)',\n page_mark_attach: 'Markéierung bäifügen',\n page_mark_remove: '{label} ewechhuelen',\n page_mark_region: 'Markéierte Beräich',\n page_mark_default_message: 'Wat ass dat?',\n file_rejected:\n 'De Fichierstyp gëtt net ënnerstëtzt oder de Fichier ass ze grouss.',\n dictate: 'Diktéieren',\n stop_dictation: 'Diktat ophalen',\n dictation_mic_blocked: 'Erlaabt den Zougang zum Mikro fir ze diktéieren',\n dictation_unavailable: 'Diktéieren ass am Moment net verfügbar',\n questions_back: 'Zréck',\n questions_next: 'Weider',\n questions_send: 'Schécken',\n questions_type_answer: 'Ech schreiwen et selwer',\n questions_answer_placeholder: 'Schreift Är Äntwert…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const MalteseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Ikteb messaġġ...',\n your_issue_has_been_resolved: 'Il-problema tiegħek ġiet riżolta!',\n new_conversation: 'Konversazzjoni ġdida',\n welcome_screen_title: 'Merħba fis-support chat tagħna',\n welcome_screen_description:\n \"Aħna hawn biex ngħinu! Ibda konversazzjoni u nirrispondu malajr kemm jista' jkun.\",\n your_name_placeholder: 'Ismek',\n your_email_placeholder: 'L-indirizz tal-email tiegħek',\n start_chat_button: 'Kellem lis-support',\n start_chat_button_loading: 'Qed jikkonnettja...',\n i_need_more_help: 'Għandi bżonn aktar għajnuna',\n this_was_helpful: \"Dan kien ta' għajnuna\",\n optional: 'Mhux obbligatorju',\n no_conversations_yet: \"Għad m'hemmx konversazzjonijiet\",\n back_to_conversations: 'Lura għall-konversazzjonijiet',\n closed_conversations: 'Konversazzjonijiet magħluqa',\n csat_title: 'Kif kienet il-konversazzjoni tiegħek?',\n csat_submitted_title: 'Int ivvalutajt il-konversazzjoni bħala',\n csat_feedback_placeholder: 'Għidilna aktar... (mhux obbligatorju)',\n follow_up_placeholder: 'Kompli l-mistoqsija…',\n companion_layout_label: 'Tqassim',\n companion_layout_floating: 'Galleġġjanti',\n companion_layout_sidebar: 'Strixxa tal-ġenb',\n companion_layout_fullscreen: 'Skrin sħiħ',\n companion_close: 'Agħlaq',\n companion_history: 'Storja tal-konversazzjonijiet',\n companion_expand_chat: 'Kabbar iċ-chat',\n companion_sidebar_dock_label: 'Iddokkjar',\n companion_sidebar_side_label: 'Naħa',\n companion_sidebar_left: 'Xellug',\n companion_sidebar_right: 'Lemin',\n companion_resize_chat: 'Biddel id-daqs taċ-chat',\n scroll_to_bottom: 'Skrollja sal-qiegħ',\n thinking: 'Qed naħseb…',\n running: 'Qed jitħaddem…',\n steps: 'passi',\n step_arguments: 'Argumenti',\n step_result: 'Riżultat',\n attach_files:\n 'Ehmeż stampi, vidjows, PDFs jew spreadsheets (daqs massimu 25 MB)',\n mark_page_active:\n 'Ikklikkja xi ħaġa fil-paġna biex timmarkaha — Esc biex tikkanċella',\n mark_page: 'Immarka xi ħaġa fil-paġna biex tistaqsi dwarha',\n stop_response: 'Waqqaf it-tweġiba',\n copy_reply: 'Ikkopja t-tweġiba',\n mentions_empty: 'L-ebda riżultat',\n copied: 'Ikkupjat',\n send_message: 'Ibgħat messaġġ',\n upload_failed: 'It-tlugħ falla: {error}',\n remove_attachment: 'Neħħi s-sekwestru',\n json_no_items: 'L-ebda oġġett',\n json_no_data: 'L-ebda data',\n json_no_chart_data: 'L-ebda data għaċ-ċart',\n json_unsupported: 'Mhux appoġġjat: {type}',\n json_see_less: 'Ara inqas',\n json_phone_agent: 'Aġent tat-telefon',\n json_phone_agent_test: 'Ittestja fuq il-web',\n page_context_remove: 'Neħħi l-kuntest tal-paġna',\n json_see_more: 'Ara {count} oħra',\n queued_label: '{count} Fil-kju',\n remove_queued_message: 'Neħħi l-messaġġ mill-kju',\n send_queued_now: 'Ibgħat il-messaġġi fil-kju issa',\n turn_failed_message: 'Kien hemm problema u t-tweġiba ma waslitx.',\n turn_failed_retry: \"Erġa' pprova\",\n page_mark_hint: 'Ikklikkja xi ħaġa biex timmarkaha',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kaxxa',\n page_mark_shape_circle: 'Ċirku',\n page_mark_shape_arrow: 'Vleġġa',\n page_mark_shape_bracket: 'Parentesi',\n page_mark_shape_underline: 'Issottolinjar',\n page_mark_shape_highlight: 'Immarkar',\n page_mark_shape_strike_through: \"Qtugħ b'linja\",\n page_mark_shape_crossed_off: \"Qtugħ b'salib\",\n page_mark_shape_aria: 'Forma tal-marka: {shape}',\n page_mark_note_placeholder: 'Żid nota… (Enter biex tehmeż)',\n page_mark_attach: 'Ehmeż il-marka',\n page_mark_remove: 'Neħħi {label}',\n page_mark_region: 'Żona mmarkata',\n page_mark_default_message: 'X’inhu dan?',\n file_rejected:\n 'It-tip tal-fajl mhuwiex appoġġjat jew il-fajl huwa kbir wisq.',\n dictate: 'Iddetta',\n stop_dictation: 'Waqqaf id-dettatura',\n dictation_mic_blocked: 'Ippermetti l-aċċess għall-mikrofonu biex tiddetta',\n dictation_unavailable: 'Id-dettatura mhijiex disponibbli bħalissa',\n questions_back: 'Lura',\n questions_next: 'Li jmiss',\n questions_send: 'Ibgħat',\n questions_type_answer: 'Nikteb jien',\n questions_answer_placeholder: 'Ikteb it-tweġiba tiegħek…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const NorwegianBokmalLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv en melding...',\n your_issue_has_been_resolved: 'Saken din er løst!',\n new_conversation: 'Ny samtale',\n welcome_screen_title: 'Velkommen til vår kundestøtte',\n welcome_screen_description:\n 'Vi er her for å hjelpe! Start en samtale, så svarer vi deg så snart som mulig.',\n your_name_placeholder: 'Ditt navn',\n your_email_placeholder: 'Din e-postadresse',\n start_chat_button: 'Snakk med kundestøtte',\n start_chat_button_loading: 'Kobler til...',\n i_need_more_help: 'Jeg trenger mer hjelp',\n this_was_helpful: 'Dette var nyttig',\n optional: 'Valgfritt',\n no_conversations_yet: 'Ingen samtaler ennå',\n back_to_conversations: 'Tilbake til samtaler',\n closed_conversations: 'Lukkede samtaler',\n csat_title: 'Hvordan var samtalen din?',\n csat_submitted_title: 'Du vurderte samtalen som',\n csat_feedback_placeholder: 'Fortell oss mer... (valgfritt)',\n follow_up_placeholder: 'Følg opp…',\n companion_layout_label: 'Oppsett',\n companion_layout_floating: 'Flytende',\n companion_layout_sidebar: 'Sidepanel',\n companion_layout_fullscreen: 'Fullskjerm',\n companion_close: 'Lukk',\n companion_history: 'Samtalehistorikk',\n companion_expand_chat: 'Utvid chatten',\n companion_sidebar_dock_label: 'Dokking',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Venstre',\n companion_sidebar_right: 'Høyre',\n companion_resize_chat: 'Endre størrelsen på chatten',\n scroll_to_bottom: 'Rull til bunnen',\n thinking: 'Tenker…',\n running: 'Kjører…',\n steps: 'trinn',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Legg ved bilder, videoer, PDF-er eller regneark (maksimal størrelse 25 MB)',\n mark_page_active:\n 'Klikk på noe på siden for å markere det — Esc for å avbryte',\n mark_page: 'Marker noe på siden for å spørre om det',\n stop_response: 'Stopp svar',\n copy_reply: 'Kopier svar',\n mentions_empty: 'Ingen treff',\n copied: 'Kopiert',\n send_message: 'Send melding',\n upload_failed: 'Opplasting mislyktes: {error}',\n remove_attachment: 'Fjern vedlegg',\n json_no_items: 'Ingen elementer',\n json_no_data: 'Ingen data',\n json_no_chart_data: 'Ingen data for diagrammet',\n json_unsupported: 'Ikke støttet: {type}',\n json_see_less: 'Vis mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Test via nett',\n page_context_remove: 'Fjern sidekontekst',\n json_see_more: 'Vis {count} til',\n queued_label: '{count} I kø',\n remove_queued_message: 'Fjern meldingen fra køen',\n send_queued_now: 'Send meldinger i køen nå',\n turn_failed_message: 'Noe gikk galt, og svaret kom ikke fram.',\n turn_failed_retry: 'Prøv igjen',\n page_mark_hint: 'Klikk på noe for å markere det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ramme',\n page_mark_shape_circle: 'Sirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Klamme',\n page_mark_shape_underline: 'Understreking',\n page_mark_shape_highlight: 'Utheving',\n page_mark_shape_strike_through: 'Gjennomstreking',\n page_mark_shape_crossed_off: 'Kryss ut',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Legg til et notat… (Enter for å legge ved)',\n page_mark_attach: 'Legg ved markering',\n page_mark_remove: 'Fjern {label}',\n page_mark_region: 'Markert område',\n page_mark_default_message: 'Hva er dette?',\n file_rejected: 'Filtypen støttes ikke, eller filen er for stor.',\n dictate: 'Dikter',\n stop_dictation: 'Stopp diktering',\n dictation_mic_blocked: 'Tillat mikrofontilgang for å diktere',\n dictation_unavailable: 'Diktering er ikke tilgjengelig akkurat nå',\n questions_back: 'Tilbake',\n questions_next: 'Neste',\n questions_send: 'Send',\n questions_type_answer: 'Jeg skriver det selv',\n questions_answer_placeholder: 'Skriv svaret ditt…',\n};\n","import type { TranslationInterface } from '.';\n\nexport const SlovakLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napíšte správu...',\n your_issue_has_been_resolved: 'Váš problém bol vyriešený!',\n new_conversation: 'Nová konverzácia',\n welcome_screen_title: 'Vitajte v našom zákazníckom chate',\n welcome_screen_description:\n 'Sme tu, aby sme vám pomohli! Začnite konverzáciu a odpovieme vám čo najskôr.',\n your_name_placeholder: 'Vaše meno',\n your_email_placeholder: 'Vaša e-mailová adresa',\n start_chat_button: 'Hovoriť s podporou',\n start_chat_button_loading: 'Pripájanie...',\n i_need_more_help: 'Potrebujem ďalšiu pomoc',\n this_was_helpful: 'Toto bolo užitočné',\n optional: 'Voliteľné',\n no_conversations_yet: 'Zatiaľ žiadne konverzácie',\n back_to_conversations: 'Späť na konverzácie',\n closed_conversations: 'Uzavreté konverzácie',\n csat_title: 'Aká bola vaša konverzácia?',\n csat_submitted_title: 'Konverzáciu ste ohodnotili ako',\n csat_feedback_placeholder: 'Povedzte nám viac... (nepovinné)',\n follow_up_placeholder: 'Pokračovať…',\n companion_layout_label: 'Rozloženie',\n companion_layout_floating: 'Plávajúce',\n companion_layout_sidebar: 'Bočný panel',\n companion_layout_fullscreen: 'Celá obrazovka',\n companion_close: 'Zavrieť',\n companion_history: 'História konverzácií',\n companion_expand_chat: 'Rozbaliť chat',\n companion_sidebar_dock_label: 'Ukotvenie',\n companion_sidebar_side_label: 'Strana',\n companion_sidebar_left: 'Vľavo',\n companion_sidebar_right: 'Vpravo',\n companion_resize_chat: 'Zmeniť veľkosť chatu',\n scroll_to_bottom: 'Posunúť nadol',\n thinking: 'Premýšľam…',\n running: 'Prebieha…',\n steps: 'kroky',\n step_arguments: 'Argumenty',\n step_result: 'Výsledok',\n attach_files:\n 'Priložiť obrázky, videá, PDF súbory alebo tabuľky (maximálna veľkosť 25 MB)',\n mark_page_active:\n 'Kliknutím na čokoľvek na stránke to označíte — klávesom Esc akciu zrušíte',\n mark_page: 'Označte niečo na stránke a opýtajte sa na to',\n stop_response: 'Zastaviť odpoveď',\n copy_reply: 'Kopírovať odpoveď',\n mentions_empty: 'Žiadne zhody',\n copied: 'Skopírované',\n send_message: 'Odoslať správu',\n upload_failed: 'Nahrávanie zlyhalo: {error}',\n remove_attachment: 'Odstrániť prílohu',\n json_no_items: 'Žiadne položky',\n json_no_data: 'Žiadne údaje',\n json_no_chart_data: 'Žiadne údaje pre graf',\n json_unsupported: 'Nepodporované: {type}',\n json_see_less: 'Zobraziť menej',\n json_phone_agent: 'Telefónny agent',\n json_phone_agent_test: 'Vyskúšať na webe',\n page_context_remove: 'Odstrániť kontext stránky',\n json_see_more: 'Zobraziť ďalších {count}',\n queued_label: '{count} Vo fronte',\n remove_queued_message: 'Odstrániť správu z frontu',\n send_queued_now: 'Odoslať správy vo fronte teraz',\n turn_failed_message: 'Niečo sa pokazilo a odpoveď neprišla.',\n turn_failed_retry: 'Skúsiť znova',\n page_mark_hint: 'Kliknutím na čokoľvek to označíte',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rámček',\n page_mark_shape_circle: 'Kruh',\n page_mark_shape_arrow: 'Šípka',\n page_mark_shape_bracket: 'Zátvorka',\n page_mark_shape_underline: 'Podčiarknutie',\n page_mark_shape_highlight: 'Zvýraznenie',\n page_mark_shape_strike_through: 'Prečiarknutie',\n page_mark_shape_crossed_off: 'Krížové prečiarknutie',\n page_mark_shape_aria: 'Tvar označenia: {shape}',\n page_mark_note_placeholder: 'Pridať poznámku… (Enter na priloženie)',\n page_mark_attach: 'Priložiť označenie',\n page_mark_remove: 'Odstrániť {label}',\n page_mark_region: 'Označená oblasť',\n page_mark_default_message: 'Čo je to?',\n file_rejected: 'Typ súboru nie je podporovaný alebo je súbor príliš veľký.',\n dictate: 'Diktovať',\n stop_dictation: 'Zastaviť diktovanie',\n dictation_mic_blocked: 'Na diktovanie povoľte prístup k mikrofónu',\n dictation_unavailable: 'Diktovanie momentálne nie je k dispozícii',\n questions_back: 'Späť',\n questions_next: 'Ďalej',\n questions_send: 'Odoslať',\n questions_type_answer: 'Napíšem to sám',\n questions_answer_placeholder: 'Napíšte svoju odpoveď…',\n};\n","import type { WidgetConfig } from '../types/widget-config';\nimport { ArabicLanguage } from './ar';\nimport { BengaliLanguage } from './bn';\nimport { BulgarianLanguage } from './bg';\nimport { CzechLanguage } from './cs';\nimport { DanishLanguage } from './da';\nimport { GreekLanguage } from './el';\nimport { GermanLanguage } from './de';\nimport { EnglishLanguage } from './en';\nimport { SpanishLanguage } from './es';\nimport { FilipinoLanguage } from './fil';\nimport { FinnishLanguage } from './fi';\nimport { FrenchLanguage } from './fr';\nimport { HindiLanguage } from './hi';\nimport { ItalianLanguage } from './it';\nimport { JapaneseLanguage } from './ja';\nimport { KoreanLanguage } from './ko';\nimport { DutchLanguage } from './nl';\nimport { NorwegianLanguage } from './no';\nimport { PolishLanguage } from './pl';\nimport { PortugueseLanguage } from './pt';\nimport { RomanianLanguage } from './ro';\nimport { SwedishLanguage } from './sv';\nimport { RussianLanguage } from './ru';\nimport { ThaiLanguage } from './th';\nimport { TurkishLanguage } from './tr';\nimport { UrduLanguage } from './ur';\nimport { VietnameseLanguage } from './vi';\nimport { ChineseSimplifiedLanguage } from './zh-cn';\nimport { CroatianLanguage } from './hr';\nimport { EstonianLanguage } from './et';\nimport { HungarianLanguage } from './hu';\nimport { IcelandicLanguage } from './is';\nimport { LatvianLanguage } from './lv';\nimport { LithuanianLanguage } from './lt';\nimport { LuxembourgishLanguage } from './lb';\nimport { MalteseLanguage } from './mt';\nimport { NorwegianBokmalLanguage } from './nb';\nimport { SlovakLanguage } from './sk';\n\nconst languages = {\n ar: ArabicLanguage,\n bn: BengaliLanguage,\n bg: BulgarianLanguage,\n cs: CzechLanguage,\n da: DanishLanguage,\n de: GermanLanguage,\n el: GreekLanguage,\n en: EnglishLanguage,\n es: SpanishLanguage,\n et: EstonianLanguage,\n fi: FinnishLanguage,\n fil: FilipinoLanguage,\n fr: FrenchLanguage,\n hi: HindiLanguage,\n hr: CroatianLanguage,\n hu: HungarianLanguage,\n is: IcelandicLanguage,\n it: ItalianLanguage,\n ja: JapaneseLanguage,\n ko: KoreanLanguage,\n lb: LuxembourgishLanguage,\n lt: LithuanianLanguage,\n lv: LatvianLanguage,\n mt: MalteseLanguage,\n nb: NorwegianBokmalLanguage,\n nl: DutchLanguage,\n no: NorwegianLanguage,\n pl: PolishLanguage,\n pt: PortugueseLanguage,\n ro: RomanianLanguage,\n ru: RussianLanguage,\n sk: SlovakLanguage,\n sv: SwedishLanguage,\n th: ThaiLanguage,\n tr: TurkishLanguage,\n ur: UrduLanguage,\n vi: VietnameseLanguage,\n 'zh-cn': ChineseSimplifiedLanguage,\n} as const;\n\nexport const LANGUAGES = Object.keys(languages) as (keyof typeof languages)[];\nexport type Language = (typeof LANGUAGES)[number];\n\nexport function isSupportedLanguage(\n lang: string | null | undefined,\n): lang is Language {\n return LANGUAGES.includes(lang as Language);\n}\n\n/** Languages written right-to-left; the widget flips its layout for them. */\nconst RTL_LANGUAGES: ReadonlySet<Language> = new Set<Language>(['ar', 'ur']);\n\nexport function isRtlLanguage(lang: Language): boolean {\n return RTL_LANGUAGES.has(lang);\n}\n\n/** The language the widget renders in: `config.language` when supported, else English. */\nexport function resolveLanguage(lang: string | null | undefined): Language {\n return isSupportedLanguage(lang) ? lang : 'en';\n}\n\nexport function getTranslation(\n key: TranslationKeyU,\n lang: Language,\n overrides: WidgetConfig['translationOverrides'],\n params?: Record<string, string | number>,\n): string {\n const text =\n overrides?.[lang]?.[key] ||\n languages[lang][key] ||\n EnglishLanguage[key] ||\n key;\n if (!params) return text;\n return text.replace(/\\{(\\w+)\\}/g, (match, name: string) =>\n name in params ? String(params[name]) : match,\n );\n}\n\n/** `getTranslation` for code that holds the config rather than a language. */\nexport function translate(\n config: Pick<WidgetConfig, 'language' | 'translationOverrides'>,\n key: TranslationKeyU,\n params?: Record<string, string | number>,\n): string {\n return getTranslation(\n key,\n resolveLanguage(config.language),\n config.translationOverrides,\n params,\n );\n}\n\nexport type TranslationInterface = {\n i_need_more_help: string;\n this_was_helpful: string;\n write_a_message_placeholder: string;\n your_issue_has_been_resolved: string;\n new_conversation: string;\n back_to_conversations: string;\n closed_conversations: string;\n no_conversations_yet: string;\n welcome_screen_title: string;\n welcome_screen_description: string;\n your_name_placeholder: string;\n your_email_placeholder: string;\n optional: string;\n start_chat_button: string;\n start_chat_button_loading: string;\n csat_title: string;\n csat_submitted_title: string;\n csat_feedback_placeholder: string;\n follow_up_placeholder: string;\n companion_layout_label: string;\n companion_layout_floating: string;\n companion_layout_sidebar: string;\n companion_layout_fullscreen: string;\n companion_close: string;\n companion_close_chat?: string;\n companion_history: string;\n companion_switch_chat?: string;\n companion_viewing?: string;\n companion_working?: string;\n companion_open?: string;\n companion_closed?: string;\n companion_draft?: string;\n companion_chats?: string;\n companion_chat_number?: string;\n companion_active_chats?: string;\n companion_other_sessions?: string;\n companion_working_chats?: string;\n companion_expand_chat: string;\n companion_sidebar_dock_label: string;\n companion_sidebar_side_label: string;\n companion_sidebar_left: string;\n companion_sidebar_right: string;\n companion_resize_chat: string;\n scroll_to_bottom: string;\n thinking: string;\n running: string;\n steps: string;\n step_arguments: string;\n step_result: string;\n attach_files: string;\n mark_page_active: string;\n mark_page: string;\n stop_response: string;\n copy_reply: string;\n mentions_empty: string;\n copied: string;\n dictate: string;\n stop_dictation: string;\n dictation_mic_blocked: string;\n dictation_unavailable: string;\n send_message: string;\n upload_failed: string;\n file_rejected: string;\n remove_attachment: string;\n json_no_items: string;\n json_no_data: string;\n json_no_chart_data: string;\n json_unsupported: string;\n json_see_less: string;\n /** Subtitle of a tool-built phone-agent card. */\n json_phone_agent: string;\n /** The phone-agent card's action, completed by the host page. */\n json_phone_agent_test: string;\n /** Dismisses the composer's page-context (entity) pill for one message. */\n page_context_remove: string;\n json_see_more: string;\n page_mark_hint: string;\n page_mark_escape: string;\n page_mark_shape_box: string;\n page_mark_shape_circle: string;\n page_mark_shape_arrow: string;\n page_mark_shape_bracket: string;\n page_mark_shape_underline: string;\n page_mark_shape_highlight: string;\n page_mark_shape_strike_through: string;\n page_mark_shape_crossed_off: string;\n page_mark_shape_aria: string;\n page_mark_note_placeholder: string;\n page_mark_attach: string;\n page_mark_remove: string;\n page_mark_region: string;\n page_mark_default_message: string;\n /** Header of the multi-send queue pill above the composer. */\n queued_label: string;\n /** Accessible label of the per-message remove button in the queue pill. */\n remove_queued_message: string;\n send_queued_now: string;\n /** Body of the error row shown when an agent turn failed to arrive. */\n turn_failed_message: string;\n /** Retry action in the failed-turn error row. */\n turn_failed_retry: string;\n /** Previous question in the agent's clarification card. */\n questions_back: string;\n /** Next question in the agent's clarification card. */\n questions_next: string;\n /** Submits every answer of the clarification card as one message. */\n questions_send: string;\n /** Escape from the offered chips into a free-text answer. */\n questions_type_answer: string;\n /** Placeholder of that free-text answer box. */\n questions_answer_placeholder: string;\n};\nexport type TranslationKeyU = keyof TranslationInterface;\n","import type { ApiCaller } from '../api/api-caller';\nimport type { Dto } from '../api/client';\nimport type { CreateSessionDto, SessionDto } from '../types/dtos';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { Poller } from '../utils/Poller';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport { runCatching } from '../utils/run-catching';\nimport type { ContactCtx } from './contact.ctx';\nimport type { StorageCtx } from './storage.ctx';\nimport { log } from '../utils/log';\n\ntype SessionState = {\n /**\n * The currently selected session.\n * Can be null if no session is selected, or if in chat screen and the session is not created yet.\n */\n session: SessionDto | null;\n isCreatingSession: boolean;\n isResolvingSession: boolean;\n};\ntype SessionsState = {\n /** List of all user sessions */\n data: SessionDto[];\n /** A cursor to get the next page of sessions */\n cursor: string | undefined;\n /** Indicates if no more pages are left */\n isLastPage: boolean;\n /** Did fetch for the first time */\n didStartInitialFetch: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class SessionCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private storageCtx?: StorageCtx;\n private sessionsPollingIntervalSeconds: number;\n private sessionsRefresher = new Poller();\n /** The session id currently written to storage (null = none written). */\n private persistedSessionId: string | null = null;\n private stopPersistingSession?: () => void;\n private sessionAbortController = new AbortController();\n\n public sessionState = new PrimitiveState<SessionState>({\n session: null,\n isCreatingSession: false,\n isResolvingSession: false,\n });\n public sessionsState = new PrimitiveState<SessionsState>({\n data: [],\n cursor: undefined,\n isLastPage: false,\n didStartInitialFetch: false,\n /**\n * Initialize this as `true` so it always starts loading until the first fetch is done\n */\n isInitialFetchLoading: true,\n });\n\n constructor({\n config,\n api,\n contactCtx,\n storageCtx,\n sessionsPollingIntervalSeconds,\n sharedSessions,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n contactCtx: ContactCtx;\n storageCtx?: StorageCtx;\n sessionsPollingIntervalSeconds: number;\n sharedSessions?: PrimitiveState<SessionsState>;\n }) {\n this.config = config;\n this.api = api;\n this.contactCtx = contactCtx;\n this.storageCtx = storageCtx;\n this.sessionsPollingIntervalSeconds = sessionsPollingIntervalSeconds;\n\n if (sharedSessions) this.sessionsState = sharedSessions;\n else this.registerSessionsRefresherWrapper();\n this.registerActiveSessionPersistence();\n }\n\n /**\n * Remember which conversation the visitor is in, so a page reload can put\n * them back into it (`RouterCtx` does the restoring). Only OPEN sessions are\n * remembered — a closed one would reopen as a dead transcript — and the\n * pointer is dropped the moment the visitor leaves for a new chat.\n *\n * The boot value is deliberately NOT written: `subscribe` fires on changes\n * only, and clearing on a null we never set would wipe the pointer the\n * restore is about to read.\n */\n private registerActiveSessionPersistence = () => {\n const storageCtx = this.storageCtx;\n if (!storageCtx) return;\n this.stopPersistingSession = this.sessionState.subscribe(\n this.persistSession,\n );\n };\n\n /** Return persistence to the owning widget without overwriting its saved selection. */\n restoreActiveSessionTracking = () => {\n this.stopPersistingSession?.();\n this.stopPersistingSession = undefined;\n this.registerActiveSessionPersistence();\n };\n\n /** Persistence belongs to the selected conversation, never a background response. */\n trackActiveSession = (active: SessionCtx) => {\n this.stopPersistingSession?.();\n this.stopPersistingSession = active.sessionState.subscribe(\n this.persistSession,\n );\n this.persistSession(active.sessionState.get());\n };\n\n private persistSession = ({ session }: SessionState) => {\n const storageCtx = this.storageCtx;\n if (!storageCtx) return;\n const openSessionId = session?.isOpened ? session.id : null;\n if (openSessionId === this.persistedSessionId) return;\n // Nothing to forget until something was remembered.\n if (!openSessionId && this.persistedSessionId === null) return;\n this.persistedSessionId = openSessionId;\n const write = openSessionId\n ? storageCtx.setActiveSessionId(openSessionId)\n : storageCtx.clearActiveSessionId();\n // Storage is an embedder-provided adapter; a broken one must never take\n // the conversation down with it.\n void write.catch((error: unknown) => {\n log.warn('failed to persist the active session', {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n };\n\n /** The conversation the visitor was last in, from a previous page load. */\n getLastActiveSessionId = async (): Promise<string | null> => {\n if (!this.storageCtx) return null;\n try {\n return await this.storageCtx.getActiveSessionId();\n } catch {\n return null;\n }\n };\n\n /** Clears the session and stops polling */\n reset = async () => {\n this.sessionAbortController.abort();\n this.sessionAbortController = new AbortController();\n // Reset the session only, leave sessions as-is\n this.sessionState.reset();\n };\n\n private registerSessionsRefresherWrapper = () => {\n if (\n // If the widget config was initially provided with a contact token, no state change would be triggered, so we just fetch\n this.contactCtx.state.get().contact?.token &&\n !this.sessionsState.get().didStartInitialFetch\n ) {\n this.registerSessionsRefresher();\n } else {\n // In other cases where auto authenticate is fired, the token would be eventually set in state, so we wait for it\n this.contactCtx.state.subscribe(({ contact }) => {\n if (contact?.token && !this.sessionsState.get().didStartInitialFetch) {\n this.registerSessionsRefresher();\n }\n });\n }\n };\n\n private registerSessionsRefresher = () => {\n this.sessionsRefresher.startPolling(async () => {\n if (this.sessionsState.get().didStartInitialFetch === false) {\n this.sessionsState.setPartial({ didStartInitialFetch: true });\n }\n\n await this.refreshSessions();\n\n if (this.sessionsState.get().isInitialFetchLoading === true) {\n this.sessionsState.setPartial({ isInitialFetchLoading: false });\n }\n }, this.sessionsPollingIntervalSeconds * 1000);\n };\n\n private getParsedCustomData = (): CreateSessionDto['customData'] => {\n return Object.fromEntries<\n NonNullable<CreateSessionDto['customData']>[string]\n >(\n Object.entries(this.config.sessionCustomData || {}).map(\n ([key, value]) => {\n if (typeof value === 'string') return [key, value];\n if (typeof value === 'boolean') return [key, value];\n if (typeof value === 'number') return [key, value];\n // TODO maybe better to unnest instead of stringify-ing\n return [key, runCatching(() => JSON.stringify(value))?.data || ''];\n },\n ),\n );\n };\n\n createSession = async (): Promise<SessionDto | null> => {\n const { signal } = this.sessionAbortController;\n this.sessionState.setPartial({ session: null, isCreatingSession: true });\n try {\n const first = await this.requestSession(signal);\n if (signal.aborted) return null;\n if (first.session) return first.session;\n\n // Self-heal a stale contact token (401): drop it, mint a fresh contact,\n // then retry exactly once.\n if (\n first.status === 401 &&\n (await this.contactCtx.recoverFromStaleToken())\n ) {\n if (signal.aborted) return null;\n const retry = await this.requestSession(signal);\n if (signal.aborted) return null;\n if (retry.session) return retry.session;\n log.error('failed to create session', retry.error);\n return null;\n }\n\n log.error('failed to create session', first.error);\n return null;\n } catch (error) {\n if (!signal.aborted) log.error('failed to create session', error);\n return null;\n } finally {\n if (!signal.aborted)\n this.sessionState.setPartial({ isCreatingSession: false });\n }\n };\n\n /** One create-session request; on success the session is stored and the hook fires. */\n private requestSession = async (\n signal: AbortSignal,\n ): Promise<{\n session: SessionDto | null;\n status: number | undefined;\n error: unknown;\n }> => {\n const externalId = this.contactCtx.state.get().contact?.externalId;\n const customData: CreateSessionDto['customData'] = {\n ...this.getParsedCustomData(),\n ...(externalId ? { external_id: externalId } : {}),\n };\n const {\n data: session,\n error,\n response,\n } = await this.api.createSession(\n {\n customData: Object.keys(customData).length > 0 ? customData : undefined,\n },\n signal,\n );\n if (signal.aborted || !session)\n return { session: null, status: response?.status, error };\n\n this.sessionState.setPartial({ session });\n try {\n this.config.hooks?.onSessionCreated?.({ session });\n } catch (hookError) {\n log.error('onSessionCreated hook failed', hookError);\n }\n return { session, status: response.status, error: undefined };\n };\n\n loadMoreSessions = async () => {\n if (this.sessionsState.get().isLastPage) return;\n\n const { data } = await this.getSessions({\n cursor: this.sessionsState.get().cursor,\n });\n\n if (data) {\n const allSessions = [...this.sessionsState.get().data, ...data.items];\n // TODO sort by updated at\n const deduped = allSessions.filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n\n this.sessionsState.setPartial({\n data: deduped,\n cursor: data.next || undefined,\n isLastPage: data.next === null,\n });\n }\n };\n\n private getSessions = async ({ cursor }: { cursor: string | undefined }) => {\n if (!this.contactCtx.state.get().contact?.token) return { data: null };\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n return await this.api.getSessions({\n cursor,\n filters: externalId\n ? {\n external_id: externalId,\n }\n : {},\n });\n };\n\n setSessions = (data: SessionDto[]) => {\n const sessions = [...data, ...this.sessionsState.get().data].filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n this.sessionsState.setPartial({ data: sessions });\n };\n\n refreshSessions = async () => {\n // Get the first page only (pass no `cursor`)\n const { data } = await this.getSessions({ cursor: undefined });\n if (!data) return;\n this.setSessions(data.items);\n };\n\n resolveSession = async () => {\n const currentSession = this.sessionState.get().session;\n if (!currentSession || !currentSession.isOpened) {\n return { success: false, error: 'Session is not opened' } as const;\n }\n\n this.sessionState.setPartial({ isResolvingSession: true });\n const { signal } = this.sessionAbortController;\n const result = await this.api\n .resolveSession({ session_id: currentSession.id }, signal)\n .catch((error: unknown) => {\n if (signal.aborted) return null;\n throw error;\n });\n if (!result || signal.aborted)\n return { success: false, error: 'Session was reset' } as const;\n const { data: session, error } = result;\n\n if (session) {\n this.sessionState.setPartial({ session, isResolvingSession: false });\n return { success: true, data: session } as const;\n }\n\n this.sessionState.setPartial({ isResolvingSession: false });\n return { success: false, error } as const;\n };\n\n createStateCheckpoint = async (\n payload: Dto['WidgetCreateStateCheckpointInputDto']['payload'],\n ) => {\n const session_id = this.sessionState.get().session?.id;\n if (!session_id) return;\n\n const { data } = await this.api.createStateCheckpoint({\n session_id,\n payload,\n });\n\n if (data?.success) return { success: true } as const;\n\n return { success: false } as const;\n };\n}\n","import { ApiCaller } from '../api/api-caller';\nimport type { WidgetConfig, WidgetMention } from '../types/widget-config';\nimport {\n type MarkedElementRef,\n type WidgetAiMessage,\n type WidgetMessageU,\n type WidgetUserMessage,\n} from '../types/messages';\nimport type {\n MessageAttachmentType,\n SendMessageDto,\n SendMessageOutputDto,\n} from '../types/dtos';\nimport { translate } from '../translation';\nimport { log } from '../utils/log';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport { genUuid } from '../utils/uuid';\nimport { SessionCtx } from './session.ctx';\nimport type { ContactCtx } from './contact.ctx';\n\n/** The shape a caller passes to `sendMessage` (and `stageUserTurn`). */\nexport type SendMessageInput = {\n content: SendMessageDto['content'];\n attachments?: SendMessageDto['attachments'];\n customData?: SendMessageDto['custom_data'];\n /**\n * Per-message AI-visible context (e.g. the composer's picked page elements),\n * merged over the config-level `context` on the wire.\n */\n clientContext?: Record<string, unknown>;\n /**\n * What the visitor @-mentioned (host items picked from `config.mentions`).\n * Sent as `clientContext.mentions`.\n */\n mentions?: WidgetMention[];\n /**\n * False when the visitor dismissed the page's entity pill for this message:\n * the send goes out without `context.entity`, everything else intact.\n * @default true\n */\n withPageEntity?: boolean;\n exitModePrompt?: string;\n /**\n * Signals that the send has passed validation, has a session, and is owned\n * by a send engine. This lets composers clear immediately without changing\n * the existing blocking `sendMessage` promise (which still waits for a bot\n * reply). It is lifecycle-only and is never sent over the wire.\n *\n * @internal\n */\n onAccepted?: () => void;\n};\n\n/** What `stageUserTurn` hands the engine that finishes the send. */\nexport type StagedUserTurn = {\n sessionId: string;\n userMessage: WidgetUserMessage;\n /** Persistent greetings riding a fresh conversation's first turn. */\n initialMessages: WidgetAiMessage[];\n};\n\n/**\n * The seam the headless agent-chat provider registers so the shared\n * `sendMessage` entry point routes to its `useChat` streaming engine. Core\n * stays framework-neutral and owns only the blocking bot-chat path plus the\n * shared persisted message list.\n */\nexport type AgentChatHandlers = {\n /** Includes preparation, queued sends, live work and post-turn reconciliation. */\n hasPendingWork?: () => boolean;\n send: (input: SendMessageInput) => Promise<void> | void;\n};\n\n/**\n * The per-message wire context shared by both send engines: the host's\n * config-level `context` (resolved fresh when it is a function) with the\n * widget's own per-send page context merged over it.\n *\n * `sendsPageContext` is `WidgetCtx.features.pageContext` — the org's\n * page-context feature narrowed by the embed. Off → the widget adds nothing\n * of its own (no page marks, no picked elements) but the host's `context`\n * still rides along exactly as it did in v4; `custom_data` is unaffected.\n */\nexport const mergeSendContext = (\n config: WidgetConfig,\n input: SendMessageInput,\n { sendsPageContext }: { sendsPageContext: boolean },\n): {\n clientContext: Record<string, unknown> | undefined;\n custom_data: Record<string, unknown>;\n} => {\n const configContext = resolveConfigContext(config);\n const mentions =\n sendsPageContext && input.mentions && input.mentions.length > 0\n ? { mentions: input.mentions.map(mentionOnTheWire) }\n : undefined;\n const merged =\n sendsPageContext && (input.clientContext || mentions)\n ? { ...configContext, ...input.clientContext, ...mentions }\n : configContext;\n return {\n clientContext:\n input.withPageEntity === false && merged && 'entity' in merged\n ? withoutKey(merged, 'entity')\n : merged,\n custom_data: {\n ...(config.messageCustomData || {}),\n ...(input.customData || {}),\n },\n };\n};\n\n/** A mention as the agent reads it: what identifies it, never the icon. */\nconst mentionOnTheWire = ({ type, id, title, meta }: WidgetMention) => ({\n type,\n id,\n title,\n ...(meta ? { meta } : {}),\n});\n\nconst withoutKey = (\n record: Record<string, unknown>,\n key: string,\n): Record<string, unknown> | undefined => {\n const { [key]: _dropped, ...rest } = record;\n return Object.keys(rest).length > 0 ? rest : undefined;\n};\n\nexport const resolveConfigContext = (\n config: WidgetConfig,\n): Record<string, unknown> | undefined => {\n if (typeof config.context !== 'function') return config.context;\n try {\n return config.context();\n } catch (err) {\n log.error('context getter threw; sending without context', err);\n return undefined;\n }\n};\n\n/** Wire shape of the per-embed feature toggles (`config.features`). */\ntype SendFeaturesBody = NonNullable<SendMessageDto['features']>;\n\n/**\n * `config.features` (camelCase) → the snake_cased `features` field both send\n * engines carry. Undefined when the embedder set nothing, so the body stays\n * byte-identical to before for embeds that never touch the option.\n */\nexport const resolveSendFeatures = (\n config: WidgetConfig,\n): SendFeaturesBody | undefined => {\n const features = config.features;\n if (!features) return undefined;\n const body: SendFeaturesBody = {};\n if (features.preamble !== undefined) body.preamble = features.preamble;\n if (features.inlineUi !== undefined) body.inline_ui = features.inlineUi;\n if (features.pageContext !== undefined) {\n body.page_context = features.pageContext;\n }\n if (features.clientTools !== undefined) {\n body.client_tools = features.clientTools;\n }\n return Object.keys(body).length > 0 ? body : undefined;\n};\n\n/**\n * Everything one send carries on the wire — the SAME body for the blocking\n * send and the streaming turn (both endpoints take `WidgetSendMessageInputDto`).\n * Config is read at call time so function-form `context` and a refreshed\n * embedder config are reflected on every request.\n */\nexport const buildSendMessageBody = ({\n config,\n input,\n uuid,\n sessionId,\n content,\n initialMessages,\n sendsPageContext,\n}: {\n config: WidgetConfig;\n input: SendMessageInput;\n /** The user message's wire id (a retry sends a fresh one). */\n uuid: string;\n sessionId: string;\n /** The rendered user message text (extra collected data already prepended). */\n content: string;\n /** Persistent greetings riding a fresh conversation's first turn. */\n initialMessages: readonly WidgetAiMessage[];\n sendsPageContext: boolean;\n}): SendMessageDto => ({\n uuid,\n bot_token: config.token,\n headers: config.headers,\n query_params: config.queryParams,\n body_properties: config.bodyProperties,\n session_id: sessionId,\n content,\n attachments: input.attachments,\n ...mergeSendContext(config, input, { sendsPageContext }),\n language: config.language,\n features: resolveSendFeatures(config),\n presentation: config.presentation,\n capabilities: [\n config.capabilities?.structuredQuestions,\n config.capabilities?.richReplies,\n config.capabilities?.pageEffects,\n ].some((value) => value !== undefined)\n ? {\n structured_questions: config.capabilities?.structuredQuestions,\n rich_replies: config.capabilities?.richReplies,\n page_effects: config.capabilities?.pageEffects,\n }\n : undefined,\n exit_mode_prompt: input.exitModePrompt,\n initial_messages:\n initialMessages.length > 0\n ? initialMessages.map((m) => ({ uuid: m.id, content: m.data.message }))\n : undefined,\n});\n\ntype MessageCtxState = {\n messages: WidgetMessageU[];\n /** Regardless of assignee */\n isSendingMessage: boolean;\n isSendingMessageToAI: boolean;\n /** A completed streamed turn can intentionally leave no assistant row. */\n settledAgentUserMessageId: string | null;\n lastAIResMightSolveUserIssue: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class MessageCtx {\n private config: WidgetConfig;\n private readonly getRequestConfig: () => WidgetConfig;\n private readonly isStreaming: () => boolean;\n private readonly getClientCapabilities: () => WidgetConfig['capabilities'];\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n\n public state = new PrimitiveState<MessageCtxState>({\n messages: [],\n isSendingMessage: false,\n isSendingMessageToAI: false,\n settledAgentUserMessageId: null,\n lastAIResMightSolveUserIssue: false,\n isInitialFetchLoading: false,\n });\n\n /** One reactive draft per conversation, including while its composer is unmounted. */\n public draftState = new PrimitiveState({\n text: '',\n mentions: [] as WidgetMention[],\n });\n\n /**\n * Current transport choice. The org or this embed may request polling\n * independently of the server's agent version.\n */\n public get streaming(): boolean {\n return this.isStreaming();\n }\n\n /**\n * `WidgetCtx.features.pageContext`: whether the widget's own page context\n * (page marks, picked elements) rides along with each message. Off → the\n * user bubble shows no page-mark chips either.\n */\n private readonly getSendsPageContext: () => boolean;\n public get sendsPageContext(): boolean {\n return this.getSendsPageContext();\n }\n\n /** Registered by the headless agent engine for the WidgetProvider lifetime. */\n private agentHandlers: AgentChatHandlers | null = null;\n\n /** Sends issued before the agent-chat surface mounts, oldest first. */\n private bufferedAgentSends: SendMessageInput[] = [];\n\n private sendMessageAbortController = new AbortController();\n\n private messageIdsDispatchedToOnMessageReceivedHook = new Set<string>();\n\n /**\n * Text of messages sent in THIS conversation, oldest first, for the\n * composer's ↑/↓ recall. Lives here rather than in the composer because the\n * quick-ask bar and the full chat composer are different mounts of the same\n * component and recall must survive the morph between them — while staying\n * scoped to one widget instance and one conversation (`reset` clears it, so\n * a new chat never recalls the previous visitor's or session's text).\n * Deliberately NOT part of `state`: nothing renders it, so it must not\n * re-render the transcript on every send.\n */\n private sentTextHistory: string[] = [];\n private static readonly SENT_TEXT_HISTORY_MAX = 50;\n\n constructor({\n config,\n api,\n sessionCtx,\n contactCtx,\n streaming,\n sendsPageContext,\n getClientCapabilities,\n getRequestConfig,\n isStreaming,\n getSendsPageContext,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n sessionCtx: SessionCtx;\n contactCtx: ContactCtx;\n streaming: boolean;\n sendsPageContext: boolean;\n /** Read renderer support at send time; React options may change after initialization. */\n getClientCapabilities?: () => WidgetConfig['capabilities'];\n getRequestConfig?: () => WidgetConfig;\n isStreaming?: () => boolean;\n getSendsPageContext?: () => boolean;\n }) {\n this.config = config;\n this.getClientCapabilities =\n getClientCapabilities ?? (() => this.getRequestConfig().capabilities);\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.contactCtx = contactCtx;\n this.isStreaming = isStreaming ?? (() => streaming);\n this.getRequestConfig = getRequestConfig ?? (() => this.config);\n this.getSendsPageContext = getSendsPageContext ?? (() => sendsPageContext);\n }\n\n reset = () => {\n this.sendMessageAbortController.abort('Resetting chat');\n this.bufferedAgentSends = [];\n this.state.reset();\n this.messageIdsDispatchedToOnMessageReceivedHook.clear();\n this.sentTextHistory = [];\n this.draftState.reset();\n };\n\n /**\n * Record sent text for ↑/↓ recall. Consecutive duplicates collapse — the\n * common case is re-sending the same line after a failure.\n */\n rememberSentText = (text: string): void => {\n const trimmed = text.trim();\n if (!trimmed || this.sentTextHistory.at(-1) === trimmed) return;\n this.sentTextHistory.push(trimmed);\n if (this.sentTextHistory.length > MessageCtx.SENT_TEXT_HISTORY_MAX) {\n this.sentTextHistory.shift();\n }\n };\n\n /** Sent text for this conversation, oldest first. */\n getSentTextHistory = (): readonly string[] => this.sentTextHistory;\n\n /**\n * Wiring for the headless agent engine: WidgetProvider registers its useChat\n * `send` here and clears it on unmount, so every streaming headless or\n * styled consumer shares the same lifecycle. Imperative sends can arrive in\n * the render gap before registration; drain those in FIFO order once ready.\n */\n registerAgentHandlers = (handlers: AgentChatHandlers): void => {\n this.agentHandlers = handlers;\n const buffered = this.bufferedAgentSends;\n this.bufferedAgentSends = [];\n buffered.forEach((input) => {\n MessageCtx.dispatchToEngine(handlers, input);\n });\n };\n\n /** Hand a send to the streaming engine; its failure can never propagate. */\n private static dispatchToEngine(\n handlers: AgentChatHandlers,\n input: SendMessageInput,\n ): void {\n try {\n Promise.resolve(handlers.send(input)).catch((err: unknown) => {\n log.error('streaming send failed', err);\n });\n } catch (err) {\n log.error('streaming send failed', err);\n }\n }\n\n get hasPendingAgentWork(): boolean {\n return (\n this.bufferedAgentSends.length > 0 ||\n (this.agentHandlers?.hasPendingWork?.() ?? false)\n );\n }\n\n unregisterAgentHandlers = (handlers: AgentChatHandlers): void => {\n // Only clear if we still own them — guards a late unmount racing a remount.\n if (this.agentHandlers === handlers) this.agentHandlers = null;\n };\n\n /**\n * Fires `config.hooks.onMessageReceived` for AI or human-agent messages exactly\n * once per id. Safe to call from any path that ingests messages from the server\n * (send-message response, polling, initial history fetch).\n */\n dispatchToOnMessageReceivedHook = (message: WidgetMessageU): void => {\n if (message.type === 'USER') return;\n if (this.messageIdsDispatchedToOnMessageReceivedHook.has(message.id))\n return;\n const session = this.sessionCtx.sessionState.get().session;\n if (!session) return;\n this.messageIdsDispatchedToOnMessageReceivedHook.add(message.id);\n this.config.hooks?.onMessageReceived?.({ message, session });\n };\n\n /**\n * Records the given message ids as already-dispatched without firing the hook.\n * Used to suppress `onMessageReceived` for historical messages that flow in\n * when an existing session is opened — the user is loading context, not\n * receiving new messages. Subsequent polls still dedupe against these ids.\n */\n markAsDispatchedToOnMessageReceivedHook = (messageIds: string[]): void => {\n messageIds.forEach((id) =>\n this.messageIdsDispatchedToOnMessageReceivedHook.add(id),\n );\n };\n\n /**\n * On the very first turn of a fresh conversation, the configured persistent\n * initial messages are inserted into the transcript above the user's first\n * message (and posted to the backend so they persist in history). Any later\n * turn returns an empty array.\n */\n private buildPersistentInitialMessages = (): WidgetAiMessage[] => {\n const shouldInsert =\n !this.sessionCtx.sessionState.get().session?.id &&\n this.state.get().messages.length === 0 &&\n this.config.advancedInitialMessages?.some((m) => m.persistent);\n if (!shouldInsert) return [];\n return (this.config.advancedInitialMessages || [])\n .filter((m) => m.persistent)\n .map(\n (m) =>\n ({\n id: genUuid(),\n component: 'bot_message',\n type: 'AI',\n timestamp: new Date().toISOString(),\n data: { message: m.message },\n agent: this.config.bot\n ? { ...this.config.bot, isAi: true, id: null }\n : undefined,\n }) satisfies WidgetAiMessage,\n );\n };\n\n /**\n * Create the session on the conversation's first send; refreshes the\n * sessions list so the new session shows up immediately. Returns `null`\n * when creation fails.\n */\n private ensureSessionId = async (): Promise<string | null> => {\n if (!this.sessionCtx.sessionState.get().session?.id) {\n const createdSession = await this.sessionCtx.createSession();\n if (!createdSession) return null;\n void this.sessionCtx.refreshSessions();\n }\n return this.sessionCtx.sessionState.get().session?.id ?? null;\n };\n\n /** Remove only this failed attempt's optimistic rows, preserving poll merges. */\n private rollbackOptimisticMessages = (\n messageIds: readonly string[],\n ): void => {\n if (messageIds.length === 0) return;\n const ids = new Set(messageIds);\n const messages = this.state.get().messages;\n const nextMessages = messages.filter((message) => !ids.has(message.id));\n if (nextMessages.length !== messages.length) {\n this.state.setPartial({ messages: nextMessages });\n }\n };\n\n /**\n * Fire the caller's `onAccepted` once a send is validated, has a session,\n * and is owned by an engine. A consumer callback must never be able to\n * break an accepted send.\n */\n notifySendAccepted = (input: SendMessageInput): void => {\n try {\n input.onAccepted?.();\n } catch (error) {\n log.error('send acceptance callback failed', error);\n }\n };\n\n /**\n * The front half every send shares, whichever engine finishes it: validate,\n * build the user message (plus the persistent greetings on a fresh\n * conversation's first turn), render it optimistically, and make sure a\n * session exists — rolling the optimistic rows back if it cannot. Returns\n * `null` when there is nothing to send or no session could be created.\n */\n stageUserTurn = async (\n input: SendMessageInput,\n { pending }: { pending: boolean },\n ): Promise<StagedUserTurn | null> => {\n const built = this.buildUserMessage(input);\n if (!built) return null;\n const userMessage = pending ? { ...built, pending: true } : built;\n\n const initialMessages = this.buildPersistentInitialMessages();\n const optimisticMessageIds = [\n ...initialMessages.map((message) => message.id),\n userMessage.id,\n ];\n this.state.setPartial({\n messages: [...initialMessages, ...this.state.get().messages, userMessage],\n });\n\n let sessionId: string | null;\n try {\n sessionId = await this.ensureSessionId();\n } catch (error) {\n this.rollbackOptimisticMessages(optimisticMessageIds);\n throw error;\n }\n if (!sessionId) {\n this.rollbackOptimisticMessages(optimisticMessageIds);\n return null;\n }\n return { sessionId, userMessage, initialMessages };\n };\n\n /**\n * Build the user message for a QUEUED (multi-send) turn WITHOUT rendering\n * it into the transcript. A queued message must not appear above the still-\n * streaming response of the active turn — the surface renders it below the\n * live overlay (dimmed via `pending`) and only `appendUserMessageIfAbsent`s\n * it into `messages` when its own turn actually starts (see `useAgentChat`).\n * A session already exists here (a turn is in flight), so this never creates\n * one.\n */\n buildQueuedUserMessage = (\n input: SendMessageInput,\n ): { sessionId: string; userMessage: WidgetUserMessage } | null => {\n const built = this.buildUserMessage(input);\n if (!built) return null;\n const sessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!sessionId) return null;\n return { sessionId, userMessage: { ...built, pending: true } };\n };\n\n /** Validate the input and build its user message; `null` when empty. */\n private buildUserMessage = (\n input: SendMessageInput,\n ): WidgetUserMessage | null => {\n if (\n !input.content.trim() &&\n (!input.attachments || input.attachments.length === 0)\n ) {\n log.warn('cannot send an empty message of no content or attachments');\n return null;\n }\n return this.toUserMessage(\n input.content.trim(),\n input.attachments || undefined,\n this.sendsPageContext\n ? MessageCtx.markedElementNames(input.clientContext)\n : undefined,\n this.sendsPageContext && input.mentions?.length\n ? input.mentions\n : undefined,\n );\n };\n\n /**\n * Defensive read of `clientContext.page_marks` → the user bubble's context\n * chips: each mark contributes the element it was placed on, the note the\n * visitor wrote, and a reference back to the mark itself (the UI renders\n * the same presentation the composer showed, thumbnail included). Entries\n * without a usable name are dropped.\n */\n private static markedElementNames(\n clientContext: Record<string, unknown> | undefined,\n ): MarkedElementRef[] | undefined {\n const raw = clientContext?.['page_marks'];\n if (!Array.isArray(raw)) return undefined;\n const marked = raw.flatMap((mark: unknown): MarkedElementRef[] => {\n if (typeof mark !== 'object' || mark === null) return [];\n const elements: unknown = (mark as { elements?: unknown }).elements;\n const first = Array.isArray(elements) ? elements[0] : undefined;\n const name: unknown =\n typeof first === 'object' && first !== null && 'name' in first\n ? (first as { name: unknown }).name\n : undefined;\n if (typeof name !== 'string' || name.length === 0) return [];\n const note: unknown = (mark as { note?: unknown }).note;\n const snapshotUrl: unknown = (mark as { snapshotUrl?: unknown })\n .snapshotUrl;\n return [\n {\n name,\n ...(typeof note === 'string' && note.length > 0 ? { note } : {}),\n ...(typeof snapshotUrl === 'string' && snapshotUrl.length > 0\n ? { snapshotUrl }\n : {}),\n mark,\n },\n ];\n });\n return marked.length > 0 ? marked : undefined;\n }\n\n /** Append a user message to the transcript once, ignoring a duplicate id. */\n appendUserMessageIfAbsent = (userMessage: WidgetUserMessage): void => {\n const messages = this.state.get().messages;\n if (messages.some((m) => m.id === userMessage.id)) return;\n this.state.setPartial({ messages: [...messages, userMessage] });\n };\n\n /**\n * Clear the `pending` flag for the user message owned by one streamed turn.\n * Later queued bubbles must remain pending until their own turn reaches the\n * server.\n */\n markUserMessageDelivered = (messageId: string): void => {\n const messages = this.state.get().messages;\n const index = messages.findIndex(\n (message) =>\n message.id === messageId && message.type === 'USER' && message.pending,\n );\n if (index === -1) return;\n const delivered = messages[index];\n if (!delivered || delivered.type !== 'USER') return;\n const nextMessages = [...messages];\n nextMessages[index] = { ...delivered, pending: false };\n this.state.setPartial({\n messages: nextMessages,\n });\n };\n\n /**\n * The blocking engine refuses a send while the AI reply is pending unless\n * the embed opted out. The streaming engine never blocks (it queues).\n */\n get blocksSendWhileAwaitingReply(): boolean {\n return (\n !this.streaming && this.config.disableSendingWhenAwaitingAIReply !== false\n );\n }\n\n sendMessage = async (input: SendMessageInput): Promise<void> => {\n // Streaming: the headless useChat engine owns the whole turn lifecycle\n // (optimistic render, streaming, interrupt-send, stop). An imperative\n // `newChat({ message })` can send before that surface's mount effect, so\n // retain the input until handlers register instead of dropping it.\n if (this.streaming) {\n if (!this.agentHandlers) {\n this.bufferedAgentSends.push(input);\n return;\n }\n await this.agentHandlers.send(input);\n return;\n }\n\n let localAbortController: AbortController | undefined;\n try {\n /* ------------------------------------------------------ */\n /* Prevent sending while waiting for AI res */\n /* ------------------------------------------------------ */\n const session = this.sessionCtx.sessionState.get().session;\n const assignee = session?.assignee.kind;\n const isAssignedToAI = assignee === 'ai';\n const isSendingToAI = this.state.get().isSendingMessageToAI;\n const lastMessage = this.state.get().messages.at(-1);\n\n if (\n this.blocksSendWhileAwaitingReply &&\n (isSendingToAI ||\n // If last message is from user, then bot response did not arrive yet\n (isAssignedToAI &&\n lastMessage?.type === 'USER' &&\n lastMessage.id !== this.state.get().settledAgentUserMessageId))\n ) {\n log.warn('cannot send messages while awaiting AI response');\n return;\n }\n\n /* ------------------------------------------------------ */\n /* Start */\n /* ------------------------------------------------------ */\n // Abort any prior in-flight send so only the latest call is awaited.\n // We rely on aggressive polling to recover any messages whose responses\n // we drop here.\n this.sendMessageAbortController.abort('Superseded by a newer message');\n this.sendMessageAbortController = new AbortController();\n localAbortController = this.sendMessageAbortController;\n this.state.setPartial({\n lastAIResMightSolveUserIssue: false,\n isSendingMessage: true,\n isSendingMessageToAI: !!isAssignedToAI || !session,\n });\n\n const staged = await this.stageUserTurn(input, { pending: false });\n if (!staged) return;\n const { sessionId, userMessage, initialMessages } = staged;\n this.notifySendAccepted(input);\n /* ------------------------------------------------------ */\n /* Send and wait for bot response */\n /* ------------------------------------------------------ */\n const { data } = await this.api.sendMessage(\n buildSendMessageBody({\n config: {\n ...this.getRequestConfig(),\n capabilities: this.getClientCapabilities(),\n },\n input,\n uuid: userMessage.id,\n sessionId,\n content: userMessage.content,\n initialMessages,\n sendsPageContext: this.sendsPageContext,\n }),\n localAbortController.signal,\n );\n\n if (data?.success) {\n /* ------------------------------------------------------ */\n /* Append bot reply if not fetched from polling */\n /* ------------------------------------------------------ */\n const botMessage = this.toBotMessage(data);\n if (botMessage) {\n const prevMessages = this.state.get().messages;\n const shouldAppend = !prevMessages.some(\n (m) => m.id === botMessage.id,\n );\n if (!shouldAppend) {\n this.state.setPartial({\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n return;\n }\n this.state.setPartial({\n messages: [...prevMessages, botMessage],\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n this.dispatchToOnMessageReceivedHook(botMessage);\n }\n if (data.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n }\n } else {\n const errorMessage = this.toBotErrorMessage(\n data?.error?.message || translate(this.config, 'turn_failed_message'),\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, errorMessage],\n });\n }\n } catch (error) {\n if (!localAbortController?.signal.aborted) {\n log.error('failed to send message', error);\n }\n } finally {\n // If our local controller was aborted, a newer send has taken over —\n // don't clear the in-flight flags out from under it.\n if (!localAbortController?.signal.aborted) {\n this.state.setPartial({\n isSendingMessage: false,\n isSendingMessageToAI: false,\n });\n }\n }\n };\n\n private toUserMessage = (\n content: string,\n attachments?: MessageAttachmentType[],\n markedElements?: MarkedElementRef[],\n mentions?: WidgetMention[],\n ): WidgetUserMessage => {\n const messageContent = (() => {\n const extraCollectedData = this.contactCtx.state.get().extraCollectedData;\n // Prepend extra collected data if this is the first message in the session\n if (\n this.state.get().messages.length === 0 &&\n extraCollectedData &&\n Object.keys(extraCollectedData).length > 0\n ) {\n const data = Object.entries(extraCollectedData)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => `${key}: ${value}`)\n .join(' \\n');\n return `${data} \\n\\n${content}`;\n }\n\n return content;\n })();\n\n return {\n id: genUuid(),\n type: 'USER',\n content: messageContent,\n attachments,\n markedElements,\n mentions,\n timestamp: new Date().toISOString(),\n };\n };\n\n private toBotMessage = (\n response: SendMessageOutputDto,\n ): WidgetAiMessage | null => {\n if (response.success && response.autopilotResponse) {\n return {\n type: 'AI',\n id: response.autopilotResponse.id || genUuid(),\n timestamp: new Date().toISOString(),\n component: 'bot_message',\n agent: this.config.bot\n ? {\n name: this.config.bot.name || '',\n isAi: true,\n // Do not set avatarUrl here... let it be taken from the config at render time\n avatarUrl: null,\n avatar: null,\n id: null,\n }\n : undefined,\n data: {\n message: response.autopilotResponse.value.content,\n action: response.uiResponse?.value.name\n ? {\n name: response.uiResponse.value.name,\n data: response.uiResponse.value.request_response,\n }\n : undefined,\n },\n };\n }\n\n return null;\n };\n\n private toBotErrorMessage = (message: string): WidgetAiMessage => {\n return {\n type: 'AI',\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: 'bot_message',\n data: {\n message,\n variant: 'error',\n action: undefined,\n },\n };\n };\n}\n","import type { SessionDto } from '../types/dtos';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport type { ContactCtx } from './contact.ctx';\nimport type { SessionCtx } from './session.ctx';\nimport type { WidgetCtx } from './widget.ctx';\n\nexport type ScreenU =\n | /** A welcome screen to collect user data. Useful in public non-logged-in environments */\n 'welcome'\n /** Show a list of the user's previous sessions */\n | 'sessions'\n /** Self-explanatory */\n | 'chat';\n\ntype RouterState = {\n screen: ScreenU;\n};\n\nexport class RouterCtx {\n state: PrimitiveState<RouterState>;\n private subscriptions: Array<() => void> = [];\n private disposed = false;\n\n private config: WidgetConfig;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n private resetChat: WidgetCtx['resetChat'];\n /**\n * Whether a reload returns the visitor to the conversation they were in.\n * Off by default: the home screen is the sessions list. Embedders whose\n * widget is a continuous assistant (an empty panel beside a live\n * conversation reads as data loss) opt in via `router.restoreLastSession`.\n */\n private readonly shouldRestoreLastSession: boolean;\n /** The stored pointer, until it is used or found unusable. */\n private restorableSessionId: string | null = null;\n /** Has the (async) storage read settled? Automatic routing waits for it. */\n private didReadStoredSession = false;\n\n constructor(private widget: WidgetCtx) {\n this.config = widget.config;\n this.contactCtx = widget.contactCtx;\n this.sessionCtx = widget.sessionCtx;\n this.resetChat = widget.resetChat;\n this.state = new PrimitiveState<RouterState>({\n screen: this.contactCtx.shouldCollectData()\n ? 'welcome'\n : this.config.router?.chatScreenOnly\n ? 'chat'\n : 'sessions',\n });\n this.shouldRestoreLastSession =\n this.config.router?.restoreLastSession ?? false;\n\n this.readStoredSession();\n this.registerRoutingListener();\n }\n\n /**\n * Read the remembered conversation before any automatic routing runs. The\n * read is async (the storage adapter may be), and the sessions list can land\n * first — so routing is re-run once the pointer is known.\n */\n private readStoredSession = () => {\n if (!this.shouldRestoreLastSession) {\n this.didReadStoredSession = true;\n return;\n }\n void this.sessionCtx\n .getLastActiveSessionId()\n .then((sessionId) => {\n this.restorableSessionId = sessionId;\n })\n .finally(() => {\n this.didReadStoredSession = true;\n this.routeFromSessions(this.sessionCtx.sessionsState.get());\n });\n };\n\n private registerRoutingListener = () => {\n this.subscriptions.push(\n this.contactCtx.state.subscribe(({ contact }) => {\n // Auto navigate to sessions screen after collecting user data\n if (contact?.token && this.state.get().screen === 'welcome') {\n this.state.setPartial({\n screen: this.config.router?.chatScreenOnly ? 'chat' : 'sessions',\n });\n }\n }),\n );\n\n this.subscriptions.push(\n this.sessionCtx.sessionsState.subscribe(this.routeFromSessions),\n );\n };\n\n /**\n * Every automatic route the sessions list can trigger, in one place so the\n * restore can re-run it once the stored pointer is known.\n */\n private routeFromSessions = ({\n isInitialFetchLoading,\n data,\n }: {\n isInitialFetchLoading: boolean;\n data: SessionDto[];\n }) => {\n // Hold automatic routing until we know whether there is a conversation to\n // return to: routing first and restoring second would flash the wrong\n // screen, or start a second conversation beside the live one.\n if (this.disposed || !this.didReadStoredSession) return;\n\n if (\n this.restorableSessionId &&\n !this.sessionCtx.sessionState.get().session?.id\n ) {\n const restored = data.find(\n (s) => s.id === this.restorableSessionId && s.isOpened,\n );\n if (restored) {\n this.restorableSessionId = null;\n this.toChatScreen(restored.id);\n return;\n }\n // Not in the list yet — the first page may still be loading. Once it has\n // landed, a pointer with no open session behind it (closed elsewhere,\n // deleted, another contact) is stale: drop it and route normally.\n if (isInitialFetchLoading) return;\n this.restorableSessionId = null;\n }\n\n if (\n this.config.router?.chatScreenOnly &&\n // Do not route to a chat if we are currently inside one already\n // This also applies to newly created sessions; the new session will be in `sessionState` before it is refreshed and included in `sessionsState`\n !this.sessionCtx.sessionState.get().session?.id\n ) {\n const mostRecentOpenSessionId = data.find((s) => s.isOpened)?.id;\n return mostRecentOpenSessionId\n ? this.toChatScreen(mostRecentOpenSessionId)\n : undefined;\n }\n\n if (data.length) return;\n if (this.config.router?.goToChatIfNoSessions === false) return;\n\n // Auto navigate to chat screen if contact has no previous sessions\n if (!isInitialFetchLoading && this.state.get().screen !== 'chat') {\n this.toChatScreen();\n }\n };\n\n dispose = () => {\n this.disposed = true;\n this.subscriptions.forEach((unsubscribe) => unsubscribe());\n this.subscriptions = [];\n this.navigateConversation = undefined;\n };\n\n /** A multi-chat host owns navigation without resetting background sends. */\n navigateConversation?: (sessionId?: string) => WidgetCtx | undefined;\n\n toSessionsScreen = () => {\n if (!this.navigateConversation) this.resetChat();\n this.state.setPartial({ screen: 'sessions' });\n };\n\n /**\n * @param sessionId The ID of the session to open, or `undefined` if it is a new chat session\n */\n toChatScreen = (sessionId?: string): WidgetCtx | undefined => {\n if (this.navigateConversation) return this.navigateConversation(sessionId);\n this.resetChat();\n\n let session: SessionDto | undefined;\n\n if (sessionId) {\n session = this.sessionCtx.sessionsState\n .get()\n .data.find((s) => s.id === sessionId);\n // Do not navigate if session is not found (this shouldn't happen, unless a wrong ID is passed)\n if (!session) return;\n this.sessionCtx.sessionState.setPartial({ session });\n }\n\n this.state.setPartial({ screen: 'chat' });\n\n this.config.hooks?.onNavigateToChat?.({ session });\n return this.widget;\n };\n}\n","import type { ExternalStorage } from '../types/external-storage';\nimport type {\n WidgetCompanionDefaultLayoutU,\n WidgetConfig,\n WidgetSidebarModeU,\n} from '../types/widget-config';\nimport type { WidgetSidebarSideResolvedU } from '../utils/companion-layout';\n\n/** The per-visitor companion preferences the widget remembers between visits. */\ntype CompanionPreferenceU =\n | 'pill-offset-x'\n | 'sidebar-width'\n | 'sidebar-side'\n | 'sidebar-mode'\n | 'layout';\n\nexport class StorageCtx {\n private storage: ExternalStorage;\n private config: WidgetConfig;\n\n private KEYS = {\n contactToken: (orgToken: string) =>\n `opencx-widget:org-token-${orgToken}:contact-token`,\n externalContactId: (orgToken: string) =>\n `opencx-widget:org-token-${orgToken}:external-contact-id`,\n companionPreference: (orgToken: string, preference: CompanionPreferenceU) =>\n `opencx-widget:org-token-${orgToken}:companion-${preference}`,\n activeSession: (orgToken: string) =>\n `opencx-widget:org-token-${orgToken}:active-session`,\n };\n\n constructor({\n storage,\n config,\n }: {\n storage: ExternalStorage;\n config: WidgetConfig;\n }) {\n this.storage = storage;\n this.config = config;\n }\n\n setContactToken = async (token: string) => {\n await this.storage.set(this.KEYS.contactToken(this.config.token), token);\n };\n getContactToken = async () => {\n return this.storage.get(this.KEYS.contactToken(this.config.token));\n };\n clearContactToken = async () => {\n await this.storage.remove(this.KEYS.contactToken(this.config.token));\n };\n\n /**\n * The conversation the visitor was last in. Only a POINTER lives here — the\n * messages themselves are on the backend — but without it a page reload\n * drops the visitor into an empty composer beside a conversation that is\n * still very much alive.\n */\n private activeSessionKey = (): string =>\n this.KEYS.activeSession(this.config.token);\n\n getActiveSessionId = async (): Promise<string | null> => {\n return this.storage.get(this.activeSessionKey());\n };\n setActiveSessionId = async (sessionId: string): Promise<void> => {\n await this.storage.set(this.activeSessionKey(), sessionId);\n };\n clearActiveSessionId = async (): Promise<void> => {\n await this.storage.remove(this.activeSessionKey());\n };\n\n setExternalContactId = async (id: string) => {\n await this.storage.set(this.KEYS.externalContactId(this.config.token), id);\n };\n getExternalContactId = async () => {\n return this.storage.get(this.KEYS.externalContactId(this.config.token));\n };\n\n private companionKey = (preference: CompanionPreferenceU): string =>\n this.KEYS.companionPreference(this.config.token, preference);\n\n private getFiniteNumber = async (key: string): Promise<number | null> => {\n const raw = await this.storage.get(key);\n if (raw === null) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n };\n\n getCompanionPillOffsetX = async (): Promise<number | null> =>\n this.getFiniteNumber(this.companionKey('pill-offset-x'));\n\n setCompanionPillOffsetX = async (offset: number): Promise<void> => {\n if (!Number.isFinite(offset)) return;\n await this.storage.set(this.companionKey('pill-offset-x'), String(offset));\n };\n\n getCompanionSidebarWidth = async (): Promise<number | null> =>\n this.getFiniteNumber(this.companionKey('sidebar-width'));\n\n setCompanionSidebarWidth = async (width: number): Promise<void> => {\n if (!Number.isFinite(width)) return;\n await this.storage.set(this.companionKey('sidebar-width'), String(width));\n };\n\n /**\n * The visitor's own sidebar side/mode, once they have picked one in the\n * layout menu. Absent until then, so `companion.sidebar.*` config keeps\n * deciding for a visitor who never touched the control. Unrecognized stored\n * values read as absent rather than poisoning the layout.\n */\n getCompanionSidebarSide =\n async (): Promise<WidgetSidebarSideResolvedU | null> => {\n const raw = await this.storage.get(this.companionKey('sidebar-side'));\n return raw === 'left' || raw === 'right' ? raw : null;\n };\n\n setCompanionSidebarSide = async (\n side: WidgetSidebarSideResolvedU,\n ): Promise<void> => {\n await this.storage.set(this.companionKey('sidebar-side'), side);\n };\n\n /**\n * The RESTING layout the visitor last picked in the layout menu. Absent\n * until they pick one, so `companion.defaultLayout` keeps deciding for a\n * visitor who never touched the control.\n *\n * `fullscreen` is deliberately unstorable: it is a mode the visitor enters\n * on top of a resting layout (Escape drops back out of it), so persisting\n * it would reopen every future visit full-screen over the host page.\n */\n getCompanionLayout =\n async (): Promise<WidgetCompanionDefaultLayoutU | null> => {\n const raw = await this.storage.get(this.companionKey('layout'));\n return raw === 'compact' || raw === 'sidebar' ? raw : null;\n };\n\n setCompanionLayout = async (\n layout: WidgetCompanionDefaultLayoutU,\n ): Promise<void> => {\n await this.storage.set(this.companionKey('layout'), layout);\n };\n\n getCompanionSidebarMode = async (): Promise<WidgetSidebarModeU | null> => {\n const raw = await this.storage.get(this.companionKey('sidebar-mode'));\n return raw === 'docked' || raw === 'floating' ? raw : null;\n };\n\n setCompanionSidebarMode = async (mode: WidgetSidebarModeU): Promise<void> => {\n await this.storage.set(this.companionKey('sidebar-mode'), mode);\n };\n}\n","import type { Dto } from '../api/client';\nimport type { WidgetConfig } from '../types/widget-config';\n\n/**\n * The org's agent as the embed sees it: branding, which engine serves the\n * web channel, and the features the CLIENT acts on. Features the server\n * applies on its own (preamble, inline UI) are not mirrored here — the embed\n * only forwards its toggles for those (see `resolveSendFeatures`).\n */\nexport type WidgetAgent = {\n name: string;\n avatarUrl: string | null;\n /**\n * The org's web channel runs the streaming engine (widget v5). `false`\n * means the classic blocking send.\n */\n streaming: boolean;\n /** Optional on older backends; controls the maximum visible tool detail. */\n presentation?: Dto['WidgetPresentationDto'];\n /** The org's EFFECTIVE features (entitlements already applied). */\n features: {\n dictation: boolean;\n attachments: boolean;\n pageContext: boolean;\n clientTools: boolean;\n };\n};\n\ntype ServerAgent = Dto['WidgetAgentDto'];\n\n/**\n * snake_case (backend DTO) → camelCase (widget types) at the boundary.\n *\n * A backend that predates widget v5 returns no `agent` block. Preserve its\n * blocking send and attachment support when an embed is upgraded first.\n */\nexport function resolveWidgetAgent({\n org,\n agent,\n}: {\n org: { name: string };\n agent?: ServerAgent | null;\n}): WidgetAgent {\n if (!agent) {\n return {\n name: org.name,\n avatarUrl: null,\n streaming: false,\n features: {\n dictation: false,\n attachments: true,\n pageContext: false,\n clientTools: false,\n },\n };\n }\n return {\n name: agent.name,\n avatarUrl: agent.avatar_url,\n streaming: agent.streaming,\n ...(agent.presentation ? { presentation: agent.presentation } : {}),\n features: {\n dictation: agent.features.dictation,\n attachments: agent.features.attachments,\n pageContext: agent.features.page_context,\n clientTools: agent.features.client_tools,\n },\n };\n}\n\n/**\n * The one narrowing rule for every per-embed feature toggle: the org's\n * effective feature can only be switched OFF by `config.features`, never on.\n */\nfunction narrowFeature(\n orgEnabled: boolean,\n embedToggle: boolean | undefined,\n): boolean {\n return orgEnabled && embedToggle !== false;\n}\n\n/** The client-side feature answers the UI asks for, narrowed by the embed. */\nexport function resolveClientFeatures(\n agent: WidgetAgent,\n config: WidgetConfig,\n): {\n /** The composer offers voice dictation. */\n dictation: boolean;\n /** The composer offers the attachment/upload affordance. */\n attachments: boolean;\n /**\n * The visitor can mark the page (the composer's page-mark button) and the\n * widget's own page context rides along with each message. The host's\n * `config.context` is unaffected — it always rides along, as it did in v4.\n */\n pageContext: boolean;\n /**\n * The widget performs the agent's client tools (highlight an element on\n * the host page).\n */\n clientTools: boolean;\n} {\n const toggles = config.features;\n return {\n dictation: narrowFeature(agent.features.dictation, toggles?.dictation),\n attachments: agent.features.attachments,\n pageContext: narrowFeature(\n agent.features.pageContext,\n toggles?.pageContext,\n ),\n clientTools: narrowFeature(\n agent.features.clientTools,\n toggles?.clientTools,\n ),\n };\n}\n\nexport type WidgetClientFeatures = ReturnType<typeof resolveClientFeatures>;\n","import { ApiCaller } from '../api/api-caller';\nimport type { ModeDto } from '../types/dtos';\nimport type { ExternalStorage } from '../types/external-storage';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { ActiveSessionPollingCtx } from './active-session-polling.ctx';\nimport { ContactCtx } from './contact.ctx';\nimport { UploadCtx } from './upload.ctx';\nimport { CsatCtx } from './csat.ctx';\nimport { DictationCtx } from './dictation.ctx';\nimport { MessageCtx } from './message.ctx';\nimport { RouterCtx } from './router.ctx';\nimport { SessionCtx } from './session.ctx';\nimport { StorageCtx } from './storage.ctx';\nimport {\n resolveClientFeatures,\n resolveWidgetAgent,\n type WidgetAgent,\n type WidgetClientFeatures,\n} from './widget-agent';\nimport { log } from '../utils/log';\n\n/** A configuration failure that prevents the widget from choosing a safe\n * runtime. The code is stable so headless consumers can render their own\n * recovery UI without matching error-message text. */\nexport class WidgetInitializationError extends Error {\n readonly code: 'config-fetch-failed';\n readonly details: unknown;\n\n constructor(code: 'config-fetch-failed', message: string, details?: unknown) {\n super(message);\n this.name = 'WidgetInitializationError';\n this.code = code;\n this.details = details;\n }\n}\n\nexport class WidgetCtx {\n public config: WidgetConfig;\n public api: ApiCaller;\n\n public contactCtx: ContactCtx;\n public sessionCtx: SessionCtx;\n public messageCtx: MessageCtx;\n public csatCtx: CsatCtx;\n public uploadCtx: UploadCtx;\n public dictationCtx: DictationCtx;\n public routerCtx: RouterCtx;\n public storageCtx?: StorageCtx;\n public modes: ModeDto[] = [];\n\n public org: {\n id: string;\n name: string;\n };\n /**\n * The org's agent — branding plus which engine serves it — resolved by the\n * backend at init. The `bot` option overrides the branding at render time.\n */\n public readonly agent: WidgetAgent;\n\n /**\n * Choose the transport from the org's default and the current embed opt-out.\n * The backend chooses the agent version independently of this transport.\n */\n private readonly getRequestConfig: () => WidgetConfig;\n private readonly getClientCapabilities?: () => WidgetConfig['capabilities'];\n\n public get streaming(): boolean {\n // Accepted sends keep their transport through preparation, queue draining\n // and reconciliation. Never let a prop update detach their owner.\n if (this.messageCtx?.hasPendingAgentWork) return true;\n if (this.messageCtx?.state.get().isSendingMessage) return false;\n return this.agent.streaming && this.getRequestConfig().streaming !== false;\n }\n\n /**\n * The org's features narrowed by this embed's `config.features` — the\n * answers the UI asks for, resolved against the current options.\n */\n public get features(): WidgetClientFeatures {\n return resolveClientFeatures(this.agent, this.getRequestConfig());\n }\n\n private static pollingIntervalsSeconds: {\n session: number;\n sessions: number;\n } | null = null;\n private activeSessionPollingCtx: ActiveSessionPollingCtx;\n\n private constructor({\n config,\n storage,\n getClientCapabilities,\n getRequestConfig,\n modes,\n org,\n agent,\n parent,\n }: {\n config: WidgetConfig;\n storage?: ExternalStorage;\n getClientCapabilities?: () => WidgetConfig['capabilities'];\n getRequestConfig?: () => WidgetConfig;\n modes: ModeDto[];\n org: {\n id: string;\n name: string;\n };\n agent: WidgetAgent;\n parent?: WidgetCtx;\n }) {\n if (!WidgetCtx.pollingIntervalsSeconds) {\n throw Error(\n 'Widget polling values are not defined, did you call WidgetCtx.initialize()',\n );\n }\n\n this.config = config;\n this.getRequestConfig = getRequestConfig ?? (() => this.config);\n this.getClientCapabilities = getClientCapabilities;\n this.org = org;\n this.agent = agent;\n this.api = parent?.api ?? new ApiCaller({ config });\n this.storageCtx =\n parent?.storageCtx ??\n (storage ? new StorageCtx({ storage, config }) : undefined);\n this.modes = modes;\n\n this.contactCtx =\n parent?.contactCtx ??\n new ContactCtx({\n api: this.api,\n config: this.config,\n storageCtx: this.storageCtx,\n });\n\n this.sessionCtx = new SessionCtx({\n config: this.config,\n api: this.api,\n contactCtx: this.contactCtx,\n // Remembers the open conversation so a reload can return to it.\n storageCtx: parent ? undefined : this.storageCtx,\n sharedSessions: parent?.sessionCtx.sessionsState,\n sessionsPollingIntervalSeconds:\n WidgetCtx.pollingIntervalsSeconds.sessions,\n });\n\n this.messageCtx = new MessageCtx({\n config: this.config,\n api: this.api,\n sessionCtx: this.sessionCtx,\n contactCtx: this.contactCtx,\n // Streaming orgs send their turns over the AI SDK transport instead of\n // the blocking bot-chat send.\n streaming: this.streaming,\n isStreaming: () => this.streaming,\n sendsPageContext: this.features.pageContext,\n getSendsPageContext: () => this.features.pageContext,\n getClientCapabilities,\n getRequestConfig,\n });\n\n this.uploadCtx = new UploadCtx(this.api);\n this.csatCtx = new CsatCtx({\n api: this.api,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n });\n\n this.dictationCtx = new DictationCtx({\n api: this.api,\n config: this.config,\n });\n\n this.activeSessionPollingCtx = new ActiveSessionPollingCtx({\n api: this.api,\n config: this.config,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n sessionPollingIntervalSeconds: WidgetCtx.pollingIntervalsSeconds.session,\n });\n\n this.routerCtx = new RouterCtx(this);\n }\n\n static initialize = async ({\n config,\n storage,\n getClientCapabilities,\n getRequestConfig,\n }: {\n config: WidgetConfig;\n storage?: ExternalStorage;\n getClientCapabilities?: () => WidgetConfig['capabilities'];\n getRequestConfig?: () => WidgetConfig;\n }) => {\n const externalConfig = await new ApiCaller({\n config,\n }).getExternalWidgetConfig();\n\n if (!externalConfig.data) {\n // Surface the backend's reason instead of failing mutely.\n log.error('widget config fetch failed', externalConfig.error);\n throw new WidgetInitializationError(\n 'config-fetch-failed',\n 'Failed to fetch widget config',\n externalConfig.error,\n );\n }\n\n this.pollingIntervalsSeconds = {\n session: externalConfig.data?.sessionPollingIntervalSeconds || 10,\n sessions: externalConfig.data?.sessionsPollingIntervalSeconds || 60,\n };\n\n return new WidgetCtx({\n config,\n storage,\n getClientCapabilities,\n getRequestConfig,\n modes: externalConfig.data.modes || [],\n org: {\n id: externalConfig.data.org.id,\n name: externalConfig.data.org.name,\n },\n agent: resolveWidgetAgent(externalConfig.data),\n });\n };\n\n /** Independent send/history lifecycle, sharing the authenticated visitor and session list. */\n createConversation = (): WidgetCtx => {\n const conversation = new WidgetCtx({\n config: {\n ...this.config,\n router: {\n ...this.config.router,\n restoreLastSession: false,\n chatScreenOnly: false,\n goToChatIfNoSessions: false,\n },\n },\n modes: this.modes,\n org: this.org,\n agent: this.agent,\n parent: this,\n getRequestConfig: this.getRequestConfig,\n getClientCapabilities: this.getClientCapabilities,\n });\n conversation.routerCtx.state.setPartial({\n screen: this.contactCtx.shouldCollectData() ? 'welcome' : 'chat',\n });\n return conversation;\n };\n\n /** Release a closed companion runtime after its last send has settled. */\n releaseConversation = () => {\n this.routerCtx.dispose();\n this.resetChat();\n };\n\n resetChat = () => {\n this.sessionCtx.reset();\n this.messageCtx.reset();\n this.uploadCtx.reset();\n };\n\n /**\n * Ingest the canonical rows the backend persisted for a streamed turn.\n * Called by the agent-chat surface when a turn finishes; the polling\n * context owns history mapping/dedupe, so this delegates to it.\n */\n reconcileAfterStream = (sessionId: string): Promise<void> =>\n this.activeSessionPollingCtx.reconcileAfterStream(sessionId);\n}\n","import type { WidgetAgent } from './widget-agent';\nimport type { WidgetConfig } from '../types/widget-config';\n\n/** The embed may hide more activity, but cannot reveal details the org hides. */\nexport function resolveClientPresentation(\n org: WidgetAgent['presentation'],\n client: WidgetConfig['presentation'],\n): WidgetConfig['presentation'] {\n if (!org) return client;\n return {\n toolActivity:\n org.toolActivity === 'hidden' || client?.toolActivity === 'hidden'\n ? 'hidden'\n : org.toolActivity === 'status' || client?.toolActivity === 'status'\n ? 'status'\n : 'details',\n reasoning: org.reasoning && client?.reasoning !== false,\n };\n}\n","/**\n * Asymmetric level smoother shared by every voice meter: fast attack so the\n * UI kicks with speech, slow release so it settles instead of twitching.\n * One implementation so the mic bars, edge glow, and width swell can never\n * drift apart in feel — only in their chosen constants.\n */\nexport class DictationLevelSmoother {\n private readonly attack: number;\n private readonly release: number;\n private value = 0;\n\n constructor({ attack, release }: { attack: number; release: number }) {\n this.attack = attack;\n this.release = release;\n }\n\n next(target: number): number {\n this.value +=\n (target - this.value) *\n (target > this.value ? this.attack : this.release);\n return this.value;\n }\n\n current(): number {\n return this.value;\n }\n}\n","import type {\n WidgetCompanionLayoutU,\n WidgetSidebarModeU,\n} from '../types/widget-config';\n\n/** The sidebar side after `auto` has been resolved against the host dir. */\nexport type WidgetSidebarSideResolvedU = 'left' | 'right';\n\nexport const DEFAULT_COMPANION_LAYOUTS = [\n 'compact',\n 'sidebar',\n 'fullscreen',\n] as const satisfies readonly WidgetCompanionLayoutU[];\n\nconst COMPANION_LAYOUTS = new Set<WidgetCompanionLayoutU>(\n DEFAULT_COMPANION_LAYOUTS,\n);\n\nfunction isCompanionLayout(value: unknown): value is WidgetCompanionLayoutU {\n return COMPANION_LAYOUTS.has(value as WidgetCompanionLayoutU);\n}\n\n/**\n * Resolve the layouts available to the companion. Configured order is part of\n * the public contract, so it is preserved while duplicates and invalid runtime\n * values are discarded. An omitted or unusable list falls back to every\n * layout, keeping the result non-empty for all consumers.\n */\nexport function normalizeCompanionLayouts(\n layouts?: unknown,\n): readonly WidgetCompanionLayoutU[] {\n if (!Array.isArray(layouts)) return DEFAULT_COMPANION_LAYOUTS;\n\n const normalized: WidgetCompanionLayoutU[] = [];\n const seen = new Set<WidgetCompanionLayoutU>();\n for (const layout of layouts) {\n if (!isCompanionLayout(layout) || seen.has(layout)) continue;\n seen.add(layout);\n normalized.push(layout);\n }\n\n return normalized.length > 0 ? normalized : DEFAULT_COMPANION_LAYOUTS;\n}\n\n/** Choose an allowed initial/fallback layout for the companion shell. */\nexport function resolveCompanionDefaultLayout(\n configuredDefault: unknown,\n allowedLayouts: readonly WidgetCompanionLayoutU[],\n): WidgetCompanionLayoutU {\n if (\n isCompanionLayout(configuredDefault) &&\n allowedLayouts.includes(configuredDefault)\n ) {\n return configuredDefault;\n }\n return allowedLayouts[0] ?? DEFAULT_COMPANION_LAYOUTS[0];\n}\n\n/**\n * Resolve the physical edge the sidebar occupies. `auto` (and any unusable\n * runtime value) follows the host document's direction — the inline-end edge,\n * which is the historical behavior — while an explicit side wins in both\n * directions.\n */\nexport function resolveSidebarSide(\n side: unknown,\n dir: string,\n): WidgetSidebarSideResolvedU {\n if (side === 'left' || side === 'right') return side;\n return dir === 'rtl' ? 'left' : 'right';\n}\n\n/** Resolve how the sidebar coexists with the page; anything but `docked` floats. */\nexport function resolveSidebarMode(mode: unknown): WidgetSidebarModeU {\n return mode === 'docked' ? 'docked' : 'floating';\n}\n"],"names":["isAgentStreamKeepalive","part","isTurnSteeredPart","PREFIX","log","message","details","defaultOnError","onErrorOptions","basicClient","options","client","createClient","middlewares","STREAM_PATH","RECONNECT_PATH","streamUrl","baseUrl","path","sessionId","ApiCaller","config","token","headers","request","key","value","definedHeaders","response","presentation","data","language","body","abortSignal","cursor","filters","file","onProgress","resolve","reject","formData","xhr","event","percentage","error","uploadUrl","_a","_b","isExhaustive","funcName","PrimitiveState","state","newState","isEqual","_s","callback","Poller","cb","intervalMs","timeouts","poll","runCatching","result","ActiveSessionPollingCtx","api","sessionCtx","messageCtx","sessionPollingIntervalSeconds","session","signal","isInitialFetch","prevMessages","newMessages","msg","newMsg","existingMsg","m","newMessage","history","commonFields","action","responseBodyText","parsed","ContactCtx","storageCtx","_c","_d","persistedToken","_e","_g","_f","_h","_j","_i","_l","_k","_n","_m","payload","extraCollectedData","e","persistedExternalId","externalId","v4","UploadCtx","files","pending","id","controller","update","progress","genUuid","uuidv4","CsatCtx","currentSessionId","uuid","COMMANDS","SUPPORTED_LANGUAGES","isCommandLanguage","escapeRegex","s","buildGrammar","languages","entries","c","lang","phrase","alternation","a","b","before","grammarCache","grammarFor","grammar","deleteLastSentence","text","trimmed","cut","ch","LOWERCASE_AFTER_BREAK_REGEX","capitalizeAfterBreaks","brk","endsAtSentenceBoundary","DictationCommandUtils","raw","pendingTail","consumable","regex","out","control","match","maxLen","len","start","tail","candidate","DRIP_INTERVAL_MS","DRIP_BACKLOG_CHARS","DictationDripUtils","displayed","processed","backlog","locale","lower","primary","REUSE_SAFETY_MARGIN_MS","DictationMintCache","expiresAtMs","mintFresh","valid","mint","isRecord","parseServerEvent","REALTIME_CALLS_URL","MAX_SESSION_MS","CONNECT_TIMEOUT_MS","DISCONNECT_GRACE_MS","DictationMicrophoneError","DictationSession","mintToken","onDelta","onState","onError","onLevel","micPromise","stream","t","pc","track","dc","offer","sdpResponse","answerSdp","type","delta","audioContext","source","analyser","tick","sum","i","centered","rms","code","SILENCE_COMMAND_MS","IDLE","DictationCtx","target","level","sessionState","silenceControl","endingSession","endingTarget","send","ArabicLanguage","BengaliLanguage","BulgarianLanguage","CzechLanguage","DanishLanguage","GreekLanguage","GermanLanguage","EnglishLanguage","SpanishLanguage","FilipinoLanguage","FinnishLanguage","FrenchLanguage","HindiLanguage","ItalianLanguage","JapaneseLanguage","KoreanLanguage","DutchLanguage","NorwegianLanguage","PolishLanguage","PortugueseLanguage","RomanianLanguage","SwedishLanguage","RussianLanguage","ThaiLanguage","TurkishLanguage","UrduLanguage","VietnameseLanguage","ChineseSimplifiedLanguage","CroatianLanguage","EstonianLanguage","HungarianLanguage","IcelandicLanguage","LatvianLanguage","LithuanianLanguage","LuxembourgishLanguage","MalteseLanguage","NorwegianBokmalLanguage","SlovakLanguage","LANGUAGES","isSupportedLanguage","RTL_LANGUAGES","isRtlLanguage","resolveLanguage","getTranslation","overrides","params","name","translate","SessionCtx","contactCtx","sessionsPollingIntervalSeconds","sharedSessions","active","openSessionId","contact","first","retry","customData","hookError","deduped","self","sessions","currentSession","session_id","mergeSendContext","input","sendsPageContext","configContext","resolveConfigContext","mentions","mentionOnTheWire","merged","withoutKey","title","meta","record","_dropped","rest","err","resolveSendFeatures","features","buildSendMessageBody","content","initialMessages","_MessageCtx","streaming","getClientCapabilities","getRequestConfig","isStreaming","getSendsPageContext","handlers","buffered","messageIds","ids","messages","nextMessages","built","userMessage","optimisticMessageIds","messageId","index","delivered","localAbortController","isAssignedToAI","isSendingToAI","lastMessage","staged","botMessage","errorMessage","currentMessages","attachments","markedElements","messageContent","_","clientContext","marked","mark","elements","note","snapshotUrl","MessageCtx","RouterCtx","widget","isInitialFetchLoading","restored","mostRecentOpenSessionId","unsubscribe","StorageCtx","storage","orgToken","preference","offset","width","side","layout","mode","resolveWidgetAgent","org","agent","narrowFeature","orgEnabled","embedToggle","resolveClientFeatures","toggles","WidgetInitializationError","_WidgetCtx","modes","parent","conversation","externalConfig","WidgetCtx","resolveClientPresentation","DictationLevelSmoother","attack","release","DEFAULT_COMPANION_LAYOUTS","COMPANION_LAYOUTS","isCompanionLayout","normalizeCompanionLayouts","layouts","normalized","seen","resolveCompanionDefaultLayout","configuredDefault","allowedLayouts","resolveSidebarSide","dir","resolveSidebarMode"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/api/agent-stream-parts.ts","../src/api/elicitation.ts","../src/utils/log.ts","../src/api/client.ts","../src/api/api-caller.ts","../src/utils/is-exhaustive.ts","../src/utils/PrimitiveState.ts","../src/utils/Poller.ts","../src/utils/run-catching.ts","../src/context/active-session-polling.ctx.ts","../src/context/contact.ctx.ts","../src/context/upload.ctx.ts","../src/utils/uuid.ts","../src/context/csat.ctx.ts","../src/dictation/dictation-commands.utils.ts","../src/dictation/dictation-drip.utils.ts","../src/dictation/dictation-mint-cache.ts","../src/utils/is-record.ts","../src/dictation/dictation-session.ts","../src/context/dictation.ctx.ts","../src/translation/ar.ts","../src/translation/bn.ts","../src/translation/bg.ts","../src/translation/cs.ts","../src/translation/da.ts","../src/translation/el.ts","../src/translation/de.ts","../src/translation/en.ts","../src/translation/es.ts","../src/translation/fil.ts","../src/translation/fi.ts","../src/translation/fr.ts","../src/translation/hi.ts","../src/translation/it.ts","../src/translation/ja.ts","../src/translation/ko.ts","../src/translation/nl.ts","../src/translation/no.ts","../src/translation/pl.ts","../src/translation/pt.ts","../src/translation/ro.ts","../src/translation/sv.ts","../src/translation/ru.ts","../src/translation/th.ts","../src/translation/tr.ts","../src/translation/ur.ts","../src/translation/vi.ts","../src/translation/zh-cn.ts","../src/translation/hr.ts","../src/translation/et.ts","../src/translation/hu.ts","../src/translation/is.ts","../src/translation/lv.ts","../src/translation/lt.ts","../src/translation/lb.ts","../src/translation/mt.ts","../src/translation/nb.ts","../src/translation/sk.ts","../src/translation/index.ts","../src/context/session.ctx.ts","../src/context/message.ctx.ts","../src/context/router.ctx.ts","../src/context/storage.ctx.ts","../src/context/widget-agent.ts","../src/context/widget.ctx.ts","../src/context/resolve-client-presentation.ts","../src/dictation/dictation-level-smoother.ts","../src/utils/companion-layout.ts"],"sourcesContent":["/**\n * The v5 stream's protocol-level data parts the client classifies a stream by.\n * Neither renders anything: the widget only needs to recognise them.\n */\n\n/**\n * The idle heartbeat. While a request waits — a message waiting to join the\n * session's live turn, or a turn that has not spoken yet — the backend emits\n * one so an idle timeout never cuts the connection. It is a `transient`\n * part: the protocol delivers it and never adds it to the message. Readers\n * that classify a stream by its first chunk must skip it.\n */\nexport const isAgentStreamKeepalive = (part: { type: string }): boolean =>\n part.type === 'data-keepalive';\n\n/**\n * The stream's answer to a message POSTed while the session already had a\n * live turn: the message was STEERED into that turn (no new turn, no reply\n * of its own — the live turn's single reply answers both messages). The\n * request's own stream carries exactly this part and ends.\n */\nexport const isTurnSteeredPart = (part: { type: string }): boolean =>\n part.type === 'data-turn-steered';\n","import { z } from 'zod';\nconst option = z.object({ const: z.string(), title: z.string().optional() });\nconst field = z.object({\n type: z.enum(['string', 'number', 'integer', 'boolean', 'array']),\n title: z.string().optional(),\n description: z.string().optional(),\n default: z\n .union([z.string(), z.number(), z.boolean(), z.array(z.string())])\n .optional(),\n enum: z.array(z.string()).optional(),\n oneOf: z.array(option).optional(),\n items: z\n .object({\n enum: z.array(z.string()).optional(),\n anyOf: z.array(option).optional(),\n })\n .optional(),\n minItems: z.number().int().nonnegative().optional(),\n maxItems: z.number().int().nonnegative().optional(),\n minimum: z.number().optional(),\n maximum: z.number().optional(),\n minLength: z.number().optional(),\n maxLength: z.number().optional(),\n format: z.string().optional(),\n});\nexport const elicitationListSchema = z.array(\n z.object({\n id: z.string(),\n serverId: z.string(),\n serverName: z.string(),\n expiresAt: z.number(),\n approvalKey: z.string().optional(),\n form: z.object({\n message: z.string(),\n requestedSchema: z.object({\n properties: z.record(z.string(), field),\n required: z.array(z.string()).optional(),\n }),\n }),\n }),\n);\nexport type ElicitationRequest = z.infer<typeof elicitationListSchema>[number];\nexport type ElicitationResponse = {\n action: 'accept' | 'decline' | 'cancel';\n remember?: boolean;\n content?: Record<string, string | number | boolean | string[]>;\n};\n\nexport const approvalPreferencesSchema = z.array(\n z.object({\n key: z.string(),\n serverId: z.string(),\n serverName: z.string(),\n message: z.string(),\n toolName: z.string(),\n }),\n);\nexport type ApprovalPreference = z.infer<\n typeof approvalPreferencesSchema\n>[number];\n","/**\n * The widget runs inside customers' pages, so every line it writes to the\n * console carries one attributable prefix. Use this instead of `console.*`.\n */\nconst PREFIX = '[opencx]';\n\nexport const log = {\n warn: (message: string, ...details: unknown[]): void => {\n console.warn(`${PREFIX} ${message}`, ...details);\n },\n error: (message: string, ...details: unknown[]): void => {\n console.error(`${PREFIX} ${message}`, ...details);\n },\n};\n","import createClient, { type Middleware } from 'openapi-fetch';\nimport { log } from '../utils/log';\nimport type { paths } from './schema';\nimport type { components } from './schema';\n\ntype Options = {\n baseUrl: string;\n onRequest?: Middleware['onRequest'];\n onResponse?: Middleware['onResponse'];\n onError?: Middleware['onError'];\n};\n\nconst defaultOnError: Middleware['onError'] = (onErrorOptions) => {\n log.error('request failed', onErrorOptions.error);\n};\n\nexport const basicClient = (options: Options) => {\n const client = createClient<paths>({\n baseUrl: options.baseUrl,\n });\n\n const middlewares: Middleware = {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n onError: options.onError || defaultOnError,\n };\n\n client.use(middlewares);\n return client;\n};\n\nexport type Endpoint = keyof paths;\nexport type Dto = components['schemas'];\n","import {\n approvalPreferencesSchema,\n elicitationListSchema,\n type ElicitationResponse,\n} from './elicitation';\nimport { type Dto, type Endpoint, basicClient } from './client';\nimport type { paths } from './schema';\nimport type { DictationMint } from '../dictation/dictation-session';\nimport type { WidgetConfig } from '../types/widget-config';\nimport type {\n AgentTurnMessagesDto,\n ResolveSessionDto,\n SendMessageDto,\n VoteInputDto,\n} from '../types/dtos';\nimport { log } from '../utils/log';\n\ntype ConnectionStartResult = NonNullable<\n paths['/backend/widget/v5/connections/{serverId}/start']['post']\n>['responses'][201]['content']['application/json'];\ntype ConnectionAttemptStatus = NonNullable<\n paths['/backend/widget/v5/connections/{serverId}/attempts/{attemptId}']['get']\n>['responses'][200]['content']['application/json']['status'];\n\nexport class ConnectionRequestExpiredError extends Error {\n constructor() {\n super('This connection request expired. Preparing a new request.');\n this.name = 'ConnectionRequestExpiredError';\n }\n}\n\nexport class ConnectionAttemptUnavailableError extends Error {\n constructor() {\n super('This connection attempt is no longer available.');\n this.name = 'ConnectionAttemptUnavailableError';\n }\n}\n\n/**\n * The two stream endpoints the AI SDK transport hits directly (it needs raw\n * URLs, not the typed client). Everything else goes through `this.client`.\n */\nconst STREAM_PATH = '/backend/widget/v5/chat/stream' satisfies Endpoint;\nconst RECONNECT_PATH =\n '/backend/widget/v5/chat/{sessionId}/stream' satisfies Endpoint;\n\nconst streamUrl = (baseUrl: string, path: string, sessionId?: string) =>\n `${baseUrl.replace(/\\/$/, '')}${\n sessionId\n ? path.replace('{sessionId}', encodeURIComponent(sessionId))\n : path\n }`;\n\nexport class ApiCaller {\n private client: ReturnType<typeof basicClient>;\n private config: WidgetConfig;\n private userToken: string | null = null;\n\n constructor({ config }: { config: WidgetConfig }) {\n this.config = config;\n this.userToken = config.user?.token || null;\n\n const { baseUrl, headers } = this.constructClientOptions(\n config.user?.token,\n );\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n }\n\n private constructClientOptions = (token: string | null | undefined) => {\n const baseUrl =\n import.meta.env.MODE === 'test'\n ? 'http://localhost:8080'\n : this.config.apiUrl || 'https://api.open.cx';\n const headers = {\n 'X-Bot-Token': this.config.token,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: token ? `Bearer ${token}` : undefined,\n };\n\n return { baseUrl, headers };\n };\n\n private createOpenAPIClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n return basicClient({\n baseUrl,\n onRequest: ({ request }) => {\n Object.entries(headers).forEach(([key, value]) => {\n if (value) {\n request.headers.set(key, value);\n }\n });\n },\n });\n };\n\n listApprovalPreferences = async () => {\n const { baseUrl, headers } = this.getStreamAuthContext();\n const response = await fetch(\n `${baseUrl}/backend/widget/v5/connections/approval-preferences`,\n { headers },\n );\n if (!response.ok) throw new Error('Could not load permissions.');\n return approvalPreferencesSchema.parse(await response.json());\n };\n\n revokeApprovalPreference = async (serverId: string, key: string) => {\n const { baseUrl, headers } = this.getStreamAuthContext();\n const response = await fetch(\n `${baseUrl}/backend/widget/v5/connections/${encodeURIComponent(serverId)}/approval-preferences/${encodeURIComponent(key)}`,\n { method: 'DELETE', headers },\n );\n if (!response.ok) throw new Error('Could not reset permission.');\n };\n\n listElicitations = async (sessionId: string, signal?: AbortSignal) => {\n const { baseUrl, headers } = this.getStreamAuthContext();\n const response = await fetch(\n `${baseUrl}/backend/widget/v5/connections/elicitation/${encodeURIComponent(sessionId)}`,\n { headers, signal },\n );\n if (!response.ok) throw new Error('Could not load the request.');\n return elicitationListSchema.parse(await response.json());\n };\n\n answerElicitation = async (\n sessionId: string,\n requestId: string,\n answer: ElicitationResponse,\n ) => {\n const { baseUrl, headers } = this.getStreamAuthContext();\n const response = await fetch(\n `${baseUrl}/backend/widget/v5/connections/elicitation/${encodeURIComponent(sessionId)}/${encodeURIComponent(requestId)}`,\n {\n method: 'POST',\n headers: { ...headers, 'Content-Type': 'application/json' },\n body: JSON.stringify(answer),\n },\n );\n if (!response.ok)\n throw new Error(\n response.status === 400\n ? 'Check your answers and try again.'\n : 'This request has ended. Ask the agent to try again.',\n );\n };\n\n listConnections = async (signal?: AbortSignal) => {\n const { data, error } = await this.client.GET(\n '/backend/widget/v5/connections',\n { signal },\n );\n if (error || !data)\n throw new Error('Could not load connections. Sign in and try again.');\n return data;\n };\n\n startConnection = async (\n serverId: string,\n requestId: string,\n signal?: AbortSignal,\n ): Promise<ConnectionStartResult> => {\n const { data, error, response } = await this.client.POST(\n '/backend/widget/v5/connections/{serverId}/start',\n {\n params: { path: { serverId } },\n body: { request_id: requestId },\n signal,\n },\n );\n if (response.status === 410) throw new ConnectionRequestExpiredError();\n if (response.status === 404)\n throw new Error('This connection request is no longer available.');\n if (error || !data)\n throw new Error('Could not start this connection. Please try again.');\n return data;\n };\n\n getConnectionAttempt = async (\n serverId: string,\n attemptId: string,\n signal?: AbortSignal,\n ): Promise<ConnectionAttemptStatus> => {\n const { data, error, response } = await this.client.GET(\n '/backend/widget/v5/connections/{serverId}/attempts/{attemptId}',\n {\n params: { path: { serverId, attemptId } },\n signal,\n },\n );\n if ([401, 403, 404].includes(response.status))\n throw new ConnectionAttemptUnavailableError();\n if (error || !data)\n throw new Error(`Could not check the connection (${response.status}).`);\n return data.status;\n };\n\n disconnectConnection = async (serverId: string) => {\n const { error } = await this.client.DELETE(\n '/backend/widget/v5/connections/{serverId}',\n {\n params: { path: { serverId } },\n },\n );\n if (error) throw new Error('Could not disconnect. Please try again.');\n };\n\n setAuthToken = (token: string) => {\n this.userToken = token;\n const { baseUrl, headers } = this.constructClientOptions(token);\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n };\n\n /**\n * AUTH headers only (X-Bot-Token / Authorization), stripped of\n * content-type/accept. The transport sets its own Content-Type, and a second\n * (case-differing) copy gets COMBINED by the Headers init into\n * \"application/json, application/json\" — which the server rejects (415). Also\n * reused for the reconnect/stop control calls (empty-body POST/GET).\n */\n private getStreamAuthContext = (): {\n baseUrl: string;\n headers: Record<string, string>;\n } => {\n const { baseUrl, headers } = this.constructClientOptions(this.userToken);\n const definedHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value !== 'string') continue;\n if (['content-type', 'accept'].includes(key.toLowerCase())) continue;\n definedHeaders[key] = value;\n }\n return { baseUrl, headers: definedHeaders };\n };\n\n /**\n * Wiring for the agent-chat streaming adapter: the send endpoint, the\n * session-scoped reconnect endpoint, and the shared auth headers.\n * Computed lazily so a later `setAuthToken` is always reflected.\n */\n getStreamTransportOptions = (): {\n api: string;\n reconnectApi: (sessionId: string) => string;\n headers: Record<string, string>;\n } => {\n const { baseUrl, headers } = this.getStreamAuthContext();\n return {\n api: streamUrl(baseUrl, STREAM_PATH),\n reconnectApi: (sessionId: string) =>\n streamUrl(baseUrl, RECONNECT_PATH, sessionId),\n headers,\n };\n };\n\n /**\n * Stop / interrupt the session's in-flight streamed turn. With resumable\n * streams on, a client abort is treated as a disconnect (the stream\n * survives), so a real \"stop\" is this explicit call — the backend cancels\n * generation and clears the resume pointer. Throws on failure — the caller\n * decides how to react, so a failed cancel is never mistaken for an ACKed\n * one.\n */\n stopStream = async (sessionId: string): Promise<void> => {\n const { response } = await this.client.POST(\n '/backend/widget/v5/chat/{sessionId}/stop',\n { params: { path: { sessionId } } },\n );\n if (!response.ok) {\n throw new Error(`Failed to stop stream: ${response.status}`);\n }\n };\n\n /**\n * The session's settled agent turns with their final UIMessage parts and\n * the transcript rows each produced — the reload-fidelity read (widget v5).\n * Returns null on any failure: the caller then keeps the plain-row\n * rendering, exactly the pre-feature behavior.\n */\n getAgentTurnMessages = async (\n sessionId: string,\n presentation?: WidgetConfig['presentation'],\n ): Promise<AgentTurnMessagesDto | null> => {\n const { data, response } = await this.client.GET(\n '/backend/widget/v5/chat/{sessionId}/messages',\n {\n params: {\n path: { sessionId },\n query: {\n toolActivity: presentation?.toolActivity,\n reasoning:\n presentation?.reasoning === undefined\n ? undefined\n : presentation.reasoning\n ? 'true'\n : 'false',\n },\n },\n },\n );\n if (!data) {\n log.warn('agent turn messages fetch failed', response.status);\n return null;\n }\n return {\n ...data,\n handled_connection_request_ids: data.handled_connection_request_ids ?? [],\n };\n };\n\n /**\n * Mint a short-lived transcription token for voice dictation (widget v5).\n * Org-gated server-side; throws on any failure so the caller can surface\n * \"dictation unavailable\" instead of hanging with an open mic.\n */\n createDictationSession = async ({\n language,\n }: {\n language?: string | undefined;\n }): Promise<DictationMint> => {\n const { data, response } = await this.client.POST(\n '/backend/widget/v5/dictation/sessions',\n { body: language ? { language } : {} },\n );\n if (!data) {\n throw new Error(`Failed to start dictation: ${response.status}`);\n }\n return data;\n };\n\n getExternalWidgetConfig = async () => {\n return await this.client.GET('/backend/widget/v2/config', {\n params: {\n header: { 'x-bot-token': this.config.token },\n },\n });\n };\n\n sendMessage = async (body: SendMessageDto, abortSignal?: AbortSignal) => {\n return await this.client.POST('/backend/widget/v2/chat/send', {\n body,\n signal: abortSignal,\n });\n };\n\n createUnverifiedContact = async (body: Dto['CreateUnverifiedContactDto']) => {\n return await this.client.POST(\n '/backend/widget/v2/contact/create-unverified',\n {\n params: { header: { 'x-bot-token': this.config.token } },\n body,\n },\n );\n };\n\n createSession = async (\n body: Dto['CreateWidgetSessionDto'],\n abortSignal?: AbortSignal,\n ) => {\n return await this.client.POST('/backend/widget/v2/create-session', {\n body,\n signal: abortSignal,\n });\n };\n\n pollSessionAndHistory = async ({\n sessionId,\n abortSignal,\n }: {\n sessionId: string;\n abortSignal: AbortSignal;\n }) => {\n return await this.client.GET('/backend/widget/v2/poll/{sessionId}', {\n params: { path: { sessionId } },\n signal: abortSignal,\n });\n };\n\n getSessions = async ({\n cursor,\n filters,\n abortSignal,\n }: {\n /** Opaque pagination token: the `next` value from the previous page (the backend paginates by `offset`). */\n cursor: string | undefined;\n filters: Record<string, string>;\n abortSignal?: AbortSignal;\n }) => {\n return await this.client.GET('/backend/widget/v2/sessions', {\n params: {\n query: {\n offset: cursor,\n filters: JSON.stringify(filters),\n },\n },\n signal: abortSignal,\n });\n };\n\n /**\n * openapi-fetch usually works fine for file uploads, but this time around it parses the payload in a weird way and results in 413 errors (payload too large)\n * Anyway, good old XHR even does it better with progress events\n */\n uploadFile = async ({\n file,\n abortSignal,\n onProgress,\n }: {\n file: File;\n abortSignal: AbortSignal;\n onProgress?: (percentage: number) => void;\n }): Promise<Dto['UploadWidgetFileResponseDto']> => {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append('file', file);\n\n const xhr = new XMLHttpRequest();\n\n // Set up abort functionality\n if (abortSignal) {\n abortSignal.addEventListener('abort', () => {\n xhr.abort();\n reject(new DOMException('Aborted', 'AbortError'));\n });\n\n // If already aborted, reject immediately\n if (abortSignal.aborted) {\n reject(new DOMException('Aborted', 'AbortError'));\n return;\n }\n }\n\n xhr.upload.addEventListener('progress', (event) => {\n if (event.lengthComputable && onProgress) {\n const percentage = Math.round((event.loaded / event.total) * 100);\n onProgress(percentage);\n }\n });\n\n // Handle completion\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const data = JSON.parse(xhr.responseText);\n resolve(data);\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`));\n }\n } else {\n reject(new Error(`Upload failed with status: ${xhr.status}`));\n }\n });\n\n xhr.addEventListener('error', () => {\n reject(new Error('Network error occurred'));\n });\n\n xhr.addEventListener('timeout', () => {\n reject(new Error('Upload timed out'));\n });\n\n const { baseUrl } = this.constructClientOptions(this.userToken);\n\n const path = '/backend/widget/v2/upload' satisfies Endpoint;\n const uploadUrl = `${baseUrl}${path}`;\n xhr.open('POST', uploadUrl);\n\n xhr.setRequestHeader('X-Bot-Token', this.config.token);\n const userToken = this.userToken ?? this.config.user?.token;\n if (userToken) {\n xhr.setRequestHeader('Authorization', `Bearer ${this.userToken}`);\n } else {\n log.error('user token not set');\n }\n\n xhr.send(formData);\n });\n };\n\n vote = async (body: VoteInputDto) => {\n return await this.client.POST('/backend/widget/v2/chat/vote', { body });\n };\n\n resolveSession = async (\n body: ResolveSessionDto,\n abortSignal?: AbortSignal,\n ) => {\n return await this.client.POST('/backend/widget/v2/session/resolve', {\n body,\n signal: abortSignal,\n });\n };\n\n createStateCheckpoint = async (\n body: Dto['WidgetCreateStateCheckpointInputDto'],\n ) => {\n return await this.client.POST('/backend/widget/v2/checkpoint', {\n body,\n });\n };\n\n submitCsat = async (body: Dto['WidgetSubmitCsatInputDto']) => {\n return await this.client.POST('/backend/widget/v2/submit-csat', { body });\n };\n}\n","import { log } from './log';\nexport function isExhaustive(value: never, funcName: string) {\n log.error(`missing case for ${value} in ${funcName}`);\n}\n","import isEqual from 'lodash.isequal';\nimport { log } from './log';\n\nexport type Subscriber<T> = (data: T) => void;\n\nexport class PrimitiveState<S> {\n private subscribers = new Set<Subscriber<S>>();\n private state: S;\n private initialState: S;\n\n constructor(state: S) {\n this.state = state;\n this.initialState = state;\n }\n\n get = (): S => this.state;\n\n set = (newState: S): void => {\n if (!isEqual(this.state, newState)) {\n this.state = newState;\n this.notifySubscribers(newState);\n }\n };\n\n setPartial = (_s: Partial<S>): void => {\n if (_s === undefined || _s === null) return;\n const newState = { ...this.state, ..._s };\n this.set(newState);\n };\n\n reset = (): void => {\n this.set(this.initialState);\n };\n\n private notifySubscribers = (state: S) => {\n const subscribersArray = Array.from(this.subscribers);\n subscribersArray.forEach((callback) => {\n try {\n callback(state);\n } catch (error) {\n if (import.meta.env.MODE !== 'test') {\n log.error('state subscriber threw', error);\n }\n }\n });\n };\n\n subscribe = (callback: Subscriber<S>): (() => void) => {\n this.subscribers.add(callback);\n\n return () => {\n this.subscribers.delete(callback);\n };\n };\n}\n","import { PrimitiveState } from './PrimitiveState';\nimport { log } from './log';\n\nexport type PollingState = {\n isPolling: boolean;\n isError: boolean;\n};\n\nexport class Poller {\n state = new PrimitiveState<PollingState>({\n isPolling: false,\n isError: false,\n });\n private abortController = new AbortController();\n\n reset = () => {\n this.abortController.abort('Resetting poller');\n this.stopPolling?.();\n this.stopPolling = null;\n };\n\n private stopPolling: (() => void) | null = null;\n\n startPolling = (\n cb: (abortSignal: AbortSignal) => Promise<void>,\n intervalMs: number,\n ) => {\n if (this.stopPolling) return;\n\n const timeouts: ReturnType<typeof setTimeout>[] = [];\n\n const poll = async () => {\n this.abortController = new AbortController();\n this.state.setPartial({ isPolling: true });\n\n try {\n await cb(this.abortController.signal);\n } catch (error) {\n if (this.abortController.signal.aborted) {\n // If aborted, just return and do not schedule the nest poll\n return;\n }\n log.error('failed to poll', error);\n this.state.setPartial({ isError: true });\n } finally {\n this.state.setPartial({ isPolling: false });\n }\n\n // Do not reschedule after a reset, including when the callback handles\n // cancellation without throwing.\n if (!this.abortController.signal.aborted) {\n timeouts.push(setTimeout(poll, intervalMs));\n }\n };\n\n poll();\n\n this.stopPolling = () => {\n timeouts.forEach(clearTimeout);\n this.state.reset();\n };\n };\n}\n","export function run<T>(fn: () => T): T {\n return fn();\n}\n\nexport type Result<T, E> =\n | { data: T; error?: undefined }\n | { data?: undefined; error: E };\n\n/**\n * Many thanks to @m-tabaza for this utility... Kotlin vibes\n */\nexport function runCatching<T, E = unknown>(\n callback: () => Promise<T>,\n): Promise<Result<T, E>>;\nexport function runCatching<T, E = unknown>(callback: () => T): Result<T, E>;\nexport function runCatching<T, E = unknown>(\n callback: () => T | Promise<T>,\n): Result<T, E> | Promise<Result<T, E>> {\n try {\n const result = callback();\n\n if (result instanceof Promise) {\n return result.then((data) => ({ data })).catch((error: E) => ({ error }));\n }\n\n return { data: result };\n } catch (error) {\n return { error: error as E };\n }\n}\n","import type { ApiCaller } from '../api/api-caller';\nimport type { ActionCallDto, MessageDto } from '../types/dtos';\nimport {\n type WidgetMessageU,\n type WidgetSystemMessageU,\n} from '../types/messages';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { isExhaustive } from '../utils/is-exhaustive';\nimport { Poller } from '../utils/Poller';\nimport { runCatching } from '../utils/run-catching';\nimport type { MessageCtx } from './message.ctx';\nimport type { SessionCtx } from './session.ctx';\nimport { log } from '../utils/log';\n\nexport class ActiveSessionPollingCtx {\n private api: ApiCaller;\n private config: WidgetConfig;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n private sessionPollingIntervalSeconds: number;\n\n private poller = new Poller();\n private fetchSessionAndFullHistoryAbortController = new AbortController();\n private reconcileAbortController = new AbortController();\n private subscriptions: Array<() => void> = [];\n /** Session the in-flight post-stream reconcile belongs to, if any. */\n private reconcilingSessionId: string | null = null;\n\n constructor({\n api,\n config,\n sessionCtx,\n messageCtx,\n sessionPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n sessionPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.config = config;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n this.sessionPollingIntervalSeconds = sessionPollingIntervalSeconds;\n\n this.registerPolling();\n }\n\n private registerPolling = () => {\n this.subscriptions.push(\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n this.fetchSessionAndHistory({\n sessionId: session.id,\n abortSignal,\n });\n }, this.sessionPollingIntervalSeconds * 1000);\n } else {\n this.poller.reset();\n }\n }),\n );\n\n /**\n * When the session is closed, fetch immediately instead of waiting for the\n * next poll tick, so closing messages (e.g. csat_requested) show up right away.\n */\n this.subscriptions.push(\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id && !session.isOpened) {\n try {\n this.fetchSessionAndFullHistoryAbortController =\n new AbortController();\n this.fetchSessionAndHistory({\n sessionId: session.id,\n abortSignal:\n this.fetchSessionAndFullHistoryAbortController.signal,\n });\n } catch (error) {\n if (\n !this.fetchSessionAndFullHistoryAbortController.signal.aborted\n ) {\n log.error('failed to fetch session and full history', error);\n }\n }\n } else {\n this.fetchSessionAndFullHistoryAbortController.abort();\n }\n }),\n );\n\n /**\n * A post-stream reconcile still in flight when the active session stops\n * being the one it was started for (new chat, session switch) must not\n * land: its rows belong to the old conversation and would be appended to\n * the fresh transcript.\n */\n this.subscriptions.push(\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (this.reconcilingSessionId === null) return;\n if (session?.id === this.reconcilingSessionId) return;\n this.reconcileAbortController.abort();\n }),\n );\n };\n\n dispose = () => {\n this.poller.reset();\n this.fetchSessionAndFullHistoryAbortController.abort();\n this.reconcileAbortController.abort();\n this.reconcilingSessionId = null;\n this.subscriptions.forEach((unsubscribe) => unsubscribe());\n this.subscriptions = [];\n };\n\n /**\n * Ingest the canonical rows the backend persisted for a just-settled\n * streamed turn. Owns a REAL abort controller — cancelled on the session\n * boundary (see `registerPolling`), which is the whole point: the signal\n * this passes must be one somebody can actually fire.\n */\n reconcileAfterStream = async (sessionId: string): Promise<void> => {\n this.reconcileAbortController.abort();\n this.reconcileAbortController = new AbortController();\n const { signal } = this.reconcileAbortController;\n this.reconcilingSessionId = sessionId;\n try {\n await this.fetchSessionAndHistory({ sessionId, abortSignal: signal });\n } catch (error) {\n // An abort is this method doing its job, not a failure.\n if (!signal.aborted) throw error;\n } finally {\n if (this.reconcilingSessionId === sessionId) {\n this.reconcilingSessionId = null;\n }\n }\n };\n\n fetchSessionAndHistory = async ({\n sessionId,\n abortSignal,\n }: {\n sessionId: string;\n abortSignal: AbortSignal;\n }): Promise<void> => {\n /**\n * This is a bit of an implicit contract... there are two cases here\n * 1. If there are no messages in state, it means the user selected a previous session from the sessions screen and got routed to the chat,\n * in this case, we want to show a loading indicator until the initial fetch is done\n * 2. There is a single message in state, which is the optimistically rendered user message,\n * in this case, we don't want to show a loading indicator\n */\n const isInitialFetch = this.messageCtx.state.get().messages.length === 0;\n if (isInitialFetch) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: true });\n }\n\n const { data } = await this.api.pollSessionAndHistory({\n sessionId,\n abortSignal,\n });\n\n if (data?.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n this.sessionCtx.setSessions([data.session]);\n }\n\n if (data?.history && data.history.length > 0) {\n // Get a fresh reference to current messages after the poll is done\n const prevMessages = this.messageCtx.state.get().messages;\n const newMessages = data.history\n .map(this.mapHistoryToMessage)\n .filter((msg): msg is WidgetMessageU => msg !== null)\n .filter(\n (newMsg) =>\n !prevMessages.some((existingMsg) => existingMsg.id === newMsg.id),\n );\n // Only commit when the poll actually surfaced NEW rows. A poll that\n // returns only already-known messages must NOT replace the array with a\n // fresh reference — that re-renders the whole transcript on every tick\n // (visible flicker during a stream, and it remounts the lazy recharts\n // chart into an empty 0-measured ResponsiveContainer). The steady state\n // of an idle/streaming session is \"poll returns the same rows\", so this\n // guard is what keeps the surface still between real updates.\n if (newMessages.length > 0) {\n this.messageCtx.state.setPartial({\n messages: [...prevMessages, ...newMessages],\n });\n if (isInitialFetch) {\n // Opening an existing session: history flows in as one batch. The user\n // is loading context, not receiving new messages — suppress the hook\n // but seed the dedup set so later polls don't re-fire these ids.\n this.messageCtx.markAsDispatchedToOnMessageReceivedHook(\n newMessages.map((m) => m.id),\n );\n } else {\n for (const newMessage of newMessages) {\n this.messageCtx.dispatchToOnMessageReceivedHook(newMessage);\n }\n }\n }\n }\n\n if (this.messageCtx.state.get().isInitialFetchLoading) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: false });\n }\n };\n\n mapHistoryToMessage = (history: MessageDto): WidgetMessageU | null => {\n const commonFields = {\n id: history.publicId,\n timestamp: history.sentAt || '',\n attachments: history.attachments || undefined,\n };\n\n if (history.sender.kind === 'user') {\n return {\n ...commonFields,\n type: 'USER',\n content: history.content.text || '',\n // Backend field name (schema.ts) → widget vocabulary.\n markedElements: history.pickedElements,\n };\n }\n\n if (history.sender.kind === 'agent') {\n return {\n ...commonFields,\n type: 'AGENT',\n component: 'agent_message',\n data: {\n message: history.content.text || '',\n },\n agent: {\n name: history.sender.name || '',\n // Do not set avatarUrl from config here... let it be taken from the config at render time\n // Only set avatar url from the backend's response\n avatarUrl: history.sender.avatar || null,\n avatar: history.sender.avatar || null,\n id: null,\n isAi: false,\n },\n };\n }\n\n if (history.sender.kind === 'ai') {\n const action =\n history.actionCalls && history.actionCalls.length > 0\n ? history.actionCalls[history.actionCalls.length - 1]\n : undefined;\n\n return {\n ...commonFields,\n type: 'AI',\n component: 'bot_message',\n agent: {\n id: null,\n name: this.config.bot?.name || '',\n isAi: true,\n // Do not set avatarUrl from config here... let it be taken from the config at render time\n avatarUrl: null,\n avatar: null,\n },\n data: {\n message: history.content.text || '',\n action: action\n ? {\n name: action.actionName,\n data: this.extractActionResult(action),\n }\n : undefined,\n },\n };\n }\n\n if (history.sender.kind === 'system') {\n const message = this.constructSystemMessage(history);\n if (message === null) return null;\n\n return { ...message };\n }\n\n return null;\n };\n\n constructSystemMessage = (\n history: MessageDto,\n ): WidgetSystemMessageU | null => {\n if (!history || !history.systemMessagePayload) return null;\n switch (history.systemMessagePayload.type) {\n case 'state_checkpoint':\n return {\n id: history.publicId,\n type: 'SYSTEM',\n subtype: 'state_checkpoint',\n data: { payload: history.systemMessagePayload.payload },\n timestamp: history.sentAt || '',\n attachments: undefined,\n };\n case 'csat_requested':\n return {\n id: history.publicId,\n type: 'SYSTEM',\n subtype: 'csat_requested',\n data: { payload: undefined },\n timestamp: history.sentAt || '',\n attachments: undefined,\n };\n case 'csat_submitted':\n return {\n id: history.publicId,\n type: 'SYSTEM',\n subtype: 'csat_submitted',\n data: {\n payload: {\n score: history.systemMessagePayload.payload.score ?? undefined,\n feedback:\n history.systemMessagePayload.payload.feedback ?? undefined,\n },\n },\n timestamp: history.sentAt || '',\n attachments: undefined,\n };\n case 'none':\n return null;\n default:\n isExhaustive(\n history.systemMessagePayload,\n this.constructSystemMessage.name,\n );\n return null;\n }\n };\n\n extractActionResult = (action: ActionCallDto) => {\n const result = action.result;\n\n if (result === null) return result;\n if (typeof result !== 'object') return result;\n\n if (\n 'responseBodyText' in result &&\n typeof result.responseBodyText === 'string'\n ) {\n const responseBodyText = result.responseBodyText;\n const parsed = runCatching(() => JSON.parse(responseBodyText)).data;\n if (parsed) return parsed;\n }\n\n return action.result;\n };\n}\n","import { PrimitiveState } from '../utils/PrimitiveState';\nimport { ApiCaller } from '../api/api-caller';\nimport { type WidgetConfig } from '../types/widget-config';\nimport { type Dto } from '../api/client';\nimport type { StorageCtx } from './storage.ctx';\nimport { v4 } from 'uuid';\nimport { log } from '../utils/log';\n\ntype ContactState = {\n contact: {\n token: string;\n externalId: string | undefined;\n } | null;\n extraCollectedData: Record<string, string> | undefined;\n isCreatingUnverifiedContact: boolean;\n isErrorCreatingUnverifiedContact: boolean;\n};\n\nexport class ContactCtx {\n private config: WidgetConfig;\n private storageCtx?: StorageCtx;\n private api: ApiCaller;\n state: PrimitiveState<ContactState>;\n\n constructor({\n config,\n api,\n storageCtx,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n storageCtx?: StorageCtx;\n }) {\n this.config = config;\n this.storageCtx = storageCtx;\n this.api = api;\n\n this.state = new PrimitiveState<ContactState>({\n contact: config.user?.token\n ? {\n token: config.user.token,\n // Set optional externalId from config... not local storage\n externalId: config.user.externalId,\n }\n : null,\n extraCollectedData: undefined,\n isCreatingUnverifiedContact: false,\n isErrorCreatingUnverifiedContact: false,\n });\n\n this.autoCreateUnverifiedUserIfNotExists();\n }\n\n shouldCollectData = (): boolean => {\n if (!this.state.get().contact?.token && this.config.collectUserData) {\n return true;\n }\n return false;\n };\n\n private autoCreateUnverifiedUserIfNotExists = async () => {\n /**\n * If token is passed in config... we consider it as a verified user and do nothing (we don't force generate an externalId)\n * If a non-verified user take their token and place it in the config... the backend will refuse their requests saying that a non-verified token must have an externalId to create and get sessions\n */\n if (this.config.user?.token) return;\n\n /**\n * If collectUserData is true... we check if the user entered their credentials before, otherwise, show them the welcome screen so they can enter their credentials\n */\n if (this.config.collectUserData && !this.config.user?.data?.email) {\n /**\n * If extra data collection fields are passed,\n * we do not check for a persisted token.\n * This will force the contact to enter the extra data fields every time they visit the page.\n */\n if (this.config.extraDataCollectionFields?.length) {\n return;\n }\n\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n }\n // return early whether there is a persisted token or not\n return;\n }\n\n /**\n * If there is no email, then it is an anonymous contact, we check if the contact is persisted or we create a new one\n */\n if (!this.config.user?.data?.email) {\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n // return early only if there is a persisted token\n return;\n }\n }\n\n /**\n * If we reach here... then it is one of two\n * 1. There is an email passed in the config, let's just upsert the unverified contact without checking for persistence; maybe the email in the config did change.\n * 2. It is an anonymous contact (without an email) using this device for the first time.\n *\n * This is still safe even if the email in the config is tampered with by the contact, because there is a client-side externalId that will be generated for the current device...\n * So, only sessions created on this device will be accessible.\n */\n await this.createUnverifiedContact({\n email: this.config.user?.data?.email,\n non_verified_name: this.config.user?.data?.name,\n non_verified_custom_data: this.config.user?.data?.customData,\n });\n };\n\n createUnverifiedContact = async (\n payload: Dto['CreateUnverifiedContactDto'],\n extraCollectedData?: Record<string, string>,\n ): Promise<void> => {\n this.state.setPartial({ extraCollectedData });\n\n try {\n this.state.setPartial({\n isCreatingUnverifiedContact: true,\n isErrorCreatingUnverifiedContact: false,\n });\n\n const { data } = await this.api.createUnverifiedContact(payload);\n if (data?.token) {\n await this.setUnverifiedContact(data.token);\n } else {\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n }\n } catch (e) {\n // A THROWN failure (offline, DNS, 5xx) must land on the same state as a\n // response that carried no token — callers read the flag, not an\n // exception. Without this catch the rejection escapes to the widget's\n // fire-and-forget send (`void sendMessage(...)`) and surfaces as an\n // unhandled promise rejection in the EMBEDDER's page, while the flag\n // stays false so nothing in the UI ever reports the failure.\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n log.error('failed to create an unverified contact', {\n _e: e instanceof Error ? e.message : String(e),\n });\n } finally {\n this.state.setPartial({ isCreatingUnverifiedContact: false });\n }\n };\n\n /**\n * A persisted contact token can go stale — it no longer resolves to a\n * contact and the backend answers 401 \"Invalid token\". Drop the dead token,\n * clear auth, and mint a fresh anonymous contact so the widget self-heals\n * instead of getting stuck on create-session. No-op for a config-provided\n * verified token (authoritative — re-minting it is not ours to do).\n * Returns true if a fresh contact token was obtained.\n */\n recoverFromStaleToken = async (): Promise<boolean> => {\n if (this.config.user?.token) return false;\n this.api.setAuthToken('');\n // `null`, not `undefined` — `ContactState.contact` declares `| null` as its\n // one \"no contact\" sentinel, and a second representation eventually\n // disagrees with a `=== null` check somewhere downstream.\n this.state.setPartial({ contact: null });\n try {\n await this.storageCtx?.clearContactToken();\n // The remembered conversation belonged to the dead contact — the fresh\n // one must never be handed a pointer into somebody else's session.\n await this.storageCtx?.clearActiveSessionId();\n } catch (error) {\n // Storage is an embedder-provided adapter. A broken adapter must not keep\n // the runtime authenticated with a token the server already rejected.\n log.warn('failed to clear a stale contact token', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n await this.createUnverifiedContact({\n email: this.config.user?.data?.email,\n non_verified_name: this.config.user?.data?.name,\n non_verified_custom_data: this.config.user?.data?.customData,\n });\n return Boolean(this.state.get().contact?.token);\n };\n\n setUnverifiedContact = async (token: string) => {\n const persistedExternalId = await this.storageCtx?.getExternalContactId();\n /** Give priority to `externalId` from the config */\n const externalId: string =\n this.config.user?.externalId || persistedExternalId || v4();\n this.api.setAuthToken(token);\n // Set token in state after setting the token in the api handler\n await this.storageCtx?.setContactToken(token);\n await this.storageCtx?.setExternalContactId(externalId);\n this.state.setPartial({ contact: { token, externalId } });\n };\n}\n","import { v4 } from 'uuid';\nimport type { ApiCaller } from '../api/api-caller';\nimport { PrimitiveState } from '../utils/PrimitiveState';\n\nexport interface FileWithProgress {\n status: 'pending' | 'uploading' | 'success' | 'error';\n id: string;\n file: File;\n fileUrl?: string;\n progress: number;\n error?: string;\n}\n\n/** Attachments belong to their conversation, not the mounted composer. */\nexport class UploadCtx {\n state = new PrimitiveState<FileWithProgress[]>([]);\n private controllers = new Map<string, AbortController>();\n constructor(private api: ApiCaller) {}\n\n appendFiles = (files: File[]) => {\n const pending = files.map(\n (file): FileWithProgress => ({\n file,\n id: v4(),\n status: 'pending',\n progress: 0,\n }),\n );\n this.state.set([...this.state.get(), ...pending]);\n pending.forEach((file) => void this.upload(file));\n };\n\n private update(id: string, update: Partial<FileWithProgress>) {\n this.state.set(\n this.state\n .get()\n .map((file) => (file.id === id ? { ...file, ...update } : file)),\n );\n }\n\n private async upload(file: FileWithProgress) {\n const controller = new AbortController();\n this.controllers.set(file.id, controller);\n this.update(file.id, { status: 'uploading' });\n try {\n const response = await this.api.uploadFile({\n file: file.file,\n abortSignal: controller.signal,\n onProgress: (progress) => this.update(file.id, { progress }),\n });\n this.update(file.id, {\n status: 'success',\n fileUrl: response.fileUrl,\n progress: 100,\n });\n } catch (error) {\n if (!controller.signal.aborted)\n this.update(file.id, {\n status: 'error',\n progress: 0,\n error: error instanceof Error ? error.message : 'Upload failed',\n });\n } finally {\n this.controllers.delete(file.id);\n }\n }\n\n cancel = (id: string) => {\n this.controllers.get(id)?.abort();\n this.controllers.delete(id);\n this.state.set(this.state.get().filter((file) => file.id !== id));\n };\n\n reset = () => {\n this.controllers.forEach((controller) => controller.abort());\n this.controllers.clear();\n this.state.reset();\n };\n}\n","import { v4 as uuidv4 } from 'uuid';\n\nexport function genUuid() {\n return uuidv4();\n}\n","import type { ApiCaller } from '../api/api-caller';\nimport type { Dto } from '../api/client';\nimport { genUuid } from '../utils/uuid';\nimport type { MessageCtx } from './message.ctx';\nimport type { SessionCtx } from './session.ctx';\n\nexport class CsatCtx {\n private api: ApiCaller;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n\n constructor({\n api,\n sessionCtx,\n messageCtx,\n }: {\n api: ApiCaller;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n }) {\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n }\n\n submitCsat = async (\n body: Pick<Dto['WidgetSubmitCsatInputDto'], 'score' | 'feedback'>,\n ) => {\n const currentSessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!currentSessionId) {\n return { data: null, error: 'No session id found' };\n }\n\n const uuid = genUuid();\n this.messageCtx.state.setPartial({\n messages: [\n ...this.messageCtx.state.get().messages,\n {\n id: uuid,\n type: 'SYSTEM',\n subtype: 'csat_submitted',\n timestamp: new Date().toISOString(),\n data: {\n payload: {\n score: body.score,\n feedback: body.feedback,\n },\n },\n },\n ],\n });\n\n const { data, error } = await this.api.submitCsat({\n ...body,\n system_message_uuid: uuid,\n session_id: currentSessionId,\n });\n return { data, error };\n };\n}\n","/**\n * Spoken-command grammar for voice dictation.\n *\n * The transcription model already auto-punctuates and capitalizes, so spoken\n * punctuation (\"comma\", \"period\") is deliberately NOT converted — saying\n * punctuation aloud is optional and the words stay literal unless they form a\n * standalone command sentence. What IS recognized (Dragon-style) are\n * structural and control commands spoken as their own utterance:\n *\n * \"new line\" → line break\n * \"new paragraph\" → paragraph break\n * \"bullet point\"/\"next item\" → start a list item (\"- …\")\n * \"scratch that\"/\"delete that\"→ remove the previous sentence\n * \"stop dictation\"/\"stop listening\" → end the session\n * \"send message\"/\"send it\" → end the session and submit (composers)\n *\n * Precision guards:\n * - A phrase only counts as a command when the model rendered it as its own\n * sentence: preceded by start-of-text or sentence-ending punctuation, and\n * FOLLOWED by punctuation (the model punctuates a spoken pause — the pause\n * IS the signal, exactly like Dragon). \". Send it to the team\" never fires.\n * - A completed phrase at stream end with no punctuation yet stays PENDING\n * until the next delta disambiguates it — except in `final` mode (the user\n * stopped: stopping is the pause, so the phrase resolves as a command).\n * - Command phrases are scoped to English + the session's UI language, so an\n * Italian speaker's ordinary \"Cancella.\" can't fire scratch-that in an\n * English session and vice versa.\n */\n\nexport type DictationControlAction = 'stop' | 'send';\n\nexport interface ProcessedDictation {\n /** Text ready for insertion, with commands applied. */\n text: string;\n /**\n * Trailing raw characters withheld from insertion because they could still\n * grow into a command phrase (\"New paragr…\"), or ARE a completed phrase\n * awaiting its terminator (\"Send it\"). Empty in `final` mode.\n */\n pendingTail: string;\n /** Control command encountered (processing stops at that point). */\n control: DictationControlAction | null;\n}\n\nexport interface ProcessOptions {\n /** ISO language hint (same value sent to the transcription session). */\n language?: string | undefined;\n /**\n * End-of-stream semantics: the user stopped, so a completed command phrase\n * at the very end fires without waiting for punctuation, and no text is\n * withheld — partial phrases are released as literal words.\n */\n final?: boolean;\n}\n\ntype CommandAction =\n | 'newline'\n | 'newparagraph'\n | 'bullet'\n | 'scratch'\n | 'stop'\n | 'send';\n\ntype CommandLanguage = 'en' | 'es' | 'fr' | 'de' | 'pt' | 'it';\n\n// Latin-script languages with reliable word boundaries. Other languages still\n// dictate perfectly — they just use the composer's buttons instead of spoken\n// control phrases.\nconst COMMANDS: Array<{\n action: CommandAction;\n phrases: Record<CommandLanguage, string[]>;\n}> = [\n {\n action: 'newparagraph',\n phrases: {\n en: ['new paragraph'],\n es: ['nuevo párrafo', 'nuevo parrafo'],\n fr: ['nouveau paragraphe'],\n de: ['neuer absatz'],\n pt: ['novo parágrafo', 'novo paragrafo'],\n it: ['nuovo paragrafo'],\n },\n },\n {\n action: 'newline',\n phrases: {\n en: ['new line', 'newline'],\n es: ['nueva línea', 'nueva linea'],\n fr: ['nouvelle ligne', 'à la ligne', 'a la ligne'],\n de: ['neue zeile'],\n pt: ['nova linha'],\n it: ['nuova riga'],\n },\n },\n {\n action: 'bullet',\n phrases: {\n en: [\n 'bullet point',\n 'new bullet',\n 'next bullet',\n 'bullet list',\n 'list item',\n 'next item',\n 'new item',\n ],\n es: ['nuevo punto', 'nueva viñeta', 'nueva vineta'],\n fr: ['nouvelle puce'],\n de: ['neuer punkt', 'aufzählungspunkt'],\n pt: ['novo item', 'novo marcador'],\n it: ['nuovo punto', 'nuovo elenco'],\n },\n },\n {\n action: 'scratch',\n phrases: {\n en: ['scratch that', 'delete that'],\n es: ['bórralo', 'borra eso'],\n fr: ['efface ça', 'efface ca'],\n de: ['lösch das', 'losch das'],\n pt: ['apaga isso'],\n it: ['cancella'],\n },\n },\n {\n action: 'stop',\n phrases: {\n en: ['stop dictation', 'stop dictating', 'stop listening'],\n es: ['detener dictado'],\n fr: ['arrête la dictée', 'arrete la dictee'],\n de: ['diktat beenden'],\n pt: ['parar ditado'],\n it: ['stop dettatura'],\n },\n },\n {\n action: 'send',\n phrases: {\n en: ['send message', 'send it'],\n es: ['enviar mensaje'],\n fr: ['envoie le message'],\n de: ['nachricht senden'],\n pt: ['enviar mensagem'],\n it: ['invia messaggio'],\n },\n },\n];\n\nconst SUPPORTED_LANGUAGES: CommandLanguage[] = [\n 'en',\n 'es',\n 'fr',\n 'de',\n 'pt',\n 'it',\n];\n\nfunction isCommandLanguage(value: string): value is CommandLanguage {\n return (SUPPORTED_LANGUAGES as string[]).includes(value);\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\ninterface Grammar {\n /** Standalone-utterance matcher (terminator REQUIRED). */\n regex: RegExp;\n /** End-of-stream matcher (terminator optional — `$` counts as the pause). */\n finalRegex: RegExp;\n phraseToAction: Map<string, CommandAction>;\n longestPhrase: number;\n}\n\n// One alternation per language set, longest phrase first so \"new paragraph\"\n// wins over a shorter overlap. Boundaries:\n// before: start of text (tolerating leading whitespace — realtime deltas\n// are space-prefixed tokens), newline, or sentence-ending punctuation, as a\n// LOOKBEHIND so a command's own terminator stays available as the boundary\n// of a directly following command (\"…New line. New paragraph.\")\n// after: [.,!?;:] then (lookahead) whitespace or end.\nfunction buildGrammar(languages: CommandLanguage[]): Grammar {\n const entries = COMMANDS.flatMap((c) =>\n languages.flatMap((lang) =>\n c.phrases[lang].map((phrase) => ({ phrase, action: c.action })),\n ),\n );\n const alternation = entries\n .map((e) => escapeRegex(e.phrase))\n .sort((a, b) => b.length - a.length)\n .join('|');\n const before = String.raw`(?<=^\\s{0,3}|[.!?\\n]\\s{0,3})`;\n return {\n regex: new RegExp(\n `${before}(${alternation})` + String.raw`([.,!?;:])(?=\\s|$)`,\n 'giu',\n ),\n finalRegex: new RegExp(\n `${before}(${alternation})` + String.raw`([.,!?;:]?)(?=\\s|$)`,\n 'giu',\n ),\n phraseToAction: new Map(\n entries.map((e) => [e.phrase.toLowerCase(), e.action]),\n ),\n longestPhrase: Math.max(...entries.map((e) => e.phrase.length)),\n };\n}\n\nconst grammarCache = new Map<string, Grammar>();\n\nfunction grammarFor(language: string | undefined): Grammar {\n const lang =\n language && isCommandLanguage(language) && language !== 'en'\n ? language\n : null;\n const key = lang ?? 'en';\n let grammar = grammarCache.get(key);\n if (!grammar) {\n grammar = buildGrammar(lang ? ['en', lang] : ['en']);\n grammarCache.set(key, grammar);\n }\n return grammar;\n}\n\n/** Remove the last sentence (or last line when no terminator) from `text`. */\nfunction deleteLastSentence(text: string): string {\n const trimmed = text.replace(/\\s+$/, '');\n if (!trimmed) return '';\n // Ignore a terminator that ends the text itself, then cut after the previous one.\n const body = trimmed.replace(/[.!?]+$/, '');\n let cut = -1;\n for (let i = body.length - 1; i >= 0; i--) {\n const ch = body[i];\n if (ch === '.' || ch === '!' || ch === '?' || ch === '\\n') {\n cut = i + 1;\n break;\n }\n }\n if (cut === -1) return '';\n return `${body.slice(0, cut)} `.replace(/\\n $/, '\\n');\n}\n\n// After a break (optionally into a bullet), or a bullet at the very start —\n// but never the plain first word: dictation may continue an existing sentence.\n// Constructor form: the `u`-flag literal trips TS1501 under the app's ts target.\nconst LOWERCASE_AFTER_BREAK_REGEX = new RegExp(\n String.raw`(^- |\\n(?:- )?)(\\p{Ll})`,\n 'gu',\n);\n\nfunction capitalizeAfterBreaks(text: string): string {\n return text.replace(\n LOWERCASE_AFTER_BREAK_REGEX,\n (_m, brk: string, ch: string) => brk + ch.toUpperCase(),\n );\n}\n\n/** Sentence-boundary check for a phrase starting where `before` ends — only\n * the trailing few characters matter (bounded: never scans the transcript). */\nfunction endsAtSentenceBoundary(before: string): boolean {\n // Start of text, tolerating a short space prefix (realtime deltas arrive\n // as space-prefixed tokens).\n if (before.length <= 3 && /^\\s*$/.test(before)) return true;\n return /[.!?\\n]\\s{0,3}$/.test(before.slice(-6));\n}\n\nexport class DictationCommandUtils {\n /**\n * Process the full raw transcript accumulated so far into insertable text.\n * Pure and deterministic: always called with the entire raw string so the\n * result never depends on delta chunking.\n */\n static process(raw: string, options?: ProcessOptions): ProcessedDictation {\n const grammar = grammarFor(options?.language);\n const pendingTail = options?.final\n ? ''\n : DictationCommandUtils.commandPrefixTail(raw, options?.language);\n const consumable = raw.slice(0, raw.length - pendingTail.length);\n const regex = options?.final ? grammar.finalRegex : grammar.regex;\n\n let out = '';\n let control: DictationControlAction | null = null;\n let cursor = 0;\n\n for (const match of Array.from(consumable.matchAll(regex))) {\n const [, phrase = ''] = match;\n const action = grammar.phraseToAction.get(phrase.toLowerCase());\n if (!action) continue;\n\n // Keep everything before the command (the boundary terminator is a\n // lookbehind, so it's part of the kept text), drop the phrase itself.\n out += consumable.slice(cursor, match.index);\n cursor = match.index + match[0].length;\n\n if (action === 'newline') out = `${out.replace(/[ \\t]+$/, '')}\\n`;\n else if (action === 'newparagraph')\n out = `${out.replace(/[ \\t]+$/, '')}\\n\\n`;\n else if (action === 'bullet') {\n const trimmed = out.replace(/[ \\t]+$/, '');\n out =\n trimmed === '' || trimmed.endsWith('\\n')\n ? `${trimmed}- `\n : `${trimmed}\\n- `;\n } else if (action === 'scratch') out = deleteLastSentence(out);\n else {\n control = action === 'send' ? 'send' : 'stop';\n break;\n }\n }\n if (control === null) out += consumable.slice(cursor);\n\n // Tidy: no leading whitespace, no spaces flanking breaks, single spacing\n // (commands leave doubled gaps behind), max double break, sentences after\n // a break start uppercase.\n const text = capitalizeAfterBreaks(\n out\n .replace(/^\\s+/, '')\n .replace(/[ \\t]+\\n/g, '\\n')\n .replace(/\\n[ \\t]+/g, '\\n')\n .replace(/(^|\\n)- +/g, '$1- ')\n .replace(/ {2,}/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n'),\n );\n\n return { text, pendingTail, control };\n }\n\n /**\n * Longest suffix of `raw` that could still become a command — a proper\n * prefix of a phrase (\"New paragr…\") OR a COMPLETED phrase with no\n * terminator yet (\"…Send it\"). Both are withheld from insertion: the next\n * delta either brings punctuation (the phrase was a spoken command) or more\n * words (\"Send it to the team\" — released as ordinary text). Firing a\n * control command from an intermediate delta would stop or submit\n * mid-sentence.\n */\n static commandPrefixTail(raw: string, language?: string | undefined): string {\n const grammar = grammarFor(language);\n const maxLen = Math.min(raw.length, grammar.longestPhrase + 2);\n for (let len = maxLen; len > 0; len--) {\n const start = raw.length - len;\n // Candidate must begin at a sentence boundary (same guard as matching).\n if (!endsAtSentenceBoundary(raw.slice(0, start))) continue;\n const tail = raw.slice(start).toLowerCase();\n const candidate = tail.replace(/^\\s+/, '');\n if (!candidate) continue;\n for (const phrase of Array.from(grammar.phraseToAction.keys())) {\n if (phrase.startsWith(candidate)) {\n // Exclude the leading whitespace — it belongs to the consumable text.\n return raw.slice(start + (tail.length - candidate.length));\n }\n }\n }\n return '';\n }\n\n /**\n * True when the current pending tail is a COMPLETED phrase (not a partial\n * prefix) — i.e. a silence pause would resolve it into a command. Used by\n * the manager's silence timer.\n */\n static pendingTailIsCompletePhrase(\n raw: string,\n language?: string | undefined,\n ): boolean {\n const tail = DictationCommandUtils.commandPrefixTail(raw, language)\n .trim()\n .toLowerCase();\n if (!tail) return false;\n return grammarFor(language).phraseToAction.has(tail);\n }\n}\n","/**\n * Pure helpers for the dictation hook: paced text reveal (\"drip\") and the\n * transcription language hint.\n */\n\n/** Cadence of the word-drip renderer (ms per step). */\nexport const DRIP_INTERVAL_MS = 55;\n/** When the backlog grows past this, step faster instead of falling behind. */\nconst DRIP_BACKLOG_CHARS = 90;\n\nexport class DictationDripUtils {\n /**\n * Next paced step toward `processed`: normally one word per tick so text\n * flows evenly instead of landing in bursty chunks; proportionally larger\n * steps when a burst put us far behind. Assumes `processed` extends\n * `displayed` (callers reconcile immediately otherwise).\n */\n static nextDripText({\n displayed,\n processed,\n }: {\n displayed: string;\n processed: string;\n }): string {\n if (processed.length <= displayed.length) return processed;\n const backlog = processed.length - displayed.length;\n if (backlog > DRIP_BACKLOG_CHARS) {\n return processed.slice(0, displayed.length + Math.ceil(backlog / 3));\n }\n // Advance past leading whitespace, then to the end of the next word.\n let i = displayed.length;\n while (i < processed.length && /\\s/.test(processed.charAt(i))) i++;\n while (i < processed.length && !/\\s/.test(processed.charAt(i))) i++;\n // Unspaced scripts (CJK): cap the step so it still drips.\n if (i - displayed.length > 12) i = displayed.length + 6;\n return processed.slice(0, Math.max(i, displayed.length + 1));\n }\n\n /** Normalize a BCP-47 browser locale into the hint OpenAI accepts. */\n static languageHint(locale: string | undefined): string | undefined {\n if (!locale) return undefined;\n const lower = locale.toLowerCase();\n // Regional Chinese forms are meaningful to the model; everything else uses\n // the primary subtag (\"en-US\" → \"en\").\n if (/^zh-(cn|tw|hk)$/.test(lower)) return lower;\n const primary = lower.split('-')[0];\n return primary && /^[a-z]{2,3}$/.test(primary) ? primary : undefined;\n }\n}\n","import type { DictationMint } from './dictation-session';\n\n/** Don't reuse a token that could expire mid-handshake. */\nconst REUSE_SAFETY_MARGIN_MS = 20_000;\n\n/**\n * Session-token reuse: an ephemeral client secret can open multiple realtime\n * sessions until it expires (120s TTL), so re-minting on every activation\n * wastes a full backend round trip. The cache holds the latest mint and\n * hands it back while comfortably inside its TTL; hovering the mic\n * pre-warms it so the first click starts instantly too.\n *\n * One instance per widget (owned by DictationCtx), never module state — two\n * widgets on one page must not share a mint across orgs.\n */\nexport class DictationMintCache {\n private cached: DictationMint | null = null;\n private inflight: Promise<DictationMint> | null = null;\n\n /** Valid cached mint, or null. */\n get(): DictationMint | null {\n if (!this.cached) return null;\n const expiresAtMs = Date.parse(this.cached.expiresAt);\n if (\n Number.isNaN(expiresAtMs) ||\n expiresAtMs - Date.now() < REUSE_SAFETY_MARGIN_MS\n ) {\n this.cached = null;\n return null;\n }\n return this.cached;\n }\n\n /**\n * Resolve a mint, deduping concurrent requests (hover-prewarm racing a\n * click reuses the same in-flight promise instead of double-minting).\n */\n async resolve(\n mintFresh: () => Promise<DictationMint>,\n ): Promise<DictationMint> {\n const valid = this.get();\n if (valid) return valid;\n if (!this.inflight) {\n this.inflight = mintFresh()\n .then((mint) => {\n this.cached = mint;\n return mint;\n })\n .finally(() => {\n this.inflight = null;\n });\n }\n return this.inflight;\n }\n\n /** Drop the cache (e.g. after a failed handshake — token may be stale). */\n clear() {\n this.cached = null;\n }\n}\n","/** A plain object read off the wire (not null, not an array). */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { isRecord } from '../utils/is-record';\nimport { log } from '../utils/log';\n/**\n * One live dictation session: microphone → WebRTC → realtime transcription.\n * The browser talks to the transcription service directly with a short-lived\n * ephemeral token minted by the backend — audio and transcripts never touch\n * OpenCX servers, and the real API key never reaches the browser.\n *\n * WebRTC (not WebSocket) because the browser stack handles Opus encoding,\n * jitter buffering and echo cancellation natively — no PCM plumbing, lowest\n * practical latency.\n *\n * Errors are CODES (the widget renders them through its translation table).\n */\n\nexport type DictationSessionState =\n | 'idle'\n | 'connecting'\n | 'listening'\n | 'stopped'\n | 'error';\n\nexport type DictationErrorCode =\n /** No getUserMedia, permission denied, or no device. */\n | 'microphone'\n /** Mint, handshake, or transport failure. */\n | 'unavailable';\n\nexport interface DictationMint {\n token: string;\n expiresAt: string;\n model: string;\n}\n\ntype ServerEvent = {\n type: string;\n delta: string | undefined;\n errorMessage: string | undefined;\n};\n\n/** The three fields dictation reads off a realtime server event. */\nfunction parseServerEvent(value: unknown): ServerEvent | null {\n if (!isRecord(value) || typeof value.type !== 'string') return null;\n const error = isRecord(value.error) ? value.error : null;\n return {\n type: value.type,\n delta: typeof value.delta === 'string' ? value.delta : undefined,\n errorMessage:\n error && typeof error.message === 'string' ? error.message : undefined,\n };\n}\n\nconst REALTIME_CALLS_URL = 'https://api.openai.com/v1/realtime/calls';\n\n/** Hard cap so an abandoned tab never leaves the mic streaming forever. */\nconst MAX_SESSION_MS = 10 * 60 * 1000;\n/** If the session isn't live shortly after starting (mint + mic + handshake\n * all included), bail out — never leave a mic open on a hung connect. */\nconst CONNECT_TIMEOUT_MS = 15_000;\n/** How long a transient WebRTC 'disconnected' may last before giving up. */\nconst DISCONNECT_GRACE_MS = 5_000;\n\nclass DictationMicrophoneError extends Error {}\n\nexport class DictationSession {\n private readonly mintToken: () => Promise<DictationMint>;\n private readonly onDelta: (delta: string) => void;\n private readonly onState: (state: DictationSessionState) => void;\n private readonly onError: (code: DictationErrorCode) => void;\n private readonly onLevel: ((level: number) => void) | undefined;\n\n private state: DictationSessionState = 'idle';\n private pc: RTCPeerConnection | null = null;\n private dc: RTCDataChannel | null = null;\n private stream: MediaStream | null = null;\n private audioContext: AudioContext | null = null;\n private levelRaf = 0;\n private timers: ReturnType<typeof setTimeout>[] = [];\n private loggedParseFailure = false;\n\n constructor({\n mintToken,\n onDelta,\n onState,\n onError,\n onLevel,\n }: {\n mintToken: () => Promise<DictationMint>;\n onDelta: (delta: string) => void;\n onState: (state: DictationSessionState) => void;\n onError: (code: DictationErrorCode) => void;\n onLevel?: (level: number) => void;\n }) {\n this.mintToken = mintToken;\n this.onDelta = onDelta;\n this.onState = onState;\n this.onError = onError;\n this.onLevel = onLevel;\n }\n\n async start() {\n if (this.state !== 'idle') return;\n this.setState('connecting');\n\n // Watchdogs arm IMMEDIATELY — mint, permission prompt, or the SDP fetch\n // can all hang, and none of them may leave the mic open forever.\n this.timers.push(\n setTimeout(() => {\n if (this.state === 'connecting') this.fail('unavailable');\n }, CONNECT_TIMEOUT_MS),\n );\n this.timers.push(setTimeout(() => this.stop(), MAX_SESSION_MS));\n\n try {\n // Mic first — the permission prompt is the slowest step; mint in parallel.\n // If mint rejects while the permission prompt is still open, the\n // eventually-resolved stream must not stay hot: drain it on arrival.\n const micPromise = this.requestMicrophone();\n void micPromise\n .then((stream) => {\n if (this.isTornDown() || (this.stream && this.stream !== stream)) {\n stream.getTracks().forEach((t) => t.stop());\n }\n })\n .catch(() => undefined); // surfaced via the await below\n const [stream, mint] = await Promise.all([micPromise, this.mintToken()]);\n if (this.isTornDown()) {\n stream.getTracks().forEach((t) => t.stop());\n return;\n }\n this.stream = stream;\n this.startLevelMeter(stream);\n\n const pc = new RTCPeerConnection();\n this.pc = pc;\n const [track] = stream.getAudioTracks();\n if (!track) throw new DictationMicrophoneError('No audio track');\n pc.addTrack(track, stream);\n\n const dc = pc.createDataChannel('oai-events');\n this.dc = dc;\n dc.addEventListener('message', (event) =>\n this.handleServerEvent(event.data),\n );\n // The mic track is already flowing once the connection is up — don't\n // make the user wait for the first server event to start speaking.\n dc.addEventListener('open', () => {\n if (this.state === 'connecting') this.setState('listening');\n });\n\n pc.addEventListener('connectionstatechange', () => {\n if (pc.connectionState === 'failed') {\n this.fail('unavailable');\n return;\n }\n // 'disconnected' is transient and routinely self-recovers — only give\n // up if it doesn't come back within a grace period.\n if (pc.connectionState === 'disconnected') {\n this.timers.push(\n setTimeout(() => {\n if (this.pc === pc && pc.connectionState !== 'connected') {\n this.fail('unavailable');\n }\n }, DISCONNECT_GRACE_MS),\n );\n }\n });\n\n const offer = await pc.createOffer();\n await pc.setLocalDescription(offer);\n\n const sdpResponse = await fetch(REALTIME_CALLS_URL, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${mint.token}`,\n 'Content-Type': 'application/sdp',\n },\n body: offer.sdp,\n });\n if (!sdpResponse.ok) {\n throw new Error(`Realtime handshake failed (${sdpResponse.status})`);\n }\n const answerSdp = await sdpResponse.text();\n if (this.isTornDown()) return;\n await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });\n } catch (e) {\n if (e instanceof DictationMicrophoneError) {\n this.fail('microphone');\n } else {\n log.error('dictation session failed to start', {\n _e: e instanceof Error ? e.message : String(e),\n });\n this.fail('unavailable');\n }\n }\n }\n\n stop() {\n if (this.state === 'stopped') return;\n this.teardown();\n this.setState('stopped');\n }\n\n private async requestMicrophone(): Promise<MediaStream> {\n if (!navigator.mediaDevices?.getUserMedia) {\n throw new DictationMicrophoneError('Microphone is not supported');\n }\n try {\n return await navigator.mediaDevices.getUserMedia({\n audio: {\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n });\n } catch (e) {\n throw new DictationMicrophoneError(\n e instanceof DOMException ? e.name : 'Could not access the microphone',\n );\n }\n }\n\n private handleServerEvent(raw: unknown) {\n if (typeof raw !== 'string') return;\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n if (!this.loggedParseFailure) {\n this.loggedParseFailure = true;\n log.error('dictation server event was not valid JSON', {\n snippet: raw.slice(0, 120),\n });\n }\n return;\n }\n const event = parseServerEvent(parsed);\n if (!event) return;\n\n const { type, delta } = event;\n if (\n type === 'session.created' ||\n type === 'transcription_session.created'\n ) {\n this.setState('listening');\n return;\n }\n if (type === 'conversation.item.input_audio_transcription.delta' && delta) {\n // First delta can arrive before we noticed session.created.\n if (this.state === 'connecting') this.setState('listening');\n this.onDelta(delta);\n return;\n }\n if (type === 'error') {\n log.error('dictation server event error', {\n _e: event.errorMessage ?? 'unknown',\n });\n this.fail('unavailable');\n }\n }\n\n private startLevelMeter(stream: MediaStream) {\n if (!this.onLevel) return;\n try {\n const audioContext = new AudioContext();\n this.audioContext = audioContext;\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 512;\n source.connect(analyser);\n const data = new Uint8Array(analyser.frequencyBinCount);\n const tick = () => {\n analyser.getByteTimeDomainData(data);\n let sum = 0;\n for (let i = 0; i < data.length; i++) {\n const centered = ((data[i] ?? 128) - 128) / 128;\n sum += centered * centered;\n }\n const rms = Math.sqrt(sum / data.length);\n this.onLevel?.(Math.min(1, rms * 4));\n this.levelRaf = requestAnimationFrame(tick);\n };\n this.levelRaf = requestAnimationFrame(tick);\n } catch (e) {\n // Level meter is decorative — dictation works without it.\n log.error('dictation level meter unavailable', {\n _e: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n private isTornDown() {\n return this.state === 'stopped' || this.state === 'error';\n }\n\n private fail(code: DictationErrorCode) {\n if (this.isTornDown()) return;\n this.teardown();\n this.setState('error');\n this.onError(code);\n }\n\n private teardown() {\n this.timers.forEach((t) => clearTimeout(t));\n this.timers = [];\n if (this.levelRaf) cancelAnimationFrame(this.levelRaf);\n this.levelRaf = 0;\n this.dc?.close();\n this.dc = null;\n this.pc?.close();\n this.pc = null;\n this.stream?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n void this.audioContext?.close().catch((e) => {\n log.error('failed to close dictation audio context', {\n _e: String(e),\n });\n });\n this.audioContext = null;\n }\n\n private setState(state: DictationSessionState) {\n if (this.state === state) return;\n this.state = state;\n this.onState(state);\n }\n}\n","import type { ApiCaller } from '../api/api-caller';\nimport { DictationCommandUtils } from '../dictation/dictation-commands.utils';\nimport {\n DRIP_INTERVAL_MS,\n DictationDripUtils,\n} from '../dictation/dictation-drip.utils';\nimport { DictationMintCache } from '../dictation/dictation-mint-cache';\nimport {\n DictationSession,\n type DictationErrorCode,\n type DictationMint,\n type DictationSessionState,\n} from '../dictation/dictation-session';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport { log } from '../utils/log';\n\nexport type DictationStatus = 'idle' | 'connecting' | 'listening';\n\nexport type DictationCtxState = {\n status: DictationStatus;\n /** Last failure, cleared on the next start. */\n error: DictationErrorCode | null;\n};\n\n/**\n * Where dictated text lands. The widget composer is a plain textarea whose\n * value is React state, so the target is just \"what is there now\" and \"set\n * it\". Text is appended after whatever the visitor already typed; a manual\n * edit inside the dictated region ends the session (their edit wins).\n */\nexport interface DictationTarget {\n getValue: () => string;\n setValue: (value: string) => void;\n /** Fired for the spoken \"send message\" command, after the text is final. */\n onSend?: (() => void) | undefined;\n}\n\n/** A completed command phrase left hanging this long resolves as spoken\n * (the pause IS the command terminator when the model hasn't punctuated). */\nconst SILENCE_COMMAND_MS = 1_300;\n\nconst IDLE: DictationCtxState = { status: 'idle', error: null };\n\n/**\n * Voice dictation for the composer: mic → realtime transcription → the\n * textarea, with the spoken-command grammar (\"new line\",\n * \"scratch that\", \"send it\") and paced word reveal. One session per widget;\n * `start` on a live session restarts it against the new target.\n */\nexport class DictationCtx {\n public state = new PrimitiveState<DictationCtxState>(IDLE);\n /** 0..1 mic level — read inside a rAF loop, never during render. */\n public readonly levelRef = { current: 0 };\n\n private readonly api: ApiCaller;\n private readonly config: WidgetConfig;\n private readonly mintCache = new DictationMintCache();\n\n private session: DictationSession | null = null;\n private target: DictationTarget | null = null;\n private language: string | undefined;\n /** Composer content when dictation started — dictated text follows it. */\n private prefix = '';\n private raw = '';\n private processed = '';\n private displayed = '';\n private dripTimer: ReturnType<typeof setInterval> | null = null;\n private silenceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor({ api, config }: { api: ApiCaller; config: WidgetConfig }) {\n this.api = api;\n this.config = config;\n }\n\n isActive = (): boolean => this.session !== null;\n\n /** Fire-and-forget token pre-mint (mic hover) so the click starts instantly. */\n prewarm = () => {\n void this.mintToken().catch((e) => {\n this.mintCache.clear();\n log.error('dictation token prewarm failed', {\n _e: e instanceof Error ? e.message : String(e),\n });\n });\n };\n\n start = (target: DictationTarget) => {\n if (this.session) this.teardown();\n\n this.target = target;\n this.language = DictationDripUtils.languageHint(\n this.config.language ?? navigator.language,\n );\n this.prefix = target.getValue();\n this.raw = '';\n this.processed = '';\n this.displayed = '';\n\n const session = new DictationSession({\n mintToken: this.mintToken,\n onLevel: (level) => {\n this.levelRef.current = level;\n },\n onState: (sessionState: DictationSessionState) => {\n if (session !== this.session) return;\n if (sessionState === 'connecting') {\n this.state.set({ status: 'connecting', error: null });\n }\n if (sessionState === 'listening') {\n this.state.set({ status: 'listening', error: null });\n }\n // The session can end itself (max-duration cap): mirror it, or the UI\n // keeps showing a live mic that is actually closed.\n if (sessionState === 'stopped') this.teardown();\n },\n onError: (code) => {\n if (session !== this.session) return;\n // The token may have been the stale part — next attempt mints fresh.\n this.mintCache.clear();\n this.teardown({ error: code, executeFinalCommand: false });\n },\n onDelta: (delta) => {\n if (session !== this.session || !this.target) return;\n if (!this.isConsistent()) {\n // The visitor edited the field mid-dictation — their edit wins.\n this.teardown();\n return;\n }\n this.raw += delta;\n const control = this.ingest();\n if (control === 'stop') {\n this.teardown();\n return;\n }\n if (control === 'send') {\n this.teardown({ send: true });\n return;\n }\n // A completed command phrase waiting for punctuation resolves after a\n // silent pause — the model may never emit the terminator once the\n // user stops talking.\n this.stopSilenceTimer();\n if (\n DictationCommandUtils.pendingTailIsCompletePhrase(\n this.raw,\n this.language,\n )\n ) {\n this.silenceTimer = setTimeout(() => {\n if (session !== this.session) return;\n this.raw = `${this.raw}.`;\n const silenceControl = this.ingest();\n if (silenceControl === 'stop') this.teardown();\n else if (silenceControl === 'send') this.teardown({ send: true });\n }, SILENCE_COMMAND_MS);\n }\n },\n });\n this.session = session;\n this.state.set({ status: 'connecting', error: null });\n\n this.dripTimer = setInterval(() => {\n if (!this.target) return;\n if (this.processed === this.displayed) return;\n if (!this.isConsistent()) {\n this.teardown();\n return;\n }\n this.applyDisplayed(\n DictationDripUtils.nextDripText({\n displayed: this.displayed,\n processed: this.processed,\n }),\n );\n }, DRIP_INTERVAL_MS);\n\n void session.start();\n };\n\n stop = () => {\n if (this.session) this.teardown();\n };\n\n private mintToken = async (): Promise<DictationMint> =>\n this.mintCache.resolve(() =>\n this.api.createDictationSession({ language: this.language }),\n );\n\n /** Applied text = prefix + dictated. A mismatch means the visitor edited. */\n private isConsistent(): boolean {\n if (!this.target) return false;\n return this.target.getValue() === this.prefix + this.displayed;\n }\n\n private applyDisplayed(text: string) {\n if (!this.target) return;\n this.target.setValue(this.prefix + text);\n this.displayed = text;\n }\n\n /** Process the transcript and apply the outcome. Shared by the delta path,\n * the silence timer, and (with `final`) teardown. Returns the control. */\n private ingest(options?: { final?: boolean }) {\n const result = DictationCommandUtils.process(this.raw, {\n language: this.language,\n final: options?.final,\n });\n this.processed = result.text;\n // Rewrites (scratch-that, retro-capitalization) apply instantly; plain\n // appends flow through the paced drip.\n if (!result.text.startsWith(this.displayed)) {\n this.applyDisplayed(result.text);\n }\n return result.control;\n }\n\n private stopSilenceTimer() {\n if (this.silenceTimer) clearTimeout(this.silenceTimer);\n this.silenceTimer = null;\n }\n\n private teardown(options?: {\n send?: boolean;\n error?: DictationErrorCode;\n /** Manual/normal stops execute a trailing spoken command (\"…send it\").\n * Error teardowns only release the words as text. */\n executeFinalCommand?: boolean;\n }) {\n const endingSession = this.session;\n const endingTarget = this.target;\n if (this.dripTimer) clearInterval(this.dripTimer);\n this.dripTimer = null;\n this.stopSilenceTimer();\n\n // End-of-stream semantics: stopping IS the pause, so the withheld tail\n // resolves — a completed command phrase fires (unless this is an error\n // teardown), and partial phrases land as literal words instead of\n // vanishing. Consistency-guarded like every other write.\n let send = options?.send ?? false;\n if (endingTarget && this.isConsistent()) {\n const control = this.ingest({ final: true });\n if (options?.executeFinalCommand !== false && control === 'send') {\n send = true;\n }\n if (this.processed !== this.displayed) {\n this.applyDisplayed(this.processed);\n }\n }\n\n this.session = null;\n this.target = null;\n endingSession?.stop();\n this.levelRef.current = 0;\n this.state.set({ status: 'idle', error: options?.error ?? null });\n if (send) endingTarget?.onSend?.();\n }\n}\n","import type { TranslationInterface } from '.';\n\nexport const ArabicLanguage: TranslationInterface = {\n write_a_message_placeholder: 'اكتب رسالة...',\n your_issue_has_been_resolved: 'تم حل مشكلتك!',\n new_conversation: 'محادثة جديدة',\n welcome_screen_title: 'مرحبًا بك في دردشة الدعم الخاصة بنا',\n welcome_screen_description:\n 'نحن هنا للمساعدة! ابدأ محادثة وسنرد عليك في أقرب وقت ممكن.',\n your_name_placeholder: 'اسمك',\n your_email_placeholder: 'عنوان بريدك الإلكتروني',\n start_chat_button: 'تحدث إلى الدعم',\n start_chat_button_loading: 'جاري الاتصال...',\n i_need_more_help: 'أحتاج المزيد من المساعدة',\n this_was_helpful: 'كان هذا مفيدًا',\n optional: 'اختياري',\n no_conversations_yet: 'لا يوجد محادثات',\n back_to_conversations: 'العودة إلى المحادثات',\n closed_conversations: 'المحادثات المغلقة',\n csat_title: 'كيف كانت محادثتك؟',\n csat_submitted_title: 'لقد قيّمت المحادثة بـ',\n csat_feedback_placeholder: 'أخبرنا المزيد... (اختياري)',\n follow_up_placeholder: 'تابع المحادثة…',\n companion_layout_label: 'التخطيط',\n companion_layout_floating: 'عائم',\n companion_layout_sidebar: 'الشريط الجانبي',\n companion_layout_fullscreen: 'ملء الشاشة',\n companion_close_chat: 'إغلاق {title}',\n companion_close: 'إغلاق',\n companion_switch_chat: 'تبديل المحادثة',\n companion_viewing: 'تعرض الآن',\n companion_working: 'قيد العمل',\n companion_open: 'مفتوحة',\n companion_closed: 'مغلقة',\n companion_draft: 'مسودة',\n companion_chats: 'الجلسات النشطة',\n companion_chat_number: 'محادثة {count}',\n companion_active_chats: '{count} جلسات نشطة',\n companion_other_sessions: 'الجلسات المفتوحة الأخرى: {count}',\n companion_working_chats: '{count} قيد العمل',\n companion_history: 'سجل المحادثات',\n companion_expand_chat: 'توسيع المحادثة',\n companion_sidebar_dock_label: 'الإرساء',\n companion_sidebar_side_label: 'الجانب',\n companion_sidebar_left: 'يسار',\n companion_sidebar_right: 'يمين',\n companion_resize_chat: 'تغيير حجم المحادثة',\n scroll_to_bottom: 'التمرير إلى الأسفل',\n thinking: 'جارٍ التفكير…',\n running: 'جارٍ التنفيذ…',\n steps: 'خطوات',\n step_arguments: 'الوسائط',\n step_result: 'النتيجة',\n attach_files:\n 'إرفاق صور أو مقاطع فيديو أو ملفات PDF أو جداول بيانات (الحد الأقصى 25 ميغابايت)',\n mark_page_active: 'انقر على أي شيء في الصفحة لتحديده — اضغط Esc للإلغاء',\n mark_page: 'حدّد شيئًا في الصفحة لطرح سؤال عنه',\n stop_response: 'إيقاف الرد',\n copy_reply: 'نسخ الرد',\n mentions_empty: 'لا توجد نتائج',\n copied: 'تم النسخ',\n send_message: 'إرسال الرسالة',\n upload_failed: 'فشل الرفع: {error}',\n remove_attachment: 'إزالة المرفق',\n json_no_items: 'لا توجد عناصر',\n json_no_data: 'لا توجد بيانات',\n json_no_chart_data: 'لا توجد بيانات لعرضها في الرسم البياني',\n json_unsupported: 'غير مدعوم: {type}',\n json_see_less: 'عرض أقل',\n json_phone_agent: 'وكيل هاتفي',\n json_phone_agent_test: 'اختبار عبر الويب',\n page_context_remove: 'إزالة سياق الصفحة',\n json_see_more: 'عرض {count} إضافية',\n queued_label: '{count} في الانتظار',\n remove_queued_message: 'إزالة الرسالة من قائمة الانتظار',\n send_queued_now: 'إرسال الرسائل في قائمة الانتظار الآن',\n turn_failed_message: 'حدث خطأ ما ولم يصل الرد.',\n turn_failed_retry: 'حاول مرة أخرى',\n page_mark_hint: 'انقر على أي شيء لتحديده',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'مربع',\n page_mark_shape_circle: 'دائرة',\n page_mark_shape_arrow: 'سهم',\n page_mark_shape_bracket: 'قوس',\n page_mark_shape_underline: 'تسطير',\n page_mark_shape_highlight: 'تمييز',\n page_mark_shape_strike_through: 'شطب',\n page_mark_shape_crossed_off: 'علامة تقاطع',\n page_mark_shape_aria: 'شكل التحديد: {shape}',\n page_mark_note_placeholder: 'أضف ملاحظة… (Enter للإرفاق)',\n page_mark_attach: 'إرفاق التحديد',\n page_mark_remove: 'إزالة {label}',\n page_mark_region: 'منطقة محددة',\n page_mark_default_message: 'ما هذا؟',\n file_rejected: 'نوع الملف غير مدعوم أو أن الملف كبير جدًا.',\n dictate: 'إملاء صوتي',\n stop_dictation: 'إيقاف الإملاء',\n dictation_mic_blocked: 'اسمح بالوصول إلى الميكروفون للإملاء',\n dictation_unavailable: 'الإملاء غير متاح حاليًا',\n questions_back: 'رجوع',\n questions_next: 'التالي',\n questions_send: 'إرسال',\n questions_type_answer: 'سأكتبها بنفسي',\n questions_answer_placeholder: 'اكتب إجابتك…',\n close_conversation_title: 'إغلاق المحادثة',\n close_conversation_description: 'هل أنت متأكد أنك تريد إغلاق هذه المحادثة؟',\n close_conversation_cancel: 'لا',\n close_conversation_confirm: 'نعم',\n dialog_close: 'إغلاق',\n zoom_in: 'تكبير',\n zoom_out: 'تصغير',\n reset_zoom: 'إعادة تعيين التكبير',\n support_chat_aria_label: 'دردشة الدعم',\n};\n","import type { TranslationInterface } from '.';\n\nexport const BengaliLanguage: TranslationInterface = {\n write_a_message_placeholder: 'একটি বার্তা লিখুন...',\n your_issue_has_been_resolved: 'আপনার সমস্যা সমাধান হয়েছে!',\n new_conversation: 'নতুন কথোপকথন',\n welcome_screen_title: 'আমাদের সাপোর্ট চ্যাটে স্বাগতম',\n welcome_screen_description:\n 'আমরা সাহায্য করতে এখানে আছি! একটি কথোপকথন শুরু করুন এবং আমরা যত তাড়াতাড়ি সম্ভব আপনার কাছে ফিরে আসব।',\n your_name_placeholder: 'আপনার নাম',\n your_email_placeholder: 'আপনার ইমেইল ঠিকানা',\n start_chat_button: 'সাপোর্টের সাথে কথা বলুন',\n start_chat_button_loading: 'সংযোগ হচ্ছে...',\n i_need_more_help: 'আমার আরও সাহায্য দরকার',\n this_was_helpful: 'এটি সহায়ক ছিল',\n optional: 'ঐচ্ছিক',\n no_conversations_yet: 'এখনো কোনো কথোপকথন নেই',\n back_to_conversations: 'কথোপকথনে ফিরে যান',\n closed_conversations: 'বন্ধ কথোপকথন',\n csat_title: 'আপনার কথোপকথন কেমন ছিল?',\n csat_submitted_title: 'আপনি কথোপকথনটি মূল্যায়ন করেছেন',\n csat_feedback_placeholder: 'আমাদের আরও বলুন... (ঐচ্ছিক)',\n follow_up_placeholder: 'আরও জিজ্ঞাসা করুন…',\n companion_layout_label: 'লেআউট',\n companion_layout_floating: 'ভাসমান',\n companion_layout_sidebar: 'সাইডবার',\n companion_layout_fullscreen: 'পূর্ণ পর্দা',\n companion_close: 'বন্ধ করুন',\n companion_history: 'কথোপকথনের ইতিহাস',\n companion_expand_chat: 'চ্যাট প্রসারিত করুন',\n companion_sidebar_dock_label: 'ডক',\n companion_sidebar_side_label: 'পাশ',\n companion_sidebar_left: 'বাম',\n companion_sidebar_right: 'ডান',\n companion_resize_chat: 'চ্যাটের আকার পরিবর্তন করুন',\n scroll_to_bottom: 'নিচে স্ক্রল করুন',\n thinking: 'ভাবছি…',\n running: 'চলছে…',\n steps: 'ধাপ',\n step_arguments: 'আর্গুমেন্ট',\n step_result: 'ফলাফল',\n attach_files:\n 'ছবি, ভিডিও, PDF বা স্প্রেডশিট সংযুক্ত করুন (সর্বোচ্চ আকার 25 MB)',\n mark_page_active:\n 'চিহ্নিত করতে পৃষ্ঠার যেকোনো কিছুতে ক্লিক করুন — বাতিল করতে Esc চাপুন',\n mark_page: 'পৃষ্ঠার কোনো কিছু সম্পর্কে জিজ্ঞাসা করতে সেটি চিহ্নিত করুন',\n stop_response: 'উত্তর থামান',\n copy_reply: 'উত্তর কপি করুন',\n mentions_empty: 'কোনো মিল নেই',\n copied: 'কপি করা হয়েছে',\n send_message: 'বার্তা পাঠান',\n upload_failed: 'আপলোড ব্যর্থ হয়েছে: {error}',\n remove_attachment: 'সংযুক্তি সরান',\n json_no_items: 'কোনো আইটেম নেই',\n json_no_data: 'কোনো ডেটা নেই',\n json_no_chart_data: 'চার্টের জন্য কোনো ডেটা নেই',\n json_unsupported: 'সমর্থিত নয়: {type}',\n json_see_less: 'কম দেখুন',\n json_phone_agent: 'ফোন এজেন্ট',\n json_phone_agent_test: 'ওয়েবে পরীক্ষা করুন',\n page_context_remove: 'পেজ প্রসঙ্গ সরান',\n json_see_more: 'আরও {count}টি দেখুন',\n queued_label: '{count} সারিতে আছে',\n remove_queued_message: 'সারি থেকে বার্তা সরান',\n send_queued_now: 'সারির বার্তাগুলি এখনই পাঠান',\n turn_failed_message: 'কিছু ভুল হয়েছে এবং উত্তরটি আসেনি।',\n turn_failed_retry: 'আবার চেষ্টা করুন',\n page_mark_hint: 'চিহ্নিত করতে যেকোনো কিছুতে ক্লিক করুন',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'বাক্স',\n page_mark_shape_circle: 'বৃত্ত',\n page_mark_shape_arrow: 'তীর',\n page_mark_shape_bracket: 'বন্ধনী',\n page_mark_shape_underline: 'নিম্নরেখা',\n page_mark_shape_highlight: 'হাইলাইট',\n page_mark_shape_strike_through: 'মাঝে দাগ',\n page_mark_shape_crossed_off: 'ক্রস করে কাটা',\n page_mark_shape_aria: 'চিহ্নের আকৃতি: {shape}',\n page_mark_note_placeholder: 'একটি নোট যোগ করুন… (সংযুক্ত করতে Enter চাপুন)',\n page_mark_attach: 'চিহ্ন সংযুক্ত করুন',\n page_mark_remove: '{label} সরান',\n page_mark_region: 'চিহ্নিত অঞ্চল',\n page_mark_default_message: 'এটি কী?',\n file_rejected: 'ফাইলের ধরন সমর্থিত নয় অথবা ফাইলটি খুব বড়।',\n dictate: 'ডিক্টেট করুন',\n stop_dictation: 'ডিক্টেশন বন্ধ করুন',\n dictation_mic_blocked: 'ডিক্টেট করতে মাইক্রোফোন অ্যাক্সেসের অনুমতি দিন',\n dictation_unavailable: 'ডিক্টেশন এখন উপলব্ধ নয়',\n questions_back: 'পেছনে',\n questions_next: 'পরবর্তী',\n questions_send: 'পাঠান',\n questions_type_answer: 'আমি লিখে দিচ্ছি',\n questions_answer_placeholder: 'আপনার উত্তর লিখুন…',\n close_conversation_title: 'কথোপকথন বন্ধ করুন',\n close_conversation_description:\n 'আপনি কি নিশ্চিত যে আপনি এই কথোপকথনটি বন্ধ করতে চান?',\n close_conversation_cancel: 'না',\n close_conversation_confirm: 'হ্যাঁ',\n dialog_close: 'বন্ধ করুন',\n zoom_in: 'বড় করুন',\n zoom_out: 'ছোট করুন',\n reset_zoom: 'জুম রিসেট করুন',\n support_chat_aria_label: 'সাপোর্ট চ্যাট',\n};\n","import type { TranslationInterface } from '.';\n\nexport const BulgarianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Напишете съобщение...',\n your_issue_has_been_resolved: 'Вашият проблем е разрешен!',\n new_conversation: 'Нов разговор',\n welcome_screen_title: 'Добре дошли в нашия чат за поддръжка',\n welcome_screen_description:\n 'Тук сме, за да помогнем! Започнете разговор и ще ви отговорим възможно най-скоро.',\n your_name_placeholder: 'Вашето име',\n your_email_placeholder: 'Вашият имейл адрес',\n start_chat_button: 'Свържете се с поддръжка',\n start_chat_button_loading: 'Свързване...',\n i_need_more_help: 'Имам нужда от повече помощ',\n this_was_helpful: 'Това беше полезно',\n optional: 'По избор',\n no_conversations_yet: 'Все още няма разговори',\n back_to_conversations: 'Назад към разговорите',\n closed_conversations: 'Затворени разговори',\n csat_title: 'Как мина разговорът ви?',\n csat_submitted_title: 'Оценихте разговора като',\n csat_feedback_placeholder: 'Кажете ни повече... (по желание)',\n follow_up_placeholder: 'Продължете…',\n companion_layout_label: 'Оформление',\n companion_layout_floating: 'Плаващ',\n companion_layout_sidebar: 'Странична лента',\n companion_layout_fullscreen: 'На цял екран',\n companion_close: 'Затвори',\n companion_history: 'История на разговорите',\n companion_expand_chat: 'Разгъване на чата',\n companion_sidebar_dock_label: 'Закачване',\n companion_sidebar_side_label: 'Страна',\n companion_sidebar_left: 'Ляво',\n companion_sidebar_right: 'Дясно',\n companion_resize_chat: 'Преоразмеряване на чата',\n scroll_to_bottom: 'Превъртане до края',\n thinking: 'Мисля…',\n running: 'Изпълнява се…',\n steps: 'стъпки',\n step_arguments: 'Аргументи',\n step_result: 'Резултат',\n attach_files:\n 'Прикачете изображения, видеоклипове, PDF файлове или електронни таблици (максимален размер 25 MB)',\n mark_page_active:\n 'Щракнете върху нещо на страницата, за да го маркирате — Esc за отказ',\n mark_page: 'Маркирайте нещо на страницата, за да попитате за него',\n stop_response: 'Спиране на отговора',\n copy_reply: 'Копирай отговора',\n mentions_empty: 'Няма съвпадения',\n copied: 'Копирано',\n send_message: 'Изпращане на съобщение',\n upload_failed: 'Неуспешно качване: {error}',\n remove_attachment: 'Премахване на прикачения файл',\n json_no_items: 'Няма елементи',\n json_no_data: 'Няма данни',\n json_no_chart_data: 'Няма данни за диаграма',\n json_unsupported: 'Не се поддържа: {type}',\n json_see_less: 'Покажи по-малко',\n json_phone_agent: 'Телефонен агент',\n json_phone_agent_test: 'Тест през уеб',\n page_context_remove: 'Премахни контекста на страницата',\n json_see_more: 'Покажи още {count}',\n queued_label: '{count} На опашката',\n remove_queued_message: 'Премахване на съобщението от опашката',\n send_queued_now: 'Изпрати съобщенията от опашката сега',\n turn_failed_message: 'Нещо се обърка и отговорът не пристигна.',\n turn_failed_retry: 'Опитайте отново',\n page_mark_hint: 'Щракнете върху нещо, за да го маркирате',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Правоъгълник',\n page_mark_shape_circle: 'Кръг',\n page_mark_shape_arrow: 'Стрелка',\n page_mark_shape_bracket: 'Скоба',\n page_mark_shape_underline: 'Подчертаване',\n page_mark_shape_highlight: 'Маркиране',\n page_mark_shape_strike_through: 'Зачертаване',\n page_mark_shape_crossed_off: 'Кръстосано зачертаване',\n page_mark_shape_aria: 'Форма на маркировката: {shape}',\n page_mark_note_placeholder: 'Добавете бележка… (Enter за прикачване)',\n page_mark_attach: 'Прикачване на маркировката',\n page_mark_remove: 'Премахване на {label}',\n page_mark_region: 'Маркирана област',\n page_mark_default_message: 'Какво е това?',\n file_rejected: 'Типът на файла не се поддържа или файлът е твърде голям.',\n dictate: 'Диктувай',\n stop_dictation: 'Спри диктуването',\n dictation_mic_blocked: 'Разрешете достъп до микрофона, за да диктувате',\n dictation_unavailable: 'Диктуването не е налично в момента',\n questions_back: 'Назад',\n questions_next: 'Напред',\n questions_send: 'Изпрати',\n questions_type_answer: 'Ще напиша сам',\n questions_answer_placeholder: 'Напишете отговора си…',\n close_conversation_title: 'Затваряне на разговора',\n close_conversation_description:\n 'Сигурни ли сте, че искате да затворите този разговор?',\n close_conversation_cancel: 'Не',\n close_conversation_confirm: 'Да',\n dialog_close: 'Затваряне',\n zoom_in: 'Увеличаване',\n zoom_out: 'Намаляване',\n reset_zoom: 'Нулиране на мащаба',\n support_chat_aria_label: 'Чат за поддръжка',\n};\n","import type { TranslationInterface } from '.';\n\nexport const CzechLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napište zprávu...',\n your_issue_has_been_resolved: 'Váš problém byl vyřešen!',\n new_conversation: 'Nová konverzace',\n welcome_screen_title: 'Vítejte v našem chatu podpory',\n welcome_screen_description:\n 'Jsme tu, abychom vám pomohli! Zahajte konverzaci a ozveme se vám co nejdříve.',\n your_name_placeholder: 'Vaše jméno',\n your_email_placeholder: 'Vaše e-mailová adresa',\n start_chat_button: 'Kontaktovat podporu',\n start_chat_button_loading: 'Připojování...',\n i_need_more_help: 'Potřebuji další pomoc',\n this_was_helpful: 'Toto bylo užitečné',\n optional: 'Volitelné',\n no_conversations_yet: 'Zatím žádné konverzace',\n back_to_conversations: 'Zpět na konverzace',\n closed_conversations: 'Uzavřené konverzace',\n csat_title: 'Jaká byla vaše konverzace?',\n csat_submitted_title: 'Konverzaci jste ohodnotili jako',\n csat_feedback_placeholder: 'Řekněte nám více... (nepovinné)',\n follow_up_placeholder: 'Pokračovat…',\n companion_layout_label: 'Rozvržení',\n companion_layout_floating: 'Plovoucí',\n companion_layout_sidebar: 'Postranní panel',\n companion_layout_fullscreen: 'Celá obrazovka',\n companion_close: 'Zavřít',\n companion_history: 'Historie konverzací',\n companion_expand_chat: 'Rozbalit chat',\n companion_sidebar_dock_label: 'Ukotvení',\n companion_sidebar_side_label: 'Strana',\n companion_sidebar_left: 'Vlevo',\n companion_sidebar_right: 'Vpravo',\n companion_resize_chat: 'Změnit velikost chatu',\n scroll_to_bottom: 'Posunout dolů',\n thinking: 'Přemýšlím…',\n running: 'Probíhá…',\n steps: 'kroky',\n step_arguments: 'Argumenty',\n step_result: 'Výsledek',\n attach_files:\n 'Připojit obrázky, videa, PDF nebo tabulky (maximální velikost 25 MB)',\n mark_page_active:\n 'Kliknutím na cokoli na stránce to označíte — klávesou Esc akci zrušíte',\n mark_page: 'Označte něco na stránce a zeptejte se na to',\n stop_response: 'Zastavit odpověď',\n copy_reply: 'Kopírovat odpověď',\n mentions_empty: 'Žádné shody',\n copied: 'Zkopírováno',\n send_message: 'Odeslat zprávu',\n upload_failed: 'Nahrání se nezdařilo: {error}',\n remove_attachment: 'Odebrat přílohu',\n json_no_items: 'Žádné položky',\n json_no_data: 'Žádná data',\n json_no_chart_data: 'Žádná data pro graf',\n json_unsupported: 'Nepodporováno: {type}',\n json_see_less: 'Zobrazit méně',\n json_phone_agent: 'Telefonní agent',\n json_phone_agent_test: 'Vyzkoušet na webu',\n page_context_remove: 'Odebrat kontext stránky',\n json_see_more: 'Zobrazit dalších {count}',\n queued_label: '{count} Ve frontě',\n remove_queued_message: 'Odebrat zprávu z fronty',\n send_queued_now: 'Odeslat zprávy ve frontě nyní',\n turn_failed_message: 'Něco se pokazilo a odpověď nedorazila.',\n turn_failed_retry: 'Zkusit znovu',\n page_mark_hint: 'Kliknutím na cokoli to označíte',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rámeček',\n page_mark_shape_circle: 'Kruh',\n page_mark_shape_arrow: 'Šipka',\n page_mark_shape_bracket: 'Závorka',\n page_mark_shape_underline: 'Podtržení',\n page_mark_shape_highlight: 'Zvýraznění',\n page_mark_shape_strike_through: 'Přeškrtnutí',\n page_mark_shape_crossed_off: 'Křížové přeškrtnutí',\n page_mark_shape_aria: 'Tvar označení: {shape}',\n page_mark_note_placeholder: 'Přidat poznámku… (Enter pro připojení)',\n page_mark_attach: 'Připojit označení',\n page_mark_remove: 'Odebrat {label}',\n page_mark_region: 'Označená oblast',\n page_mark_default_message: 'Co to je?',\n file_rejected: 'Typ souboru není podporován nebo je soubor příliš velký.',\n dictate: 'Diktovat',\n stop_dictation: 'Zastavit diktování',\n dictation_mic_blocked: 'Pro diktování povolte přístup k mikrofonu',\n dictation_unavailable: 'Diktování momentálně není k dispozici',\n questions_back: 'Zpět',\n questions_next: 'Další',\n questions_send: 'Odeslat',\n questions_type_answer: 'Napíšu to sám',\n questions_answer_placeholder: 'Napište svou odpověď…',\n close_conversation_title: 'Uzavřít konverzaci',\n close_conversation_description: 'Opravdu chcete tuto konverzaci uzavřít?',\n close_conversation_cancel: 'Ne',\n close_conversation_confirm: 'Ano',\n dialog_close: 'Zavřít',\n zoom_in: 'Přiblížit',\n zoom_out: 'Oddálit',\n reset_zoom: 'Obnovit přiblížení',\n support_chat_aria_label: 'Chat podpory',\n};\n","import type { TranslationInterface } from '.';\n\nexport const DanishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv en besked...',\n your_issue_has_been_resolved: 'Dit problem er løst!',\n new_conversation: 'Ny samtale',\n welcome_screen_title: 'Velkommen til vores support chat',\n welcome_screen_description:\n 'Vi er her for at hjælpe! Start en samtale, og vi vender tilbage til dig så hurtigt som muligt.',\n your_name_placeholder: 'Dit navn',\n your_email_placeholder: 'Din e-mailadresse',\n start_chat_button: 'Tal med support',\n start_chat_button_loading: 'Forbinder...',\n i_need_more_help: 'Jeg har brug for mere hjælp',\n this_was_helpful: 'Dette var nyttigt',\n optional: 'Valgfrit',\n no_conversations_yet: 'Ingen samtaler endnu',\n back_to_conversations: 'Tilbage til samtaler',\n closed_conversations: 'Lukkede samtaler',\n csat_title: 'Hvordan var din samtale?',\n csat_submitted_title: 'Du vurderede samtalen som',\n csat_feedback_placeholder: 'Fortæl os mere... (valgfrit)',\n follow_up_placeholder: 'Følg op…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Flydende',\n companion_layout_sidebar: 'Sidepanel',\n companion_layout_fullscreen: 'Fuld skærm',\n companion_close: 'Luk',\n companion_history: 'Samtalehistorik',\n companion_expand_chat: 'Udvid chat',\n companion_sidebar_dock_label: 'Dok',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Venstre',\n companion_sidebar_right: 'Højre',\n companion_resize_chat: 'Tilpas chatstørrelse',\n scroll_to_bottom: 'Rul til bunden',\n thinking: 'Tænker…',\n running: 'Kører…',\n steps: 'trin',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Vedhæft billeder, videoer, PDF-filer eller regneark (maksimal størrelse 25 MB)',\n mark_page_active:\n 'Klik på noget på siden for at markere det — Esc annullerer',\n mark_page: 'Markér noget på siden for at spørge om det',\n stop_response: 'Stop svar',\n copy_reply: 'Kopiér svar',\n mentions_empty: 'Ingen resultater',\n copied: 'Kopieret',\n send_message: 'Send besked',\n upload_failed: 'Upload mislykkedes: {error}',\n remove_attachment: 'Fjern vedhæftning',\n json_no_items: 'Ingen elementer',\n json_no_data: 'Ingen data',\n json_no_chart_data: 'Ingen data til diagram',\n json_unsupported: 'Ikke understøttet: {type}',\n json_see_less: 'Vis mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Test via web',\n page_context_remove: 'Fjern sidekontekst',\n json_see_more: 'Vis {count} mere',\n queued_label: '{count} I kø',\n remove_queued_message: 'Fjern besked fra køen',\n send_queued_now: 'Send beskeder i køen nu',\n turn_failed_message: 'Noget gik galt, og svaret kom ikke frem.',\n turn_failed_retry: 'Prøv igen',\n page_mark_hint: 'Klik på noget for at markere det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Firkant',\n page_mark_shape_circle: 'Cirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Kantparentes',\n page_mark_shape_underline: 'Understregning',\n page_mark_shape_highlight: 'Fremhævning',\n page_mark_shape_strike_through: 'Gennemstregning',\n page_mark_shape_crossed_off: 'Kryds ud',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Tilføj en note… (Enter for at vedhæfte)',\n page_mark_attach: 'Vedhæft markering',\n page_mark_remove: 'Fjern {label}',\n page_mark_region: 'Markeret område',\n page_mark_default_message: 'Hvad er det her?',\n file_rejected: 'Filtypen understøttes ikke, eller filen er for stor.',\n dictate: 'Dikter',\n stop_dictation: 'Stop diktering',\n dictation_mic_blocked: 'Tillad mikrofonadgang for at diktere',\n dictation_unavailable: 'Diktering er ikke tilgængelig lige nu',\n questions_back: 'Tilbage',\n questions_next: 'Næste',\n questions_send: 'Send',\n questions_type_answer: 'Jeg skriver det selv',\n questions_answer_placeholder: 'Skriv dit svar…',\n close_conversation_title: 'Luk samtale',\n close_conversation_description:\n 'Er du sikker på, at du vil lukke denne samtale?',\n close_conversation_cancel: 'Nej',\n close_conversation_confirm: 'Ja',\n dialog_close: 'Luk',\n zoom_in: 'Zoom ind',\n zoom_out: 'Zoom ud',\n reset_zoom: 'Nulstil zoom',\n support_chat_aria_label: 'Supportchat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const GreekLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Γράψτε ένα μήνυμα...',\n your_issue_has_been_resolved: 'Το πρόβλημά σας επιλύθηκε!',\n new_conversation: 'Νέα συνομιλία',\n welcome_screen_title: 'Καλώς ήρθατε στη συνομιλία υποστήριξης',\n welcome_screen_description:\n 'Είμαστε εδώ για να βοηθήσουμε! Ξεκινήστε μια συνομιλία και θα σας απαντήσουμε το συντομότερο δυνατό.',\n your_name_placeholder: 'Το όνομά σας',\n your_email_placeholder: 'Η διεύθυνση email σας',\n start_chat_button: 'Επικοινωνία με την υποστήριξη',\n start_chat_button_loading: 'Σύνδεση...',\n i_need_more_help: 'Χρειάζομαι περισσότερη βοήθεια',\n this_was_helpful: 'Αυτό ήταν χρήσιμο',\n optional: 'Προαιρετικό',\n no_conversations_yet: 'Δεν υπάρχουν συνομιλίες ακόμα',\n back_to_conversations: 'Πίσω στις συνομιλίες',\n closed_conversations: 'Κλειστές συνομιλίες',\n csat_title: 'Πώς ήταν η συνομιλία σας;',\n csat_submitted_title: 'Βαθμολογήσατε τη συνομιλία ως',\n csat_feedback_placeholder: 'Πείτε μας περισσότερα... (προαιρετικό)',\n follow_up_placeholder: 'Συνέχεια…',\n companion_layout_label: 'Διάταξη',\n companion_layout_floating: 'Αιωρούμενο',\n companion_layout_sidebar: 'Πλευρική στήλη',\n companion_layout_fullscreen: 'Πλήρης οθόνη',\n companion_close: 'Κλείσιμο',\n companion_history: 'Ιστορικό συνομιλιών',\n companion_expand_chat: 'Ανάπτυξη συνομιλίας',\n companion_sidebar_dock_label: 'Αγκύρωση',\n companion_sidebar_side_label: 'Πλευρά',\n companion_sidebar_left: 'Αριστερά',\n companion_sidebar_right: 'Δεξιά',\n companion_resize_chat: 'Αλλαγή μεγέθους συνομιλίας',\n scroll_to_bottom: 'Κύλιση στο τέλος',\n thinking: 'Σκέψη…',\n running: 'Εκτελείται…',\n steps: 'βήματα',\n step_arguments: 'Ορίσματα',\n step_result: 'Αποτέλεσμα',\n attach_files:\n 'Επισύναψη εικόνων, βίντεο, PDF ή υπολογιστικών φύλλων (μέγιστο μέγεθος 25 MB)',\n mark_page_active:\n 'Κάντε κλικ σε οτιδήποτε στη σελίδα για να το επισημάνετε — Esc για ακύρωση',\n mark_page: 'Επισημάνετε κάτι στη σελίδα για να ρωτήσετε σχετικά με αυτό',\n stop_response: 'Διακοπή απάντησης',\n copy_reply: 'Αντιγραφή απάντησης',\n mentions_empty: 'Δεν βρέθηκαν αποτελέσματα',\n copied: 'Αντιγράφηκε',\n send_message: 'Αποστολή μηνύματος',\n upload_failed: 'Η μεταφόρτωση απέτυχε: {error}',\n remove_attachment: 'Αφαίρεση συνημμένου',\n json_no_items: 'Δεν υπάρχουν στοιχεία',\n json_no_data: 'Δεν υπάρχουν δεδομένα',\n json_no_chart_data: 'Δεν υπάρχουν δεδομένα για γράφημα',\n json_unsupported: 'Δεν υποστηρίζεται: {type}',\n json_see_less: 'Εμφάνιση λιγότερων',\n json_phone_agent: 'Τηλεφωνικός πράκτορας',\n json_phone_agent_test: 'Δοκιμή μέσω web',\n page_context_remove: 'Αφαίρεση περιβάλλοντος σελίδας',\n json_see_more: 'Εμφάνιση {count} ακόμη',\n queued_label: '{count} Σε αναμονή',\n remove_queued_message: 'Αφαίρεση μηνύματος από την ουρά',\n send_queued_now: 'Αποστολή μηνυμάτων ουράς τώρα',\n turn_failed_message: 'Κάτι πήγε στραβά και η απάντηση δεν έφτασε.',\n turn_failed_retry: 'Δοκιμάστε ξανά',\n page_mark_hint: 'Κάντε κλικ σε κάτι για να το επισημάνετε',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Πλαίσιο',\n page_mark_shape_circle: 'Κύκλος',\n page_mark_shape_arrow: 'Βέλος',\n page_mark_shape_bracket: 'Αγκύλη',\n page_mark_shape_underline: 'Υπογράμμιση',\n page_mark_shape_highlight: 'Επισήμανση',\n page_mark_shape_strike_through: 'Διακριτή διαγραφή',\n page_mark_shape_crossed_off: 'Χιαστή διαγραφή',\n page_mark_shape_aria: 'Σχήμα επισήμανσης: {shape}',\n page_mark_note_placeholder: 'Προσθέστε σημείωση… (Enter για επισύναψη)',\n page_mark_attach: 'Επισύναψη επισήμανσης',\n page_mark_remove: 'Αφαίρεση {label}',\n page_mark_region: 'Επισημασμένη περιοχή',\n page_mark_default_message: 'Τι είναι αυτό;',\n file_rejected:\n 'Ο τύπος αρχείου δεν υποστηρίζεται ή το αρχείο είναι πολύ μεγάλο.',\n dictate: 'Υπαγόρευση',\n stop_dictation: 'Διακοπή υπαγόρευσης',\n dictation_mic_blocked: 'Επιτρέψτε την πρόσβαση στο μικρόφωνο για υπαγόρευση',\n dictation_unavailable: 'Η υπαγόρευση δεν είναι διαθέσιμη αυτή τη στιγμή',\n questions_back: 'Πίσω',\n questions_next: 'Επόμενο',\n questions_send: 'Αποστολή',\n questions_type_answer: 'Θα το γράψω',\n questions_answer_placeholder: 'Γράψτε την απάντησή σας…',\n close_conversation_title: 'Κλείσιμο συνομιλίας',\n close_conversation_description:\n 'Είστε βέβαιοι ότι θέλετε να κλείσετε αυτήν τη συνομιλία;',\n close_conversation_cancel: 'Όχι',\n close_conversation_confirm: 'Ναι',\n dialog_close: 'Κλείσιμο',\n zoom_in: 'Μεγέθυνση',\n zoom_out: 'Σμίκρυνση',\n reset_zoom: 'Επαναφορά ζουμ',\n support_chat_aria_label: 'Συνομιλία υποστήριξης',\n};\n","import type { TranslationInterface } from '.';\n\nexport const GermanLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Nachricht schreiben...',\n your_issue_has_been_resolved: 'Ihr Problem wurde gelöst!',\n new_conversation: 'Neue Konversation',\n welcome_screen_title: 'Willkommen in unserem Support-Chat',\n welcome_screen_description:\n 'Wir sind hier, um zu helfen! Beginnen Sie ein Gesprách und wir werden so schnell wie mogelijk antworten.',\n your_name_placeholder: 'Ihr Name',\n your_email_placeholder: 'Ihre E-Mail-Adresse',\n start_chat_button: 'Mit dem Support sprechen',\n start_chat_button_loading: 'Verbindung wird hergestellt...',\n i_need_more_help: 'Ich brauche weitere Hilfe',\n this_was_helpful: 'Dies war hilfreich',\n optional: 'Optional',\n no_conversations_yet: 'noch keine Gespräche',\n back_to_conversations: 'Zurück zur Konversationen',\n closed_conversations: 'Geschlossene Konversationen',\n csat_title: 'Wie war Ihr Gespräch?',\n csat_submitted_title: 'Sie haben das Gespräch bewertet als',\n csat_feedback_placeholder: 'Erzählen Sie uns mehr... (optional)',\n follow_up_placeholder: 'Nachfragen…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Schwebend',\n companion_layout_sidebar: 'Seitenleiste',\n companion_layout_fullscreen: 'Vollbild',\n companion_close: 'Schließen',\n companion_history: 'Gesprächsverlauf',\n companion_expand_chat: 'Chat erweitern',\n companion_sidebar_dock_label: 'Andocken',\n companion_sidebar_side_label: 'Seite',\n companion_sidebar_left: 'Links',\n companion_sidebar_right: 'Rechts',\n companion_resize_chat: 'Chatgröße ändern',\n scroll_to_bottom: 'Nach unten scrollen',\n thinking: 'Denke nach…',\n running: 'Wird ausgeführt…',\n steps: 'Schritte',\n step_arguments: 'Argumente',\n step_result: 'Ergebnis',\n attach_files:\n 'Bilder, Videos, PDFs oder Tabellen anhängen (maximale Größe 25 MB)',\n mark_page_active:\n 'Klicken Sie auf etwas auf der Seite, um es zu markieren — Esc zum Abbrechen',\n mark_page: 'Markieren Sie etwas auf der Seite, um danach zu fragen',\n stop_response: 'Antwort stoppen',\n copy_reply: 'Antwort kopieren',\n mentions_empty: 'Keine Treffer',\n copied: 'Kopiert',\n send_message: 'Nachricht senden',\n upload_failed: 'Upload fehlgeschlagen: {error}',\n remove_attachment: 'Anhang entfernen',\n json_no_items: 'Keine Elemente',\n json_no_data: 'Keine Daten',\n json_no_chart_data: 'Keine Daten für das Diagramm',\n json_unsupported: 'Nicht unterstützt: {type}',\n json_see_less: 'Weniger anzeigen',\n json_phone_agent: 'Telefon-Agent',\n json_phone_agent_test: 'Im Web testen',\n page_context_remove: 'Seitenkontext entfernen',\n json_see_more: '{count} weitere anzeigen',\n queued_label: '{count} In Warteschlange',\n remove_queued_message: 'Nachricht aus der Warteschlange entfernen',\n send_queued_now: 'Wartende Nachrichten jetzt senden',\n turn_failed_message:\n 'Etwas ist schiefgelaufen und die Antwort ist nicht angekommen.',\n turn_failed_retry: 'Erneut versuchen',\n page_mark_hint: 'Klicken Sie auf etwas, um es zu markieren',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rahmen',\n page_mark_shape_circle: 'Kreis',\n page_mark_shape_arrow: 'Pfeil',\n page_mark_shape_bracket: 'Klammer',\n page_mark_shape_underline: 'Unterstreichen',\n page_mark_shape_highlight: 'Hervorheben',\n page_mark_shape_strike_through: 'Durchstreichen',\n page_mark_shape_crossed_off: 'Auskreuzen',\n page_mark_shape_aria: 'Markierungsform: {shape}',\n page_mark_note_placeholder: 'Notiz hinzufügen… (Enter zum Anhängen)',\n page_mark_attach: 'Markierung anhängen',\n page_mark_remove: '{label} entfernen',\n page_mark_region: 'Markierter Bereich',\n page_mark_default_message: 'Was ist das?',\n file_rejected:\n 'Der Dateityp wird nicht unterstützt oder die Datei ist zu groß.',\n dictate: 'Diktieren',\n stop_dictation: 'Diktat beenden',\n dictation_mic_blocked: 'Mikrofonzugriff erlauben, um zu diktieren',\n dictation_unavailable: 'Diktieren ist derzeit nicht verfügbar',\n questions_back: 'Zurück',\n questions_next: 'Weiter',\n questions_send: 'Senden',\n questions_type_answer: 'Ich schreibe es selbst',\n questions_answer_placeholder: 'Antwort eingeben…',\n close_conversation_title: 'Konversation schließen',\n close_conversation_description:\n 'Möchten Sie diese Konversation wirklich schließen?',\n close_conversation_cancel: 'Nein',\n close_conversation_confirm: 'Ja',\n dialog_close: 'Schließen',\n zoom_in: 'Vergrößern',\n zoom_out: 'Verkleinern',\n reset_zoom: 'Zoom zurücksetzen',\n support_chat_aria_label: 'Support-Chat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const EnglishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Write a message...',\n your_issue_has_been_resolved: 'Your issue has been resolved!',\n new_conversation: 'New conversation',\n welcome_screen_title: 'Welcome to our support chat',\n welcome_screen_description:\n \"We're here to help! Start a conversation and we'll get back to you as soon as possible.\",\n your_name_placeholder: 'Your name',\n your_email_placeholder: 'Your email address',\n start_chat_button: 'Talk to support',\n start_chat_button_loading: 'Connecting...',\n i_need_more_help: 'I need more help',\n this_was_helpful: 'This was helpful',\n optional: 'Optional',\n no_conversations_yet: 'No conversations yet',\n back_to_conversations: 'Back to conversations',\n closed_conversations: 'Closed conversations',\n csat_title: 'How was your conversation?',\n csat_submitted_title: 'You rated the conversation as',\n csat_feedback_placeholder: 'Tell us more... (optional)',\n follow_up_placeholder: 'Follow up…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Floating',\n companion_layout_sidebar: 'Sidebar',\n companion_layout_fullscreen: 'Fullscreen',\n companion_close_chat: 'Close {title}',\n companion_close: 'Close',\n companion_switch_chat: 'Switch chat',\n companion_viewing: 'Viewing',\n companion_working: 'Working',\n companion_open: 'Open',\n companion_closed: 'Closed',\n companion_draft: 'Draft',\n companion_chats: 'Active sessions',\n companion_chat_number: 'Chat {count}',\n companion_active_chats: '{count} active sessions',\n companion_other_sessions: 'Other open sessions: {count}',\n companion_working_chats: '{count} working',\n companion_history: 'Conversation history',\n companion_expand_chat: 'Expand chat',\n companion_sidebar_dock_label: 'Dock',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Left',\n companion_sidebar_right: 'Right',\n companion_resize_chat: 'Resize chat',\n scroll_to_bottom: 'Scroll to bottom',\n thinking: 'Thinking…',\n running: 'Running…',\n steps: 'steps',\n step_arguments: 'Arguments',\n step_result: 'Result',\n attach_files:\n 'Attach images, videos, PDFs, or spreadsheets (maximum size 25 MB)',\n mark_page_active: 'Click anything on the page to mark it — Esc to cancel',\n mark_page: 'Mark something on the page to ask about it',\n stop_response: 'Stop response',\n copy_reply: 'Copy reply',\n mentions_empty: 'No matches',\n copied: 'Copied',\n send_message: 'Send message',\n upload_failed: 'Failed to upload: {error}',\n remove_attachment: 'Remove attachment',\n json_no_items: 'No items',\n json_no_data: 'No data',\n json_no_chart_data: 'No data to chart',\n json_unsupported: 'Unsupported: {type}',\n json_see_less: 'See less',\n json_phone_agent: 'Phone agent',\n json_phone_agent_test: 'Test via web',\n page_context_remove: 'Remove page context',\n json_see_more: 'See {count} more',\n queued_label: '{count} Queued',\n remove_queued_message: 'Remove queued message',\n send_queued_now: 'Send queued messages now',\n turn_failed_message: 'Something went wrong and the reply didn’t arrive.',\n turn_failed_retry: 'Try again',\n page_mark_hint: 'Click anything to mark it',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Box',\n page_mark_shape_circle: 'Circle',\n page_mark_shape_arrow: 'Arrow',\n page_mark_shape_bracket: 'Bracket',\n page_mark_shape_underline: 'Underline',\n page_mark_shape_highlight: 'Highlight',\n page_mark_shape_strike_through: 'Strike through',\n page_mark_shape_crossed_off: 'Cross out',\n page_mark_shape_aria: 'Mark shape: {shape}',\n page_mark_note_placeholder: 'Add a note… (Enter to attach)',\n page_mark_attach: 'Attach mark',\n page_mark_remove: 'Remove {label}',\n page_mark_region: 'Marked region',\n page_mark_default_message: 'What is this?',\n file_rejected: 'The file type is unsupported or the file is too large.',\n dictate: 'Dictate',\n stop_dictation: 'Stop dictating',\n dictation_mic_blocked: 'Allow microphone access to dictate',\n dictation_unavailable: 'Dictation is unavailable right now',\n questions_back: 'Back',\n questions_next: 'Next',\n questions_send: 'Send',\n questions_type_answer: \"I'll type it\",\n questions_answer_placeholder: 'Type your answer…',\n close_conversation_title: 'Close conversation',\n close_conversation_description:\n 'Are you sure you want to close this conversation?',\n close_conversation_cancel: 'No',\n close_conversation_confirm: 'Yes',\n dialog_close: 'Close',\n zoom_in: 'Zoom in',\n zoom_out: 'Zoom out',\n reset_zoom: 'Reset zoom',\n support_chat_aria_label: 'Support chat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const SpanishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Escribe un mensaje...',\n your_issue_has_been_resolved: '¡Tu problema fue resuelto!',\n new_conversation: 'Nueva conversación',\n welcome_screen_title: 'Bienvenido a nuestro chat de soporte',\n welcome_screen_description:\n '¡Estamos aquí para ayudarte! Inicia una conversación y responderemos lo antes posible.',\n your_name_placeholder: 'Tu nombre',\n your_email_placeholder: 'Tu correo electrónico',\n start_chat_button: 'Hablar con soporte',\n start_chat_button_loading: 'Conectando...',\n i_need_more_help: 'Necesito más ayuda',\n this_was_helpful: 'Esto fue útil',\n optional: 'Opcional',\n no_conversations_yet: 'Sin conversaciones aún',\n back_to_conversations: 'Volver a conversaciones',\n closed_conversations: 'Conversaciones cerradas',\n csat_title: '¿Qué tal fue tu conversación?',\n csat_submitted_title: 'Valoraste la conversación como',\n csat_feedback_placeholder: 'Cuéntanos más... (opcional)',\n follow_up_placeholder: 'Continuar…',\n companion_layout_label: 'Diseño',\n companion_layout_floating: 'Flotante',\n companion_layout_sidebar: 'Barra lateral',\n companion_layout_fullscreen: 'Pantalla completa',\n companion_close: 'Cerrar',\n companion_history: 'Historial de conversaciones',\n companion_expand_chat: 'Ampliar chat',\n companion_sidebar_dock_label: 'Acople',\n companion_sidebar_side_label: 'Lado',\n companion_sidebar_left: 'Izquierda',\n companion_sidebar_right: 'Derecha',\n companion_resize_chat: 'Cambiar el tamaño del chat',\n scroll_to_bottom: 'Desplazarse al final',\n thinking: 'Pensando…',\n running: 'En curso…',\n steps: 'pasos',\n step_arguments: 'Argumentos',\n step_result: 'Resultado',\n attach_files:\n 'Adjuntar imágenes, vídeos, PDF u hojas de cálculo (tamaño máximo 25 MB)',\n mark_page_active:\n 'Haz clic en cualquier elemento de la página para marcarlo — Esc para cancelar',\n mark_page: 'Marca algo de la página para preguntar sobre ello',\n stop_response: 'Detener respuesta',\n copy_reply: 'Copiar respuesta',\n mentions_empty: 'Sin coincidencias',\n copied: 'Copiado',\n send_message: 'Enviar mensaje',\n upload_failed: 'Error al subir: {error}',\n remove_attachment: 'Quitar archivo adjunto',\n json_no_items: 'No hay elementos',\n json_no_data: 'No hay datos',\n json_no_chart_data: 'No hay datos para el gráfico',\n json_unsupported: 'No compatible: {type}',\n json_see_less: 'Ver menos',\n json_phone_agent: 'Agente telefónico',\n json_phone_agent_test: 'Probar en la web',\n page_context_remove: 'Quitar el contexto de la página',\n json_see_more: 'Ver {count} más',\n queued_label: '{count} En cola',\n remove_queued_message: 'Quitar mensaje de la cola',\n send_queued_now: 'Enviar los mensajes en cola ahora',\n turn_failed_message: 'Algo salió mal y la respuesta no llegó.',\n turn_failed_retry: 'Intentar de nuevo',\n page_mark_hint: 'Haz clic en algo para marcarlo',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Recuadro',\n page_mark_shape_circle: 'Círculo',\n page_mark_shape_arrow: 'Flecha',\n page_mark_shape_bracket: 'Corchete',\n page_mark_shape_underline: 'Subrayado',\n page_mark_shape_highlight: 'Resaltado',\n page_mark_shape_strike_through: 'Tachado',\n page_mark_shape_crossed_off: 'Tachado en cruz',\n page_mark_shape_aria: 'Forma de la marca: {shape}',\n page_mark_note_placeholder: 'Añade una nota… (Enter para adjuntar)',\n page_mark_attach: 'Adjuntar marca',\n page_mark_remove: 'Quitar {label}',\n page_mark_region: 'Región marcada',\n page_mark_default_message: '¿Qué es esto?',\n file_rejected:\n 'El tipo de archivo no es compatible o el archivo es demasiado grande.',\n dictate: 'Dictar',\n stop_dictation: 'Detener dictado',\n dictation_mic_blocked: 'Permite el acceso al micrófono para dictar',\n dictation_unavailable: 'El dictado no está disponible ahora mismo',\n questions_back: 'Atrás',\n questions_next: 'Siguiente',\n questions_send: 'Enviar',\n questions_type_answer: 'Lo escribo yo',\n questions_answer_placeholder: 'Escribe tu respuesta…',\n close_conversation_title: 'Cerrar conversación',\n close_conversation_description:\n '¿Seguro que quieres cerrar esta conversación?',\n close_conversation_cancel: 'No',\n close_conversation_confirm: 'Sí',\n dialog_close: 'Cerrar',\n zoom_in: 'Acercar',\n zoom_out: 'Alejar',\n reset_zoom: 'Restablecer zoom',\n support_chat_aria_label: 'Chat de soporte',\n};\n","import type { TranslationInterface } from '.';\n\nexport const FilipinoLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Magsulat ng mensahe...',\n your_issue_has_been_resolved: 'Nalutas na ang iyong isyu!',\n new_conversation: 'Bagong usapan',\n welcome_screen_title: 'Maligayang pagdating sa aming support chat',\n welcome_screen_description:\n 'Narito kami upang tumulong! Magsimula ng usapan at babalikan ka namin sa lalong madaling panahon.',\n your_name_placeholder: 'Iyong pangalan',\n your_email_placeholder: 'Iyong email address',\n start_chat_button: 'Makipag-usap sa support',\n start_chat_button_loading: 'Kumokonekta...',\n i_need_more_help: 'Kailangan ko pa ng tulong',\n this_was_helpful: 'Nakatulong ito',\n optional: 'Opsyonal',\n no_conversations_yet: 'Wala pang mga usapan',\n back_to_conversations: 'Bumalik sa mga usapan',\n closed_conversations: 'Mga saradong usapan',\n csat_title: 'Kumusta ang iyong usapan?',\n csat_submitted_title: 'Ni-rate mo ang usapan bilang',\n csat_feedback_placeholder: 'Sabihin pa sa amin... (opsyonal)',\n follow_up_placeholder: 'Magpatuloy…',\n companion_layout_label: 'Ayos',\n companion_layout_floating: 'Lumulutang',\n companion_layout_sidebar: 'Sidebar',\n companion_layout_fullscreen: 'Buong screen',\n companion_close: 'Isara',\n companion_history: 'Kasaysayan ng mga pag-uusap',\n companion_expand_chat: 'Palawakin ang chat',\n companion_sidebar_dock_label: 'Dock',\n companion_sidebar_side_label: 'Gilid',\n companion_sidebar_left: 'Kaliwa',\n companion_sidebar_right: 'Kanan',\n companion_resize_chat: 'Baguhin ang laki ng chat',\n scroll_to_bottom: 'Mag-scroll sa ibaba',\n thinking: 'Nag-iisip…',\n running: 'Isinasagawa…',\n steps: 'mga hakbang',\n step_arguments: 'Mga argumento',\n step_result: 'Resulta',\n attach_files:\n 'Mag-attach ng mga larawan, video, PDF, o spreadsheet (maximum na laki 25 MB)',\n mark_page_active:\n 'Mag-click ng kahit ano sa page para markahan ito — Esc para kanselahin',\n mark_page: 'Markahan ang isang bagay sa page para magtanong tungkol dito',\n stop_response: 'Ihinto ang sagot',\n copy_reply: 'Kopyahin ang sagot',\n mentions_empty: 'Walang tugma',\n copied: 'Nakopya',\n send_message: 'Ipadala ang mensahe',\n upload_failed: 'Hindi na-upload: {error}',\n remove_attachment: 'Alisin ang attachment',\n json_no_items: 'Walang mga item',\n json_no_data: 'Walang data',\n json_no_chart_data: 'Walang data para sa chart',\n json_unsupported: 'Hindi suportado: {type}',\n json_see_less: 'Tumingin ng mas kaunti',\n json_phone_agent: 'Phone agent',\n json_phone_agent_test: 'Subukan sa web',\n page_context_remove: 'Alisin ang konteksto ng page',\n json_see_more: 'Tumingin pa ng {count}',\n queued_label: '{count} Nakapila',\n remove_queued_message: 'Alisin ang mensahe sa pila',\n send_queued_now: 'Ipadala na ang mga mensahe sa pila',\n turn_failed_message: 'Nagkaproblema at hindi dumating ang sagot.',\n turn_failed_retry: 'Subukan muli',\n page_mark_hint: 'Mag-click ng kahit ano para markahan ito',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kahon',\n page_mark_shape_circle: 'Bilog',\n page_mark_shape_arrow: 'Palaso',\n page_mark_shape_bracket: 'Bracket',\n page_mark_shape_underline: 'Salungguhit',\n page_mark_shape_highlight: 'Highlight',\n page_mark_shape_strike_through: 'Guhit sa gitna',\n page_mark_shape_crossed_off: 'Ekis',\n page_mark_shape_aria: 'Hugis ng marka: {shape}',\n page_mark_note_placeholder: 'Magdagdag ng tala… (Enter para i-attach)',\n page_mark_attach: 'I-attach ang marka',\n page_mark_remove: 'Alisin ang {label}',\n page_mark_region: 'Minarkahang bahagi',\n page_mark_default_message: 'Ano ito?',\n file_rejected: 'Hindi suportado ang uri ng file o masyadong malaki ang file.',\n dictate: 'Mag-dictate',\n stop_dictation: 'Ihinto ang dictation',\n dictation_mic_blocked: 'Payagan ang access sa mikropono para mag-dictate',\n dictation_unavailable: 'Hindi available ang dictation ngayon',\n questions_back: 'Bumalik',\n questions_next: 'Susunod',\n questions_send: 'Ipadala',\n questions_type_answer: 'Ako na ang magta-type',\n questions_answer_placeholder: 'I-type ang iyong sagot…',\n close_conversation_title: 'Isara ang usapan',\n close_conversation_description:\n 'Sigurado ka bang gusto mong isara ang usapang ito?',\n close_conversation_cancel: 'Hindi',\n close_conversation_confirm: 'Oo',\n dialog_close: 'Isara',\n zoom_in: 'Palakihin',\n zoom_out: 'Paliitin',\n reset_zoom: 'I-reset ang zoom',\n support_chat_aria_label: 'Chat ng suporta',\n};\n","import type { TranslationInterface } from '.';\n\nexport const FinnishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Kirjoita viesti...',\n your_issue_has_been_resolved: 'Ongelmasi on ratkaistu!',\n new_conversation: 'Uusi keskustelu',\n welcome_screen_title: 'Tervetuloa tukichattiin',\n welcome_screen_description:\n 'Olemme täällä auttamassa! Aloita keskustelu ja palaamme sinulle mahdollisimman pian.',\n your_name_placeholder: 'Nimesi',\n your_email_placeholder: 'Sähköpostiosoitteesi',\n start_chat_button: 'Keskustele tuen kanssa',\n start_chat_button_loading: 'Yhdistetään...',\n i_need_more_help: 'Tarvitsen lisää apua',\n this_was_helpful: 'Tämä oli hyödyllistä',\n optional: 'Valinnainen',\n no_conversations_yet: 'Ei vielä keskusteluja',\n back_to_conversations: 'Takaisin keskusteluihin',\n closed_conversations: 'Suljetut keskustelut',\n csat_title: 'Millainen keskustelusi oli?',\n csat_submitted_title: 'Arvioit keskustelun',\n csat_feedback_placeholder: 'Kerro lisää... (valinnainen)',\n follow_up_placeholder: 'Jatka…',\n companion_layout_label: 'Asettelu',\n companion_layout_floating: 'Kelluva',\n companion_layout_sidebar: 'Sivupalkki',\n companion_layout_fullscreen: 'Koko näyttö',\n companion_close: 'Sulje',\n companion_history: 'Keskusteluhistoria',\n companion_expand_chat: 'Laajenna keskustelu',\n companion_sidebar_dock_label: 'Telakointi',\n companion_sidebar_side_label: 'Puoli',\n companion_sidebar_left: 'Vasen',\n companion_sidebar_right: 'Oikea',\n companion_resize_chat: 'Muuta keskustelun kokoa',\n scroll_to_bottom: 'Vieritä alas',\n thinking: 'Ajattelen…',\n running: 'Suoritetaan…',\n steps: 'vaihetta',\n step_arguments: 'Argumentit',\n step_result: 'Tulos',\n attach_files:\n 'Liitä kuvia, videoita, PDF-tiedostoja tai laskentataulukoita (enimmäiskoko 25 MB)',\n mark_page_active:\n 'Merkitse sivulta jotain napsauttamalla sitä — peruuta Esc-näppäimellä',\n mark_page: 'Merkitse sivulta jotain kysyäksesi siitä',\n stop_response: 'Pysäytä vastaus',\n copy_reply: 'Kopioi vastaus',\n mentions_empty: 'Ei osumia',\n copied: 'Kopioitu',\n send_message: 'Lähetä viesti',\n upload_failed: 'Lataus epäonnistui: {error}',\n remove_attachment: 'Poista liite',\n json_no_items: 'Ei kohteita',\n json_no_data: 'Ei tietoja',\n json_no_chart_data: 'Kaaviolle ei ole tietoja',\n json_unsupported: 'Ei tuettu: {type}',\n json_see_less: 'Näytä vähemmän',\n json_phone_agent: 'Puhelinagentti',\n json_phone_agent_test: 'Testaa verkossa',\n page_context_remove: 'Poista sivun konteksti',\n json_see_more: 'Näytä vielä {count}',\n queued_label: '{count} Jonossa',\n remove_queued_message: 'Poista viesti jonosta',\n send_queued_now: 'Lähetä jonossa olevat viestit nyt',\n turn_failed_message: 'Jokin meni pieleen, eikä vastaus saapunut.',\n turn_failed_retry: 'Yritä uudelleen',\n page_mark_hint: 'Merkitse jotain napsauttamalla sitä',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Laatikko',\n page_mark_shape_circle: 'Ympyrä',\n page_mark_shape_arrow: 'Nuoli',\n page_mark_shape_bracket: 'Hakasulje',\n page_mark_shape_underline: 'Alleviivaus',\n page_mark_shape_highlight: 'Korostus',\n page_mark_shape_strike_through: 'Yliviivaus',\n page_mark_shape_crossed_off: 'Rastita yli',\n page_mark_shape_aria: 'Merkinnän muoto: {shape}',\n page_mark_note_placeholder: 'Lisää huomautus… (Enter liittää)',\n page_mark_attach: 'Liitä merkintä',\n page_mark_remove: 'Poista {label}',\n page_mark_region: 'Merkitty alue',\n page_mark_default_message: 'Mikä tämä on?',\n file_rejected: 'Tiedostotyyppiä ei tueta tai tiedosto on liian suuri.',\n dictate: 'Sanele',\n stop_dictation: 'Lopeta sanelu',\n dictation_mic_blocked: 'Salli mikrofonin käyttö sanellaksesi',\n dictation_unavailable: 'Sanelu ei ole juuri nyt käytettävissä',\n questions_back: 'Takaisin',\n questions_next: 'Seuraava',\n questions_send: 'Lähetä',\n questions_type_answer: 'Kirjoitan itse',\n questions_answer_placeholder: 'Kirjoita vastauksesi…',\n close_conversation_title: 'Sulje keskustelu',\n close_conversation_description: 'Haluatko varmasti sulkea tämän keskustelun?',\n close_conversation_cancel: 'Ei',\n close_conversation_confirm: 'Kyllä',\n dialog_close: 'Sulje',\n zoom_in: 'Lähennä',\n zoom_out: 'Loitonna',\n reset_zoom: 'Palauta zoomaus',\n support_chat_aria_label: 'Tukichat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const FrenchLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Écrivez un message...',\n your_issue_has_been_resolved: 'Votre problème a été résolu !',\n new_conversation: 'Nouvelle conversation',\n welcome_screen_title: 'Bienvenue dans notre chat de support',\n welcome_screen_description:\n 'Nous sommes là pour vous aider ! Commencez une conversation et nous vous répondrons dès que possible.',\n your_name_placeholder: 'Votre nom',\n your_email_placeholder: 'Votre adresse e-mail',\n start_chat_button: 'Parler au support',\n start_chat_button_loading: 'Connexion...',\n i_need_more_help: \"Je besoin d'aide plus\",\n this_was_helpful: \"C'était utile\",\n optional: 'Optionnel',\n no_conversations_yet: 'Aucune conversation pour le moment',\n back_to_conversations: 'Retour aux conversations',\n closed_conversations: 'Conversations fermées',\n csat_title: 'Comment s’est passée votre conversation ?',\n csat_submitted_title: 'Vous avez évalué la conversation comme',\n csat_feedback_placeholder: 'Dites-nous en plus... (facultatif)',\n follow_up_placeholder: 'Poser une autre question…',\n companion_layout_label: 'Disposition',\n companion_layout_floating: 'Flottant',\n companion_layout_sidebar: 'Barre latérale',\n companion_layout_fullscreen: 'Plein écran',\n companion_close: 'Fermer',\n companion_history: 'Historique des conversations',\n companion_expand_chat: 'Agrandir le chat',\n companion_sidebar_dock_label: 'Ancrage',\n companion_sidebar_side_label: 'Côté',\n companion_sidebar_left: 'Gauche',\n companion_sidebar_right: 'Droite',\n companion_resize_chat: 'Redimensionner le chat',\n scroll_to_bottom: 'Faire défiler vers le bas',\n thinking: 'Réflexion…',\n running: 'En cours…',\n steps: 'étapes',\n step_arguments: 'Arguments',\n step_result: 'Résultat',\n attach_files:\n 'Joindre des images, des vidéos, des PDF ou des feuilles de calcul (taille maximale 25 Mo)',\n mark_page_active:\n 'Cliquez sur un élément de la page pour le marquer — Échap pour annuler',\n mark_page:\n 'Marquez un élément de la page pour poser une question à son sujet',\n stop_response: 'Arrêter la réponse',\n copy_reply: 'Copier la réponse',\n mentions_empty: 'Aucun résultat',\n copied: 'Copié',\n send_message: 'Envoyer le message',\n upload_failed: 'Échec du téléversement : {error}',\n remove_attachment: 'Supprimer la pièce jointe',\n json_no_items: 'Aucun élément',\n json_no_data: 'Aucune donnée',\n json_no_chart_data: 'Aucune donnée à afficher dans le graphique',\n json_unsupported: 'Non pris en charge : {type}',\n json_see_less: 'Voir moins',\n json_phone_agent: 'Agent téléphonique',\n json_phone_agent_test: 'Tester via le web',\n page_context_remove: 'Retirer le contexte de la page',\n json_see_more: 'Voir {count} de plus',\n queued_label: '{count} En attente',\n remove_queued_message: 'Retirer le message de la file d’attente',\n send_queued_now: 'Envoyer les messages en attente maintenant',\n turn_failed_message:\n 'Un problème est survenu et la réponse n’est pas arrivée.',\n turn_failed_retry: 'Réessayer',\n page_mark_hint: 'Cliquez sur un élément pour le marquer',\n page_mark_escape: 'Échap',\n page_mark_shape_box: 'Encadré',\n page_mark_shape_circle: 'Cercle',\n page_mark_shape_arrow: 'Flèche',\n page_mark_shape_bracket: 'Crochet',\n page_mark_shape_underline: 'Soulignement',\n page_mark_shape_highlight: 'Surlignage',\n page_mark_shape_strike_through: 'Barré',\n page_mark_shape_crossed_off: 'Biffé',\n page_mark_shape_aria: 'Forme de la marque : {shape}',\n page_mark_note_placeholder: 'Ajouter une note… (Entrée pour joindre)',\n page_mark_attach: 'Joindre la marque',\n page_mark_remove: 'Supprimer {label}',\n page_mark_region: 'Zone marquée',\n page_mark_default_message: 'Qu’est-ce que c’est ?',\n file_rejected:\n 'Le type de fichier n’est pas pris en charge ou le fichier est trop volumineux.',\n dictate: 'Dicter',\n stop_dictation: 'Arrêter la dictée',\n dictation_mic_blocked: \"Autorisez l'accès au micro pour dicter\",\n dictation_unavailable: 'La dictée est indisponible pour le moment',\n questions_back: 'Retour',\n questions_next: 'Suivant',\n questions_send: 'Envoyer',\n questions_type_answer: 'Je préfère écrire',\n questions_answer_placeholder: 'Écrivez votre réponse…',\n close_conversation_title: 'Fermer la conversation',\n close_conversation_description:\n 'Voulez-vous vraiment fermer cette conversation ?',\n close_conversation_cancel: 'Non',\n close_conversation_confirm: 'Oui',\n dialog_close: 'Fermer',\n zoom_in: 'Zoom avant',\n zoom_out: 'Zoom arrière',\n reset_zoom: 'Réinitialiser le zoom',\n support_chat_aria_label: 'Chat de support',\n};\n","import type { TranslationInterface } from '.';\n\nexport const HindiLanguage: TranslationInterface = {\n write_a_message_placeholder: 'एक संदेश लिखें...',\n your_issue_has_been_resolved: 'आपकी समस्या हल हो गई है!',\n new_conversation: 'नई बातचीत',\n welcome_screen_title: 'हमारी सहायता चैट में आपका स्वागत है',\n welcome_screen_description:\n 'हम मदद के लिए यहाँ हैं! बातचीत शुरू करें और हम जल्द से जल्द आपसे संपर्क करेंगे।',\n your_name_placeholder: 'आपका नाम',\n your_email_placeholder: 'आपका ईमेल पता',\n start_chat_button: 'सहायता से बात करें',\n start_chat_button_loading: 'कनेक्ट हो रहा है...',\n i_need_more_help: 'मुझे और मदद चाहिए',\n this_was_helpful: 'यह मददगार था',\n optional: 'वैकल्पिक',\n no_conversations_yet: 'अभी तक कोई बातचीत नहीं',\n back_to_conversations: 'बातचीत पर वापस जाएं',\n closed_conversations: 'बंद बातचीत',\n csat_title: 'आपकी बातचीत कैसी रही?',\n csat_submitted_title: 'आपने बातचीत को आंका',\n csat_feedback_placeholder: 'हमें और बताएं... (वैकल्पिक)',\n follow_up_placeholder: 'आगे पूछें…',\n companion_layout_label: 'लेआउट',\n companion_layout_floating: 'फ़्लोटिंग',\n companion_layout_sidebar: 'साइडबार',\n companion_layout_fullscreen: 'पूर्ण स्क्रीन',\n companion_close: 'बंद करें',\n companion_history: 'बातचीत का इतिहास',\n companion_expand_chat: 'चैट फैलाएँ',\n companion_sidebar_dock_label: 'डॉक',\n companion_sidebar_side_label: 'ओर',\n companion_sidebar_left: 'बाएँ',\n companion_sidebar_right: 'दाएँ',\n companion_resize_chat: 'चैट का आकार बदलें',\n scroll_to_bottom: 'नीचे स्क्रॉल करें',\n thinking: 'सोच रहा है…',\n running: 'चल रहा है…',\n steps: 'चरण',\n step_arguments: 'आर्ग्युमेंट',\n step_result: 'परिणाम',\n attach_files:\n 'चित्र, वीडियो, PDF या स्प्रेडशीट संलग्न करें (अधिकतम आकार 25 MB)',\n mark_page_active:\n 'चिह्नित करने के लिए पेज पर किसी भी चीज़ पर क्लिक करें — रद्द करने के लिए Esc दबाएँ',\n mark_page: 'पेज पर किसी चीज़ के बारे में पूछने के लिए उसे चिह्नित करें',\n stop_response: 'जवाब रोकें',\n copy_reply: 'उत्तर कॉपी करें',\n mentions_empty: 'कोई मेल नहीं',\n copied: 'कॉपी हो गया',\n send_message: 'संदेश भेजें',\n upload_failed: 'अपलोड विफल: {error}',\n remove_attachment: 'अटैचमेंट हटाएँ',\n json_no_items: 'कोई आइटम नहीं',\n json_no_data: 'कोई डेटा नहीं',\n json_no_chart_data: 'चार्ट के लिए कोई डेटा नहीं',\n json_unsupported: 'समर्थित नहीं: {type}',\n json_see_less: 'कम देखें',\n json_phone_agent: 'फ़ोन एजेंट',\n json_phone_agent_test: 'वेब से परखें',\n page_context_remove: 'पेज संदर्भ हटाएँ',\n json_see_more: '{count} और देखें',\n queued_label: '{count} कतार में',\n remove_queued_message: 'संदेश को कतार से हटाएँ',\n send_queued_now: 'कतार के संदेश अभी भेजें',\n turn_failed_message: 'कुछ गलत हुआ और जवाब नहीं आया।',\n turn_failed_retry: 'फिर से कोशिश करें',\n page_mark_hint: 'चिह्नित करने के लिए किसी भी चीज़ पर क्लिक करें',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'बॉक्स',\n page_mark_shape_circle: 'वृत्त',\n page_mark_shape_arrow: 'तीर',\n page_mark_shape_bracket: 'कोष्ठक',\n page_mark_shape_underline: 'रेखांकन',\n page_mark_shape_highlight: 'हाइलाइट',\n page_mark_shape_strike_through: 'काटने की रेखा',\n page_mark_shape_crossed_off: 'क्रॉस से काटें',\n page_mark_shape_aria: 'चिह्न का आकार: {shape}',\n page_mark_note_placeholder: 'नोट जोड़ें… (संलग्न करने के लिए Enter दबाएँ)',\n page_mark_attach: 'चिह्न संलग्न करें',\n page_mark_remove: '{label} हटाएँ',\n page_mark_region: 'चिह्नित क्षेत्र',\n page_mark_default_message: 'यह क्या है?',\n file_rejected: 'फ़ाइल प्रकार समर्थित नहीं है या फ़ाइल बहुत बड़ी है।',\n dictate: 'बोलकर लिखें',\n stop_dictation: 'डिक्टेशन रोकें',\n dictation_mic_blocked: 'बोलकर लिखने के लिए माइक्रोफ़ोन की अनुमति दें',\n dictation_unavailable: 'डिक्टेशन अभी उपलब्ध नहीं है',\n questions_back: 'पीछे',\n questions_next: 'आगे',\n questions_send: 'भेजें',\n questions_type_answer: 'मैं खुद लिखूंगा',\n questions_answer_placeholder: 'अपना उत्तर लिखें…',\n close_conversation_title: 'बातचीत बंद करें',\n close_conversation_description:\n 'क्या आप वाकई इस बातचीत को बंद करना चाहते हैं?',\n close_conversation_cancel: 'नहीं',\n close_conversation_confirm: 'हाँ',\n dialog_close: 'बंद करें',\n zoom_in: 'ज़ूम इन',\n zoom_out: 'ज़ूम आउट',\n reset_zoom: 'ज़ूम रीसेट करें',\n support_chat_aria_label: 'सहायता चैट',\n};\n","import type { TranslationInterface } from '.';\n\nexport const ItalianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Scrivi un messaggio...',\n your_issue_has_been_resolved: 'Il tuo problema è stato risolto!',\n new_conversation: 'Nuova conversazione',\n welcome_screen_title: 'Benvenuto nella nostra chat di supporto',\n welcome_screen_description:\n 'Siamo qui per aiutarti! Inizia una conversazione e ti risponderemo il prima possibile.',\n your_name_placeholder: 'Il tuo nome',\n your_email_placeholder: 'Il tuo indirizzo email',\n start_chat_button: 'Parla con il supporto',\n start_chat_button_loading: 'Connessione in corso...',\n i_need_more_help: 'Ho bisogno di ulteriore aiuto',\n this_was_helpful: 'Questo è stato utile',\n optional: 'Opzionale',\n no_conversations_yet: 'Nessuna conversazione ancora',\n back_to_conversations: 'Torna alle conversazioni',\n closed_conversations: 'Conversazioni chiuse',\n csat_title: 'Com’è andata la tua conversazione?',\n csat_submitted_title: 'Hai valutato la conversazione come',\n csat_feedback_placeholder: 'Dicci di più... (facoltativo)',\n follow_up_placeholder: 'Continua…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Mobile',\n companion_layout_sidebar: 'Barra laterale',\n companion_layout_fullscreen: 'Schermo intero',\n companion_close: 'Chiudi',\n companion_history: 'Cronologia conversazioni',\n companion_expand_chat: 'Espandi chat',\n companion_sidebar_dock_label: 'Aggancio',\n companion_sidebar_side_label: 'Lato',\n companion_sidebar_left: 'Sinistra',\n companion_sidebar_right: 'Destra',\n companion_resize_chat: 'Ridimensiona chat',\n scroll_to_bottom: 'Scorri fino in fondo',\n thinking: 'Sto pensando…',\n running: 'In esecuzione…',\n steps: 'passaggi',\n step_arguments: 'Argomenti',\n step_result: 'Risultato',\n attach_files:\n 'Allega immagini, video, PDF o fogli di calcolo (dimensione massima 25 MB)',\n mark_page_active:\n 'Fai clic su un elemento della pagina per contrassegnarlo — Esc per annullare',\n mark_page:\n 'Contrassegna un elemento della pagina per fare una domanda al riguardo',\n stop_response: 'Interrompi risposta',\n copy_reply: 'Copia risposta',\n mentions_empty: 'Nessun risultato',\n copied: 'Copiato',\n send_message: 'Invia messaggio',\n upload_failed: 'Caricamento non riuscito: {error}',\n remove_attachment: 'Rimuovi allegato',\n json_no_items: 'Nessun elemento',\n json_no_data: 'Nessun dato',\n json_no_chart_data: 'Nessun dato per il grafico',\n json_unsupported: 'Non supportato: {type}',\n json_see_less: 'Mostra meno',\n json_phone_agent: 'Agente telefonico',\n json_phone_agent_test: 'Prova via web',\n page_context_remove: 'Rimuovi il contesto della pagina',\n json_see_more: 'Mostra altri {count}',\n queued_label: '{count} In coda',\n remove_queued_message: 'Rimuovi messaggio dalla coda',\n send_queued_now: 'Invia ora i messaggi in coda',\n turn_failed_message:\n 'Si è verificato un problema e la risposta non è arrivata.',\n turn_failed_retry: 'Riprova',\n page_mark_hint: 'Fai clic su un elemento per contrassegnarlo',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Riquadro',\n page_mark_shape_circle: 'Cerchio',\n page_mark_shape_arrow: 'Freccia',\n page_mark_shape_bracket: 'Parentesi',\n page_mark_shape_underline: 'Sottolineatura',\n page_mark_shape_highlight: 'Evidenziazione',\n page_mark_shape_strike_through: 'Barrato',\n page_mark_shape_crossed_off: 'Cancellato con una croce',\n page_mark_shape_aria: 'Forma del segno: {shape}',\n page_mark_note_placeholder: 'Aggiungi una nota… (Invio per allegare)',\n page_mark_attach: 'Allega segno',\n page_mark_remove: 'Rimuovi {label}',\n page_mark_region: 'Area contrassegnata',\n page_mark_default_message: 'Che cos’è questo?',\n file_rejected: 'Il tipo di file non è supportato o il file è troppo grande.',\n dictate: 'Detta',\n stop_dictation: 'Interrompi dettatura',\n dictation_mic_blocked: \"Consenti l'accesso al microfono per dettare\",\n dictation_unavailable: 'La dettatura non è disponibile al momento',\n questions_back: 'Indietro',\n questions_next: 'Avanti',\n questions_send: 'Invia',\n questions_type_answer: 'Lo scrivo io',\n questions_answer_placeholder: 'Scrivi la tua risposta…',\n close_conversation_title: 'Chiudi conversazione',\n close_conversation_description: 'Vuoi davvero chiudere questa conversazione?',\n close_conversation_cancel: 'No',\n close_conversation_confirm: 'Sì',\n dialog_close: 'Chiudi',\n zoom_in: 'Ingrandisci',\n zoom_out: 'Riduci',\n reset_zoom: 'Reimposta zoom',\n support_chat_aria_label: 'Chat di supporto',\n};\n","import type { TranslationInterface } from '.';\n\nexport const JapaneseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'メッセージを入力...',\n your_issue_has_been_resolved: '問題が解決しました!',\n new_conversation: '新しい会話',\n welcome_screen_title: 'サポートチャットへようこそ',\n welcome_screen_description:\n 'お手伝いいたします!会話を開始していただければ、できるだけ早くご連絡いたします。',\n your_name_placeholder: 'お名前',\n your_email_placeholder: 'メールアドレス',\n start_chat_button: 'サポートに相談',\n start_chat_button_loading: '接続中...',\n i_need_more_help: 'さらにサポートが必要です',\n this_was_helpful: '役に立ちました',\n optional: '任意',\n no_conversations_yet: 'まだ会話がありません',\n back_to_conversations: '会話一覧に戻る',\n closed_conversations: '終了した会話',\n csat_title: '会話はいかがでしたか?',\n csat_submitted_title: '会話を次のように評価しました',\n csat_feedback_placeholder: '詳しく教えてください...(任意)',\n follow_up_placeholder: '続けて質問…',\n companion_layout_label: 'レイアウト',\n companion_layout_floating: 'フローティング',\n companion_layout_sidebar: 'サイドバー',\n companion_layout_fullscreen: '全画面',\n companion_close: '閉じる',\n companion_history: '会話履歴',\n companion_expand_chat: 'チャットを拡大',\n companion_sidebar_dock_label: 'ドック',\n companion_sidebar_side_label: '位置',\n companion_sidebar_left: '左',\n companion_sidebar_right: '右',\n companion_resize_chat: 'チャットのサイズを変更',\n scroll_to_bottom: '一番下までスクロール',\n thinking: '考えています…',\n running: '実行中…',\n steps: 'ステップ',\n step_arguments: '引数',\n step_result: '結果',\n attach_files: '画像、動画、PDF、スプレッドシートを添付(最大サイズ 25 MB)',\n mark_page_active: 'ページ上の項目をクリックしてマーク — Esc でキャンセル',\n mark_page: '質問したいページ上の項目をマーク',\n stop_response: '回答を停止',\n copy_reply: '返信をコピー',\n mentions_empty: '一致する項目はありません',\n copied: 'コピーしました',\n send_message: 'メッセージを送信',\n upload_failed: 'アップロードに失敗しました: {error}',\n remove_attachment: '添付ファイルを削除',\n json_no_items: '項目がありません',\n json_no_data: 'データがありません',\n json_no_chart_data: 'グラフ用のデータがありません',\n json_unsupported: '未対応: {type}',\n json_see_less: '表示を減らす',\n json_phone_agent: '電話エージェント',\n json_phone_agent_test: 'ウェブでテスト',\n page_context_remove: 'ページのコンテキストを削除',\n json_see_more: 'さらに {count} 件表示',\n queued_label: '{count} 送信待ち',\n remove_queued_message: '送信待ちのメッセージを削除',\n send_queued_now: '送信待ちのメッセージを今すぐ送信',\n turn_failed_message: '問題が発生し、回答を受信できませんでした。',\n turn_failed_retry: 'もう一度試す',\n page_mark_hint: 'クリックしてマーク',\n page_mark_escape: 'Esc',\n page_mark_shape_box: '枠',\n page_mark_shape_circle: '円',\n page_mark_shape_arrow: '矢印',\n page_mark_shape_bracket: 'かっこ',\n page_mark_shape_underline: '下線',\n page_mark_shape_highlight: 'ハイライト',\n page_mark_shape_strike_through: '取り消し線',\n page_mark_shape_crossed_off: '×印',\n page_mark_shape_aria: 'マークの形状: {shape}',\n page_mark_note_placeholder: 'メモを追加…(Enter で添付)',\n page_mark_attach: 'マークを添付',\n page_mark_remove: '{label}を削除',\n page_mark_region: 'マークした領域',\n page_mark_default_message: 'これは何ですか?',\n file_rejected: '対応していないファイル形式か、ファイルサイズが大きすぎます。',\n dictate: '音声入力',\n stop_dictation: '音声入力を停止',\n dictation_mic_blocked: '音声入力にはマイクへのアクセスを許可してください',\n dictation_unavailable: '音声入力は現在ご利用いただけません',\n questions_back: '戻る',\n questions_next: '次へ',\n questions_send: '送信',\n questions_type_answer: '自分で入力する',\n questions_answer_placeholder: '回答を入力してください…',\n close_conversation_title: '会話を終了',\n close_conversation_description: 'この会話を終了してもよろしいですか?',\n close_conversation_cancel: 'いいえ',\n close_conversation_confirm: 'はい',\n dialog_close: '閉じる',\n zoom_in: '拡大',\n zoom_out: '縮小',\n reset_zoom: 'ズームをリセット',\n support_chat_aria_label: 'サポートチャット',\n};\n","import type { TranslationInterface } from '.';\n\nexport const KoreanLanguage: TranslationInterface = {\n write_a_message_placeholder: '메시지를 입력하세요...',\n your_issue_has_been_resolved: '문제가 해결되었습니다!',\n new_conversation: '새 대화',\n welcome_screen_title: '고객 지원 채팅에 오신 것을 환영합니다',\n welcome_screen_description:\n '도움을 드리기 위해 여기 있습니다! 대화를 시작해 주시면 가능한 한 빨리 연락드리겠습니다.',\n your_name_placeholder: '이름',\n your_email_placeholder: '이메일 주소',\n start_chat_button: '상담원과 대화',\n start_chat_button_loading: '연결 중...',\n i_need_more_help: '추가 도움이 필요합니다',\n this_was_helpful: '도움이 되었습니다',\n optional: '선택 사항',\n no_conversations_yet: '아직 대화가 없습니다',\n back_to_conversations: '대화 목록으로 돌아가기',\n closed_conversations: '종료된 대화',\n csat_title: '대화는 어떠셨나요?',\n csat_submitted_title: '대화를 다음과 같이 평가했습니다',\n csat_feedback_placeholder: '더 알려주세요... (선택 사항)',\n follow_up_placeholder: '이어서 질문…',\n companion_layout_label: '레이아웃',\n companion_layout_floating: '플로팅',\n companion_layout_sidebar: '사이드바',\n companion_layout_fullscreen: '전체 화면',\n companion_close: '닫기',\n companion_history: '대화 기록',\n companion_expand_chat: '채팅 펼치기',\n companion_sidebar_dock_label: '도킹',\n companion_sidebar_side_label: '위치',\n companion_sidebar_left: '왼쪽',\n companion_sidebar_right: '오른쪽',\n companion_resize_chat: '채팅 크기 조절',\n scroll_to_bottom: '맨 아래로 스크롤',\n thinking: '생각 중…',\n running: '실행 중…',\n steps: '단계',\n step_arguments: '인수',\n step_result: '결과',\n attach_files: '이미지, 동영상, PDF 또는 스프레드시트 첨부(최대 크기 25 MB)',\n mark_page_active:\n '페이지에서 표시할 항목을 클릭하세요 — 취소하려면 Esc를 누르세요',\n mark_page: '질문할 페이지의 항목을 표시하세요',\n stop_response: '응답 중지',\n copy_reply: '답변 복사',\n mentions_empty: '일치하는 항목 없음',\n copied: '복사됨',\n send_message: '메시지 보내기',\n upload_failed: '업로드 실패: {error}',\n remove_attachment: '첨부 파일 삭제',\n json_no_items: '항목 없음',\n json_no_data: '데이터 없음',\n json_no_chart_data: '차트 데이터 없음',\n json_unsupported: '지원되지 않음: {type}',\n json_see_less: '간단히 보기',\n json_phone_agent: '전화 상담원',\n json_phone_agent_test: '웹에서 테스트',\n page_context_remove: '페이지 컨텍스트 제거',\n json_see_more: '{count}개 더 보기',\n queued_label: '{count} 대기 중',\n remove_queued_message: '대기열에서 메시지 삭제',\n send_queued_now: '대기 중인 메시지 지금 보내기',\n turn_failed_message: '문제가 발생하여 답변이 도착하지 않았습니다.',\n turn_failed_retry: '다시 시도',\n page_mark_hint: '표시할 항목을 클릭하세요',\n page_mark_escape: 'Esc',\n page_mark_shape_box: '상자',\n page_mark_shape_circle: '원',\n page_mark_shape_arrow: '화살표',\n page_mark_shape_bracket: '괄호',\n page_mark_shape_underline: '밑줄',\n page_mark_shape_highlight: '강조',\n page_mark_shape_strike_through: '취소선',\n page_mark_shape_crossed_off: 'X표',\n page_mark_shape_aria: '표시 모양: {shape}',\n page_mark_note_placeholder: '메모 추가…(Enter로 첨부)',\n page_mark_attach: '표시 첨부',\n page_mark_remove: '{label} 삭제',\n page_mark_region: '표시된 영역',\n page_mark_default_message: '이건 무엇인가요?',\n file_rejected: '지원되지 않는 파일 형식이거나 파일이 너무 큽니다.',\n dictate: '받아쓰기',\n stop_dictation: '받아쓰기 중지',\n dictation_mic_blocked: '받아쓰기를 하려면 마이크 접근을 허용하세요',\n dictation_unavailable: '지금은 받아쓰기를 사용할 수 없습니다',\n questions_back: '뒤로',\n questions_next: '다음',\n questions_send: '보내기',\n questions_type_answer: '직접 입력할게요',\n questions_answer_placeholder: '답변을 입력하세요…',\n close_conversation_title: '대화 종료',\n close_conversation_description: '이 대화를 종료하시겠습니까?',\n close_conversation_cancel: '아니요',\n close_conversation_confirm: '예',\n dialog_close: '닫기',\n zoom_in: '확대',\n zoom_out: '축소',\n reset_zoom: '확대/축소 초기화',\n support_chat_aria_label: '고객 지원 채팅',\n};\n","import type { TranslationInterface } from '.';\n\nexport const DutchLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Schrijf een bericht...',\n your_issue_has_been_resolved: 'Uw probleem is opgelost!',\n new_conversation: 'Nieuw gesprek',\n welcome_screen_title: 'Welkom bij onze supportchat',\n welcome_screen_description:\n 'We zijn hier om te helpen! Begin een gesprek en we nemen zo snel mogelijk contact met u op.',\n your_name_placeholder: 'Uw naam',\n your_email_placeholder: 'Uw e-mailadres',\n start_chat_button: 'Praat met ondersteuning',\n start_chat_button_loading: 'Verbinding maken...',\n i_need_more_help: 'Ik heb nog meer hulp nodig',\n this_was_helpful: 'Mijn vraag is opgelost',\n optional: 'Optioneel',\n no_conversations_yet: 'Nog geen gesprekken',\n back_to_conversations: 'Terug naar gesprekken',\n closed_conversations: 'Afgesloten gesprekken',\n csat_title: 'Hoe was je gesprek?',\n csat_submitted_title: 'Je hebt het gesprek beoordeeld als',\n csat_feedback_placeholder: 'Vertel ons meer... (optioneel)',\n follow_up_placeholder: 'Verder vragen…',\n companion_layout_label: 'Indeling',\n companion_layout_floating: 'Zwevend',\n companion_layout_sidebar: 'Zijbalk',\n companion_layout_fullscreen: 'Volledig scherm',\n companion_close: 'Sluiten',\n companion_history: 'Gespreksgeschiedenis',\n companion_expand_chat: 'Chat uitvouwen',\n companion_sidebar_dock_label: 'Vastzetten',\n companion_sidebar_side_label: 'Zijde',\n companion_sidebar_left: 'Links',\n companion_sidebar_right: 'Rechts',\n companion_resize_chat: 'Chatgrootte wijzigen',\n scroll_to_bottom: 'Naar beneden scrollen',\n thinking: 'Denkt na…',\n running: 'Wordt uitgevoerd…',\n steps: 'stappen',\n step_arguments: 'Argumenten',\n step_result: 'Resultaat',\n attach_files:\n \"Afbeeldingen, video's, pdf's of spreadsheets bijvoegen (maximale grootte 25 MB)\",\n mark_page_active:\n 'Klik op iets op de pagina om het te markeren — Esc om te annuleren',\n mark_page: 'Markeer iets op de pagina om er een vraag over te stellen',\n stop_response: 'Antwoord stoppen',\n copy_reply: 'Antwoord kopiëren',\n mentions_empty: 'Geen resultaten',\n copied: 'Gekopieerd',\n send_message: 'Bericht verzenden',\n upload_failed: 'Uploaden mislukt: {error}',\n remove_attachment: 'Bijlage verwijderen',\n json_no_items: 'Geen items',\n json_no_data: 'Geen gegevens',\n json_no_chart_data: 'Geen gegevens voor de grafiek',\n json_unsupported: 'Niet ondersteund: {type}',\n json_see_less: 'Minder weergeven',\n json_phone_agent: 'Telefoonagent',\n json_phone_agent_test: 'Testen via web',\n page_context_remove: 'Paginacontext verwijderen',\n json_see_more: 'Nog {count} weergeven',\n queued_label: '{count} In wachtrij',\n remove_queued_message: 'Bericht uit wachtrij verwijderen',\n send_queued_now: 'Berichten in wachtrij nu verzenden',\n turn_failed_message: 'Er ging iets mis en het antwoord is niet aangekomen.',\n turn_failed_retry: 'Opnieuw proberen',\n page_mark_hint: 'Klik op iets om het te markeren',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kader',\n page_mark_shape_circle: 'Cirkel',\n page_mark_shape_arrow: 'Pijl',\n page_mark_shape_bracket: 'Haakje',\n page_mark_shape_underline: 'Onderstrepen',\n page_mark_shape_highlight: 'Markeren',\n page_mark_shape_strike_through: 'Doorhalen',\n page_mark_shape_crossed_off: 'Doorkruisen',\n page_mark_shape_aria: 'Vorm van markering: {shape}',\n page_mark_note_placeholder: 'Voeg een notitie toe… (Enter om bij te voegen)',\n page_mark_attach: 'Markering bijvoegen',\n page_mark_remove: '{label} verwijderen',\n page_mark_region: 'Gemarkeerd gebied',\n page_mark_default_message: 'Wat is dit?',\n file_rejected:\n 'Het bestandstype wordt niet ondersteund of het bestand is te groot.',\n dictate: 'Dicteren',\n stop_dictation: 'Dicteren stoppen',\n dictation_mic_blocked: 'Sta microfoontoegang toe om te dicteren',\n dictation_unavailable: 'Dicteren is momenteel niet beschikbaar',\n questions_back: 'Terug',\n questions_next: 'Volgende',\n questions_send: 'Verzenden',\n questions_type_answer: 'Ik typ het zelf',\n questions_answer_placeholder: 'Typ je antwoord…',\n close_conversation_title: 'Gesprek sluiten',\n close_conversation_description:\n 'Weet je zeker dat je dit gesprek wilt sluiten?',\n close_conversation_cancel: 'Nee',\n close_conversation_confirm: 'Ja',\n dialog_close: 'Sluiten',\n zoom_in: 'Inzoomen',\n zoom_out: 'Uitzoomen',\n reset_zoom: 'Zoom herstellen',\n support_chat_aria_label: 'Supportchat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const NorwegianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv en melding...',\n your_issue_has_been_resolved: 'Problemet ditt er løst!',\n new_conversation: 'Ny samtale',\n welcome_screen_title: 'Velkommen til vår kundestøtte-chat',\n welcome_screen_description:\n 'Vi er her for å hjelpe! Start en samtale så kommer vi tilbake til deg så snart som mulig.',\n your_name_placeholder: 'Ditt navn',\n your_email_placeholder: 'Din e-postadresse',\n start_chat_button: 'Snakk med kundestøtte',\n start_chat_button_loading: 'Kobler til...',\n i_need_more_help: 'Jeg trenger mer hjelp',\n this_was_helpful: 'Dette var nyttig',\n optional: 'Valgfritt',\n no_conversations_yet: 'Ingen samtaler ennå',\n back_to_conversations: 'Tilbake til samtaler',\n closed_conversations: 'Lukkede samtaler',\n csat_title: 'Hvordan var samtalen din?',\n csat_submitted_title: 'Du vurderte samtalen som',\n csat_feedback_placeholder: 'Fortell oss mer... (valgfritt)',\n follow_up_placeholder: 'Følg opp…',\n companion_layout_label: 'Oppsett',\n companion_layout_floating: 'Flytende',\n companion_layout_sidebar: 'Sidepanel',\n companion_layout_fullscreen: 'Fullskjerm',\n companion_close: 'Lukk',\n companion_history: 'Samtalehistorikk',\n companion_expand_chat: 'Utvid chatten',\n companion_sidebar_dock_label: 'Dokking',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Venstre',\n companion_sidebar_right: 'Høyre',\n companion_resize_chat: 'Endre størrelsen på chatten',\n scroll_to_bottom: 'Rull til bunnen',\n thinking: 'Tenker…',\n running: 'Kjører…',\n steps: 'trinn',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Legg ved bilder, videoer, PDF-er eller regneark (maksimal størrelse 25 MB)',\n mark_page_active:\n 'Klikk på noe på siden for å markere det — Esc for å avbryte',\n mark_page: 'Marker noe på siden for å spørre om det',\n stop_response: 'Stopp svar',\n copy_reply: 'Kopier svar',\n mentions_empty: 'Ingen treff',\n copied: 'Kopiert',\n send_message: 'Send melding',\n upload_failed: 'Opplasting mislyktes: {error}',\n remove_attachment: 'Fjern vedlegg',\n json_no_items: 'Ingen elementer',\n json_no_data: 'Ingen data',\n json_no_chart_data: 'Ingen data for diagrammet',\n json_unsupported: 'Ikke støttet: {type}',\n json_see_less: 'Vis mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Test via nett',\n page_context_remove: 'Fjern sidekontekst',\n json_see_more: 'Vis {count} til',\n queued_label: '{count} I kø',\n remove_queued_message: 'Fjern meldingen fra køen',\n send_queued_now: 'Send meldinger i køen nå',\n turn_failed_message: 'Noe gikk galt, og svaret kom ikke fram.',\n turn_failed_retry: 'Prøv igjen',\n page_mark_hint: 'Klikk på noe for å markere det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ramme',\n page_mark_shape_circle: 'Sirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Klamme',\n page_mark_shape_underline: 'Understreking',\n page_mark_shape_highlight: 'Utheving',\n page_mark_shape_strike_through: 'Gjennomstreking',\n page_mark_shape_crossed_off: 'Kryss ut',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Legg til et notat… (Enter for å legge ved)',\n page_mark_attach: 'Legg ved markering',\n page_mark_remove: 'Fjern {label}',\n page_mark_region: 'Markert område',\n page_mark_default_message: 'Hva er dette?',\n file_rejected: 'Filtypen støttes ikke, eller filen er for stor.',\n dictate: 'Dikter',\n stop_dictation: 'Stopp diktering',\n dictation_mic_blocked: 'Tillat mikrofontilgang for å diktere',\n dictation_unavailable: 'Diktering er ikke tilgjengelig akkurat nå',\n questions_back: 'Tilbake',\n questions_next: 'Neste',\n questions_send: 'Send',\n questions_type_answer: 'Jeg skriver det selv',\n questions_answer_placeholder: 'Skriv svaret ditt…',\n close_conversation_title: 'Lukk samtale',\n close_conversation_description:\n 'Er du sikker på at du vil lukke denne samtalen?',\n close_conversation_cancel: 'Nei',\n close_conversation_confirm: 'Ja',\n dialog_close: 'Lukk',\n zoom_in: 'Zoom inn',\n zoom_out: 'Zoom ut',\n reset_zoom: 'Tilbakestill zoom',\n support_chat_aria_label: 'Support-chat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const PolishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napisz wiadomość...',\n your_issue_has_been_resolved: 'Twój problem został rozwiązany!',\n new_conversation: 'Nowa rozmowa',\n welcome_screen_title: 'Witamy w naszym czacie wsparcia',\n welcome_screen_description:\n 'Jesteśmy tutaj, aby pomóc! Rozpocznij rozmowę, a odpowiemy jak najszybciej.',\n your_name_placeholder: 'Twoje imię',\n your_email_placeholder: 'Twój adres email',\n start_chat_button: 'Porozmawiaj ze wsparciem',\n start_chat_button_loading: 'Łączenie...',\n i_need_more_help: 'Potrzebuję więcej pomocy',\n this_was_helpful: 'To było pomocne',\n optional: 'Opcjonalne',\n no_conversations_yet: 'Jeszcze brak rozmów',\n back_to_conversations: 'Powrót do rozmów',\n closed_conversations: 'Zamknięte rozmowy',\n csat_title: 'Jak przebiegła Twoja rozmowa?',\n csat_submitted_title: 'Oceniłeś rozmowę jako',\n csat_feedback_placeholder: 'Powiedz nam więcej... (opcjonalnie)',\n follow_up_placeholder: 'Dopytaj…',\n companion_layout_label: 'Układ',\n companion_layout_floating: 'Pływający',\n companion_layout_sidebar: 'Pasek boczny',\n companion_layout_fullscreen: 'Pełny ekran',\n companion_close: 'Zamknij',\n companion_history: 'Historia rozmów',\n companion_expand_chat: 'Rozwiń czat',\n companion_sidebar_dock_label: 'Dokowanie',\n companion_sidebar_side_label: 'Strona',\n companion_sidebar_left: 'Lewa',\n companion_sidebar_right: 'Prawa',\n companion_resize_chat: 'Zmień rozmiar czatu',\n scroll_to_bottom: 'Przewiń na dół',\n thinking: 'Myślę…',\n running: 'W toku…',\n steps: 'kroki',\n step_arguments: 'Argumenty',\n step_result: 'Wynik',\n attach_files:\n 'Dołącz obrazy, filmy, pliki PDF lub arkusze kalkulacyjne (maksymalny rozmiar 25 MB)',\n mark_page_active:\n 'Kliknij coś na stronie, aby to oznaczyć — Esc, aby anulować',\n mark_page: 'Oznacz coś na stronie, aby o to zapytać',\n stop_response: 'Zatrzymaj odpowiedź',\n copy_reply: 'Kopiuj odpowiedź',\n mentions_empty: 'Brak wyników',\n copied: 'Skopiowano',\n send_message: 'Wyślij wiadomość',\n upload_failed: 'Przesyłanie nie powiodło się: {error}',\n remove_attachment: 'Usuń załącznik',\n json_no_items: 'Brak elementów',\n json_no_data: 'Brak danych',\n json_no_chart_data: 'Brak danych do wykresu',\n json_unsupported: 'Nieobsługiwane: {type}',\n json_see_less: 'Pokaż mniej',\n json_phone_agent: 'Agent telefoniczny',\n json_phone_agent_test: 'Przetestuj w sieci',\n page_context_remove: 'Usuń kontekst strony',\n json_see_more: 'Pokaż jeszcze {count}',\n queued_label: '{count} W kolejce',\n remove_queued_message: 'Usuń wiadomość z kolejki',\n send_queued_now: 'Wyślij wiadomości z kolejki teraz',\n turn_failed_message: 'Coś poszło nie tak i odpowiedź nie dotarła.',\n turn_failed_retry: 'Spróbuj ponownie',\n page_mark_hint: 'Kliknij coś, aby to oznaczyć',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ramka',\n page_mark_shape_circle: 'Okrąg',\n page_mark_shape_arrow: 'Strzałka',\n page_mark_shape_bracket: 'Nawias',\n page_mark_shape_underline: 'Podkreślenie',\n page_mark_shape_highlight: 'Wyróżnienie',\n page_mark_shape_strike_through: 'Przekreślenie',\n page_mark_shape_crossed_off: 'Skreślenie krzyżykiem',\n page_mark_shape_aria: 'Kształt oznaczenia: {shape}',\n page_mark_note_placeholder: 'Dodaj notatkę… (Enter, aby dołączyć)',\n page_mark_attach: 'Dołącz oznaczenie',\n page_mark_remove: 'Usuń {label}',\n page_mark_region: 'Oznaczony obszar',\n page_mark_default_message: 'Co to jest?',\n file_rejected: 'Typ pliku nie jest obsługiwany lub plik jest za duży.',\n dictate: 'Dyktuj',\n stop_dictation: 'Zatrzymaj dyktowanie',\n dictation_mic_blocked: 'Zezwól na dostęp do mikrofonu, aby dyktować',\n dictation_unavailable: 'Dyktowanie jest obecnie niedostępne',\n questions_back: 'Wstecz',\n questions_next: 'Dalej',\n questions_send: 'Wyślij',\n questions_type_answer: 'Napiszę sam',\n questions_answer_placeholder: 'Wpisz swoją odpowiedź…',\n close_conversation_title: 'Zamknij rozmowę',\n close_conversation_description: 'Czy na pewno chcesz zamknąć tę rozmowę?',\n close_conversation_cancel: 'Nie',\n close_conversation_confirm: 'Tak',\n dialog_close: 'Zamknij',\n zoom_in: 'Powiększ',\n zoom_out: 'Pomniejsz',\n reset_zoom: 'Resetuj powiększenie',\n support_chat_aria_label: 'Czat pomocy',\n};\n","import type { TranslationInterface } from '.';\n\nexport const PortugueseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Escreva uma mensagem...',\n your_issue_has_been_resolved: 'Seu problema foi resolvido!',\n new_conversation: 'Nova conversa',\n welcome_screen_title: 'Bem-vindo ao nosso chat de suporte',\n welcome_screen_description:\n 'Estamos aqui para ajudar! Inicie uma conversa e responderemos o mais rápido possível.',\n your_name_placeholder: 'Seu nome',\n your_email_placeholder: 'Seu endereço de email',\n start_chat_button: 'Falar com o suporte',\n start_chat_button_loading: 'Conectando...',\n i_need_more_help: 'preciso de mais ajuda',\n this_was_helpful: 'Isso foi útil',\n optional: 'Opcional',\n no_conversations_yet: 'Nenhuma conversa ainda',\n back_to_conversations: 'Voltar para conversas',\n closed_conversations: 'Conversas fechadas',\n csat_title: 'Como foi a sua conversa?',\n csat_submitted_title: 'Você avaliou a conversa como',\n csat_feedback_placeholder: 'Conte-nos mais... (opcional)',\n follow_up_placeholder: 'Continuar…',\n companion_layout_label: 'Esquema',\n companion_layout_floating: 'Flutuante',\n companion_layout_sidebar: 'Barra lateral',\n companion_layout_fullscreen: 'Ecrã inteiro',\n companion_close: 'Fechar',\n companion_history: 'Histórico de conversas',\n companion_expand_chat: 'Expandir chat',\n companion_sidebar_dock_label: 'Ancoragem',\n companion_sidebar_side_label: 'Lado',\n companion_sidebar_left: 'Esquerda',\n companion_sidebar_right: 'Direita',\n companion_resize_chat: 'Redimensionar chat',\n scroll_to_bottom: 'Deslocar para o fim',\n thinking: 'A pensar…',\n running: 'Em execução…',\n steps: 'passos',\n step_arguments: 'Argumentos',\n step_result: 'Resultado',\n attach_files:\n 'Anexar imagens, vídeos, PDFs ou folhas de cálculo (tamanho máximo 25 MB)',\n mark_page_active:\n 'Clique em algo na página para o marcar — Esc para cancelar',\n mark_page: 'Marque algo na página para perguntar sobre isso',\n stop_response: 'Parar resposta',\n copy_reply: 'Copiar resposta',\n mentions_empty: 'Sem resultados',\n copied: 'Copiado',\n send_message: 'Enviar mensagem',\n upload_failed: 'Falha no carregamento: {error}',\n remove_attachment: 'Remover anexo',\n json_no_items: 'Sem itens',\n json_no_data: 'Sem dados',\n json_no_chart_data: 'Sem dados para o gráfico',\n json_unsupported: 'Não suportado: {type}',\n json_see_less: 'Ver menos',\n json_phone_agent: 'Agente telefónico',\n json_phone_agent_test: 'Testar via web',\n page_context_remove: 'Remover contexto da página',\n json_see_more: 'Ver mais {count}',\n queued_label: '{count} Na fila',\n remove_queued_message: 'Remover mensagem da fila',\n send_queued_now: 'Enviar mensagens da fila agora',\n turn_failed_message: 'Algo correu mal e a resposta não chegou.',\n turn_failed_retry: 'Tentar novamente',\n page_mark_hint: 'Clique em algo para o marcar',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Caixa',\n page_mark_shape_circle: 'Círculo',\n page_mark_shape_arrow: 'Seta',\n page_mark_shape_bracket: 'Parêntese',\n page_mark_shape_underline: 'Sublinhado',\n page_mark_shape_highlight: 'Realce',\n page_mark_shape_strike_through: 'Rasurado',\n page_mark_shape_crossed_off: 'Riscado em cruz',\n page_mark_shape_aria: 'Forma da marca: {shape}',\n page_mark_note_placeholder: 'Adicionar nota… (Enter para anexar)',\n page_mark_attach: 'Anexar marca',\n page_mark_remove: 'Remover {label}',\n page_mark_region: 'Área marcada',\n page_mark_default_message: 'O que é isto?',\n file_rejected:\n 'O tipo de ficheiro não é suportado ou o ficheiro é demasiado grande.',\n dictate: 'Ditar',\n stop_dictation: 'Parar ditado',\n dictation_mic_blocked: 'Permita o acesso ao microfone para ditar',\n dictation_unavailable: 'O ditado não está disponível agora',\n questions_back: 'Voltar',\n questions_next: 'Seguinte',\n questions_send: 'Enviar',\n questions_type_answer: 'Prefiro escrever',\n questions_answer_placeholder: 'Escreva a sua resposta…',\n close_conversation_title: 'Encerrar conversa',\n close_conversation_description:\n 'Tem certeza de que deseja encerrar esta conversa?',\n close_conversation_cancel: 'Não',\n close_conversation_confirm: 'Sim',\n dialog_close: 'Fechar',\n zoom_in: 'Ampliar',\n zoom_out: 'Reduzir',\n reset_zoom: 'Redefinir zoom',\n support_chat_aria_label: 'Chat de suporte',\n};\n","import type { TranslationInterface } from '.';\n\nexport const RomanianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Scrie un mesaj...',\n your_issue_has_been_resolved: 'Problema ta a fost rezolvată!',\n new_conversation: 'Conversație nouă',\n welcome_screen_title: 'Bine ai venit la chat-ul nostru de suport',\n welcome_screen_description:\n 'Suntem aici să te ajutăm! Începe o conversație și îți vom răspunde cât mai curând posibil.',\n your_name_placeholder: 'Numele tău',\n your_email_placeholder: 'Adresa ta de email',\n start_chat_button: 'Vorbește cu suportul',\n start_chat_button_loading: 'Se conectează...',\n i_need_more_help: 'Am nevoie de mai mult ajutor',\n this_was_helpful: 'Acest lucru a fost util',\n optional: 'Opțional',\n no_conversations_yet: 'Încă nu există conversații',\n back_to_conversations: 'Înapoi la conversații',\n closed_conversations: 'Conversații închise',\n csat_title: 'Cum a fost conversația ta?',\n csat_submitted_title: 'Ai evaluat conversația ca',\n csat_feedback_placeholder: 'Spune-ne mai multe... (opțional)',\n follow_up_placeholder: 'Continuă…',\n companion_layout_label: 'Aspect',\n companion_layout_floating: 'Flotant',\n companion_layout_sidebar: 'Bară laterală',\n companion_layout_fullscreen: 'Ecran complet',\n companion_close: 'Închide',\n companion_history: 'Istoricul conversațiilor',\n companion_expand_chat: 'Extinde chatul',\n companion_sidebar_dock_label: 'Andocare',\n companion_sidebar_side_label: 'Parte',\n companion_sidebar_left: 'Stânga',\n companion_sidebar_right: 'Dreapta',\n companion_resize_chat: 'Redimensionează chatul',\n scroll_to_bottom: 'Derulează în partea de jos',\n thinking: 'Mă gândesc…',\n running: 'În curs…',\n steps: 'pași',\n step_arguments: 'Argumente',\n step_result: 'Rezultat',\n attach_files:\n 'Atașează imagini, videoclipuri, PDF-uri sau foi de calcul (dimensiune maximă 25 MB)',\n mark_page_active:\n 'Dă clic pe ceva din pagină pentru a-l marca — Esc pentru anulare',\n mark_page: 'Marchează ceva din pagină pentru a întreba despre acel element',\n stop_response: 'Oprește răspunsul',\n copy_reply: 'Copiază răspunsul',\n mentions_empty: 'Niciun rezultat',\n copied: 'Copiat',\n send_message: 'Trimite mesajul',\n upload_failed: 'Încărcarea a eșuat: {error}',\n remove_attachment: 'Elimină atașamentul',\n json_no_items: 'Niciun element',\n json_no_data: 'Nu există date',\n json_no_chart_data: 'Nu există date pentru grafic',\n json_unsupported: 'Neacceptat: {type}',\n json_see_less: 'Vezi mai puțin',\n json_phone_agent: 'Agent telefonic',\n json_phone_agent_test: 'Testează pe web',\n page_context_remove: 'Elimină contextul paginii',\n json_see_more: 'Vezi încă {count}',\n queued_label: '{count} În așteptare',\n remove_queued_message: 'Elimină mesajul din coadă',\n send_queued_now: 'Trimite acum mesajele din coadă',\n turn_failed_message: 'Ceva nu a mers bine și răspunsul nu a sosit.',\n turn_failed_retry: 'Încearcă din nou',\n page_mark_hint: 'Dă clic pe ceva pentru a-l marca',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Chenar',\n page_mark_shape_circle: 'Cerc',\n page_mark_shape_arrow: 'Săgeată',\n page_mark_shape_bracket: 'Paranteză',\n page_mark_shape_underline: 'Subliniere',\n page_mark_shape_highlight: 'Evidențiere',\n page_mark_shape_strike_through: 'Tăiere',\n page_mark_shape_crossed_off: 'Tăiere în cruce',\n page_mark_shape_aria: 'Forma marcajului: {shape}',\n page_mark_note_placeholder: 'Adaugă o notă… (Enter pentru atașare)',\n page_mark_attach: 'Atașează marcajul',\n page_mark_remove: 'Elimină {label}',\n page_mark_region: 'Zonă marcată',\n page_mark_default_message: 'Ce este acesta?',\n file_rejected:\n 'Tipul de fișier nu este acceptat sau fișierul este prea mare.',\n dictate: 'Dictează',\n stop_dictation: 'Oprește dictarea',\n dictation_mic_blocked: 'Permite accesul la microfon pentru a dicta',\n dictation_unavailable: 'Dictarea nu este disponibilă momentan',\n questions_back: 'Înapoi',\n questions_next: 'Înainte',\n questions_send: 'Trimite',\n questions_type_answer: 'Scriu eu',\n questions_answer_placeholder: 'Scrieți răspunsul dvs.…',\n close_conversation_title: 'Închide conversația',\n close_conversation_description: 'Sigur vrei să închizi această conversație?',\n close_conversation_cancel: 'Nu',\n close_conversation_confirm: 'Da',\n dialog_close: 'Închide',\n zoom_in: 'Mărește',\n zoom_out: 'Micșorează',\n reset_zoom: 'Resetează zoomul',\n support_chat_aria_label: 'Chat de asistență',\n};\n","import type { TranslationInterface } from '.';\n\nexport const SwedishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv ett meddelande...',\n your_issue_has_been_resolved: 'Ditt problem har lösts!',\n new_conversation: 'Ny konversation',\n welcome_screen_title: 'Välkommen till vår supportchatt',\n welcome_screen_description:\n 'Vi är här för att hjälpa! Starta en konversation så återkommer vi till dig så snart som möjligt.',\n your_name_placeholder: 'Ditt namn',\n your_email_placeholder: 'Din e-postadress',\n start_chat_button: 'Prata med support',\n start_chat_button_loading: 'Ansluter...',\n i_need_more_help: 'Jag behöver mer hjälp',\n this_was_helpful: 'Detta var användbart',\n optional: 'Frivilligt',\n no_conversations_yet: 'Inga konversationer ännu',\n back_to_conversations: 'Tillbaka till konversationer',\n closed_conversations: 'Stängda konversationer',\n csat_title: 'Hur var din konversation?',\n csat_submitted_title: 'Du betygsatte konversationen som',\n csat_feedback_placeholder: 'Berätta mer... (valfritt)',\n follow_up_placeholder: 'Följ upp…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Flytande',\n companion_layout_sidebar: 'Sidopanel',\n companion_layout_fullscreen: 'Helskärm',\n companion_close: 'Stäng',\n companion_history: 'Konversationshistorik',\n companion_expand_chat: 'Expandera chatten',\n companion_sidebar_dock_label: 'Dockning',\n companion_sidebar_side_label: 'Sida',\n companion_sidebar_left: 'Vänster',\n companion_sidebar_right: 'Höger',\n companion_resize_chat: 'Ändra chattens storlek',\n scroll_to_bottom: 'Rulla längst ned',\n thinking: 'Tänker…',\n running: 'Körs…',\n steps: 'steg',\n step_arguments: 'Argument',\n step_result: 'Resultat',\n attach_files:\n 'Bifoga bilder, videor, PDF-filer eller kalkylblad (maximal storlek 25 MB)',\n mark_page_active:\n 'Klicka på något på sidan för att markera det — Esc för att avbryta',\n mark_page: 'Markera något på sidan för att fråga om det',\n stop_response: 'Stoppa svaret',\n copy_reply: 'Kopiera svar',\n mentions_empty: 'Inga träffar',\n copied: 'Kopierat',\n send_message: 'Skicka meddelande',\n upload_failed: 'Uppladdningen misslyckades: {error}',\n remove_attachment: 'Ta bort bilaga',\n json_no_items: 'Inga objekt',\n json_no_data: 'Inga data',\n json_no_chart_data: 'Inga data för diagrammet',\n json_unsupported: 'Stöds inte: {type}',\n json_see_less: 'Visa mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Testa via webben',\n page_context_remove: 'Ta bort sidkontext',\n json_see_more: 'Visa ytterligare {count}',\n queued_label: '{count} I kö',\n remove_queued_message: 'Ta bort meddelandet från kön',\n send_queued_now: 'Skicka köade meddelanden nu',\n turn_failed_message: 'Något gick fel och svaret kom inte fram.',\n turn_failed_retry: 'Försök igen',\n page_mark_hint: 'Klicka på något för att markera det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ruta',\n page_mark_shape_circle: 'Cirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Hakparentes',\n page_mark_shape_underline: 'Understrykning',\n page_mark_shape_highlight: 'Markering',\n page_mark_shape_strike_through: 'Genomstrykning',\n page_mark_shape_crossed_off: 'Kryssa över',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Lägg till en anteckning… (Enter för att bifoga)',\n page_mark_attach: 'Bifoga markering',\n page_mark_remove: 'Ta bort {label}',\n page_mark_region: 'Markerat område',\n page_mark_default_message: 'Vad är det här?',\n file_rejected: 'Filtypen stöds inte eller filen är för stor.',\n dictate: 'Diktera',\n stop_dictation: 'Sluta diktera',\n dictation_mic_blocked: 'Tillåt mikrofonåtkomst för att diktera',\n dictation_unavailable: 'Diktering är inte tillgänglig just nu',\n questions_back: 'Tillbaka',\n questions_next: 'Nästa',\n questions_send: 'Skicka',\n questions_type_answer: 'Jag skriver själv',\n questions_answer_placeholder: 'Skriv ditt svar…',\n close_conversation_title: 'Avsluta konversation',\n close_conversation_description:\n 'Är du säker på att du vill avsluta den här konversationen?',\n close_conversation_cancel: 'Nej',\n close_conversation_confirm: 'Ja',\n dialog_close: 'Stäng',\n zoom_in: 'Zooma in',\n zoom_out: 'Zooma ut',\n reset_zoom: 'Återställ zoom',\n support_chat_aria_label: 'Supportchatt',\n};\n","import type { TranslationInterface } from '.';\n\nexport const RussianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Напишите сообщение...',\n your_issue_has_been_resolved: 'Ваша проблема решена!',\n new_conversation: 'Новый разговор',\n welcome_screen_title: 'Добро пожаловать в чат поддержки',\n welcome_screen_description:\n 'Мы здесь, чтобы помочь! Начните разговор, и мы ответим вам как можно скорее.',\n your_name_placeholder: 'Ваше имя',\n your_email_placeholder: 'Ваш адрес электронной почты',\n start_chat_button: 'Связаться с поддержкой',\n start_chat_button_loading: 'Подключение...',\n i_need_more_help: 'Мне нужна дополнительная помощь',\n this_was_helpful: 'Это было полезно',\n optional: 'Необязательно',\n no_conversations_yet: 'Пока нет разговоров',\n back_to_conversations: 'Назад к разговорам',\n closed_conversations: 'Закрытые разговоры',\n csat_title: 'Как прошёл ваш разговор?',\n csat_submitted_title: 'Вы оценили разговор как',\n csat_feedback_placeholder: 'Расскажите подробнее... (необязательно)',\n follow_up_placeholder: 'Уточнить…',\n companion_layout_label: 'Макет',\n companion_layout_floating: 'Плавающий',\n companion_layout_sidebar: 'Боковая панель',\n companion_layout_fullscreen: 'На весь экран',\n companion_close: 'Закрыть',\n companion_history: 'История разговоров',\n companion_expand_chat: 'Развернуть чат',\n companion_sidebar_dock_label: 'Закрепление',\n companion_sidebar_side_label: 'Сторона',\n companion_sidebar_left: 'Слева',\n companion_sidebar_right: 'Справа',\n companion_resize_chat: 'Изменить размер чата',\n scroll_to_bottom: 'Прокрутить вниз',\n thinking: 'Думаю…',\n running: 'Выполняется…',\n steps: 'шаги',\n step_arguments: 'Аргументы',\n step_result: 'Результат',\n attach_files:\n 'Прикрепить изображения, видео, PDF-файлы или таблицы (максимальный размер 25 МБ)',\n mark_page_active:\n 'Нажмите на элемент страницы, чтобы отметить его — Esc для отмены',\n mark_page: 'Отметьте элемент на странице, чтобы задать вопрос о нём',\n stop_response: 'Остановить ответ',\n copy_reply: 'Скопировать ответ',\n mentions_empty: 'Ничего не найдено',\n copied: 'Скопировано',\n send_message: 'Отправить сообщение',\n upload_failed: 'Не удалось загрузить: {error}',\n remove_attachment: 'Удалить вложение',\n json_no_items: 'Нет элементов',\n json_no_data: 'Нет данных',\n json_no_chart_data: 'Нет данных для диаграммы',\n json_unsupported: 'Не поддерживается: {type}',\n json_see_less: 'Показать меньше',\n json_phone_agent: 'Телефонный агент',\n json_phone_agent_test: 'Проверить через веб',\n page_context_remove: 'Убрать контекст страницы',\n json_see_more: 'Показать ещё {count}',\n queued_label: '{count} В очереди',\n remove_queued_message: 'Удалить сообщение из очереди',\n send_queued_now: 'Отправить сообщения из очереди сейчас',\n turn_failed_message: 'Что-то пошло не так, и ответ не пришёл.',\n turn_failed_retry: 'Повторить попытку',\n page_mark_hint: 'Нажмите на элемент, чтобы отметить его',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Рамка',\n page_mark_shape_circle: 'Круг',\n page_mark_shape_arrow: 'Стрелка',\n page_mark_shape_bracket: 'Скобка',\n page_mark_shape_underline: 'Подчёркивание',\n page_mark_shape_highlight: 'Выделение',\n page_mark_shape_strike_through: 'Зачёркивание',\n page_mark_shape_crossed_off: 'Перечёркивание крестом',\n page_mark_shape_aria: 'Форма отметки: {shape}',\n page_mark_note_placeholder: 'Добавить заметку… (Enter, чтобы прикрепить)',\n page_mark_attach: 'Прикрепить отметку',\n page_mark_remove: 'Удалить {label}',\n page_mark_region: 'Отмеченная область',\n page_mark_default_message: 'Что это?',\n file_rejected: 'Тип файла не поддерживается или файл слишком большой.',\n dictate: 'Диктовать',\n stop_dictation: 'Остановить диктовку',\n dictation_mic_blocked: 'Разрешите доступ к микрофону, чтобы диктовать',\n dictation_unavailable: 'Диктовка сейчас недоступна',\n questions_back: 'Назад',\n questions_next: 'Далее',\n questions_send: 'Отправить',\n questions_type_answer: 'Напишу сам',\n questions_answer_placeholder: 'Напишите ваш ответ…',\n close_conversation_title: 'Закрыть разговор',\n close_conversation_description:\n 'Вы уверены, что хотите закрыть этот разговор?',\n close_conversation_cancel: 'Нет',\n close_conversation_confirm: 'Да',\n dialog_close: 'Закрыть',\n zoom_in: 'Увеличить',\n zoom_out: 'Уменьшить',\n reset_zoom: 'Сбросить масштаб',\n support_chat_aria_label: 'Чат поддержки',\n};\n","import type { TranslationInterface } from '.';\n\nexport const ThaiLanguage: TranslationInterface = {\n write_a_message_placeholder: 'เขียนข้อความ...',\n your_issue_has_been_resolved: 'ปัญหาของคุณได้รับการแก้ไขแล้ว!',\n new_conversation: 'การสนทนาใหม่',\n welcome_screen_title: 'ยินดีต้อนรับสู่แชทสนับสนุนของเรา',\n welcome_screen_description:\n 'เราพร้อมช่วยเหลือคุณ! เริ่มการสนทนาและเราจะติดต่อกลับโดยเร็วที่สุด',\n your_name_placeholder: 'ชื่อของคุณ',\n your_email_placeholder: 'ที่อยู่อีเมลของคุณ',\n start_chat_button: 'พูดคุยกับฝ่ายสนับสนุน',\n start_chat_button_loading: 'กำลังเชื่อมต่อ...',\n i_need_more_help: 'ฉันต้องการความช่วยเหลือเพิ่มเติม',\n this_was_helpful: 'สิ่งนี้เป็นประโยชน์',\n optional: 'ไม่บังคับ',\n no_conversations_yet: 'ยังไม่มีการสนทนา',\n back_to_conversations: 'กลับไปที่การสนทนา',\n closed_conversations: 'การสนทนาที่ปิดแล้ว',\n csat_title: 'การสนทนาของคุณเป็นอย่างไรบ้าง?',\n csat_submitted_title: 'คุณให้คะแนนการสนทนาว่า',\n csat_feedback_placeholder: 'บอกเราเพิ่มเติม... (ไม่บังคับ)',\n follow_up_placeholder: 'ถามต่อ…',\n companion_layout_label: 'เค้าโครง',\n companion_layout_floating: 'แบบลอย',\n companion_layout_sidebar: 'แถบด้านข้าง',\n companion_layout_fullscreen: 'เต็มหน้าจอ',\n companion_close: 'ปิด',\n companion_history: 'ประวัติการสนทนา',\n companion_expand_chat: 'ขยายแชต',\n companion_sidebar_dock_label: 'เชื่อมต่อ',\n companion_sidebar_side_label: 'ด้าน',\n companion_sidebar_left: 'ซ้าย',\n companion_sidebar_right: 'ขวา',\n companion_resize_chat: 'ปรับขนาดแชต',\n scroll_to_bottom: 'เลื่อนไปด้านล่าง',\n thinking: 'กำลังคิด…',\n running: 'กำลังทำงาน…',\n steps: 'ขั้นตอน',\n step_arguments: 'อาร์กิวเมนต์',\n step_result: 'ผลลัพธ์',\n attach_files: 'แนบรูปภาพ วิดีโอ PDF หรือสเปรดชีต (ขนาดสูงสุด 25 MB)',\n mark_page_active:\n 'คลิกสิ่งใดก็ได้บนหน้าเพื่อทำเครื่องหมาย — กด Esc เพื่อยกเลิก',\n mark_page: 'ทำเครื่องหมายสิ่งที่อยู่บนหน้าเพื่อถามเกี่ยวกับสิ่งนั้น',\n stop_response: 'หยุดการตอบ',\n copy_reply: 'คัดลอกคำตอบ',\n mentions_empty: 'ไม่พบรายการ',\n copied: 'คัดลอกแล้ว',\n send_message: 'ส่งข้อความ',\n upload_failed: 'อัปโหลดไม่สำเร็จ: {error}',\n remove_attachment: 'ลบไฟล์แนบ',\n json_no_items: 'ไม่มีรายการ',\n json_no_data: 'ไม่มีข้อมูล',\n json_no_chart_data: 'ไม่มีข้อมูลสำหรับแผนภูมิ',\n json_unsupported: 'ไม่รองรับ: {type}',\n json_see_less: 'ดูน้อยลง',\n json_phone_agent: 'เอเจนต์โทรศัพท์',\n json_phone_agent_test: 'ทดสอบผ่านเว็บ',\n page_context_remove: 'ลบบริบทของหน้า',\n json_see_more: 'ดูเพิ่มอีก {count} รายการ',\n queued_label: '{count} อยู่ในคิว',\n remove_queued_message: 'นำข้อความออกจากคิว',\n send_queued_now: 'ส่งข้อความในคิวตอนนี้',\n turn_failed_message: 'เกิดข้อผิดพลาดและไม่ได้รับคำตอบ',\n turn_failed_retry: 'ลองอีกครั้ง',\n page_mark_hint: 'คลิกสิ่งใดก็ได้เพื่อทำเครื่องหมาย',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'กรอบ',\n page_mark_shape_circle: 'วงกลม',\n page_mark_shape_arrow: 'ลูกศร',\n page_mark_shape_bracket: 'วงเล็บ',\n page_mark_shape_underline: 'ขีดเส้นใต้',\n page_mark_shape_highlight: 'ไฮไลต์',\n page_mark_shape_strike_through: 'ขีดฆ่า',\n page_mark_shape_crossed_off: 'กากบาท',\n page_mark_shape_aria: 'รูปร่างเครื่องหมาย: {shape}',\n page_mark_note_placeholder: 'เพิ่มหมายเหตุ… (กด Enter เพื่อแนบ)',\n page_mark_attach: 'แนบเครื่องหมาย',\n page_mark_remove: 'ลบ {label}',\n page_mark_region: 'บริเวณที่ทำเครื่องหมาย',\n page_mark_default_message: 'นี่คืออะไร',\n file_rejected: 'ไม่รองรับประเภทไฟล์หรือไฟล์มีขนาดใหญ่เกินไป',\n dictate: 'พูดเพื่อพิมพ์',\n stop_dictation: 'หยุดการพูดเพื่อพิมพ์',\n dictation_mic_blocked: 'อนุญาตการเข้าถึงไมโครโฟนเพื่อพูดเพื่อพิมพ์',\n dictation_unavailable: 'ไม่สามารถใช้การพูดเพื่อพิมพ์ได้ในขณะนี้',\n questions_back: 'ย้อนกลับ',\n questions_next: 'ถัดไป',\n questions_send: 'ส่ง',\n questions_type_answer: 'ขอพิมพ์เอง',\n questions_answer_placeholder: 'พิมพ์คำตอบของคุณ…',\n close_conversation_title: 'ปิดการสนทนา',\n close_conversation_description: 'คุณแน่ใจหรือไม่ว่าต้องการปิดการสนทนานี้?',\n close_conversation_cancel: 'ไม่',\n close_conversation_confirm: 'ใช่',\n dialog_close: 'ปิด',\n zoom_in: 'ขยาย',\n zoom_out: 'ย่อ',\n reset_zoom: 'รีเซ็ตการซูม',\n support_chat_aria_label: 'แชทฝ่ายสนับสนุน',\n};\n","import type { TranslationInterface } from '.';\n\nexport const TurkishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Bir mesaj yazın...',\n your_issue_has_been_resolved: 'Sorununuz çözüldü!',\n new_conversation: 'Yeni konuşma',\n welcome_screen_title: 'Destek sohbetimize hoş geldiniz',\n welcome_screen_description:\n 'Yardım etmek için buradayız! Bir konuşma başlatın, en kısa sürede size geri döneceğiz.',\n your_name_placeholder: 'Adınız',\n your_email_placeholder: 'E-posta adresiniz',\n start_chat_button: 'Destekle konuş',\n start_chat_button_loading: 'Bağlanıyor...',\n i_need_more_help: 'Daha fazla yardıma ihtiyacım var',\n this_was_helpful: 'Bu yardımcı oldu',\n optional: 'İsteğe bağlı',\n no_conversations_yet: 'Henüz konuşma yok',\n back_to_conversations: 'Konuşmalara geri dön',\n closed_conversations: 'Kapatılan konuşmalar',\n csat_title: 'Görüşmeniz nasıldı?',\n csat_submitted_title: 'Görüşmeyi şöyle değerlendirdiniz',\n csat_feedback_placeholder: 'Bize daha fazlasını anlatın... (isteğe bağlı)',\n follow_up_placeholder: 'Devam et…',\n companion_layout_label: 'Düzen',\n companion_layout_floating: 'Kayan',\n companion_layout_sidebar: 'Kenar çubuğu',\n companion_layout_fullscreen: 'Tam ekran',\n companion_close: 'Kapat',\n companion_history: 'Konuşma geçmişi',\n companion_expand_chat: 'Sohbeti genişlet',\n companion_sidebar_dock_label: 'Sabitleme',\n companion_sidebar_side_label: 'Taraf',\n companion_sidebar_left: 'Sol',\n companion_sidebar_right: 'Sağ',\n companion_resize_chat: 'Sohbeti yeniden boyutlandır',\n scroll_to_bottom: 'En alta kaydır',\n thinking: 'Düşünüyor…',\n running: 'Çalışıyor…',\n steps: 'adım',\n step_arguments: 'Bağımsız değişkenler',\n step_result: 'Sonuç',\n attach_files:\n 'Görsel, video, PDF veya elektronik tablo ekle (en fazla 25 MB)',\n mark_page_active:\n \"İşaretlemek için sayfadaki bir öğeye tıklayın — iptal etmek için Esc'ye basın\",\n mark_page: 'Hakkında soru sormak için sayfadaki bir öğeyi işaretleyin',\n stop_response: 'Yanıtı durdur',\n copy_reply: 'Yanıtı kopyala',\n mentions_empty: 'Eşleşme yok',\n copied: 'Kopyalandı',\n send_message: 'Mesaj gönder',\n upload_failed: 'Yükleme başarısız: {error}',\n remove_attachment: 'Eki kaldır',\n json_no_items: 'Öğe yok',\n json_no_data: 'Veri yok',\n json_no_chart_data: 'Grafik için veri yok',\n json_unsupported: 'Desteklenmiyor: {type}',\n json_see_less: 'Daha az göster',\n json_phone_agent: 'Telefon temsilcisi',\n json_phone_agent_test: 'Web üzerinden test et',\n page_context_remove: 'Sayfa bağlamını kaldır',\n json_see_more: '{count} tane daha göster',\n queued_label: '{count} Sırada',\n remove_queued_message: 'Mesajı sıradan kaldır',\n send_queued_now: 'Sıradaki mesajları şimdi gönder',\n turn_failed_message: 'Bir sorun oluştu ve yanıt ulaşmadı.',\n turn_failed_retry: 'Tekrar dene',\n page_mark_hint: 'İşaretlemek için bir öğeye tıklayın',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kutu',\n page_mark_shape_circle: 'Daire',\n page_mark_shape_arrow: 'Ok',\n page_mark_shape_bracket: 'Ayraç',\n page_mark_shape_underline: 'Alt çizgi',\n page_mark_shape_highlight: 'Vurgu',\n page_mark_shape_strike_through: 'Üstü çizili',\n page_mark_shape_crossed_off: 'Çarpı at',\n page_mark_shape_aria: 'İşaret şekli: {shape}',\n page_mark_note_placeholder: \"Not ekleyin… (Eklemek için Enter'a basın)\",\n page_mark_attach: 'İşareti ekle',\n page_mark_remove: '{label} öğesini kaldır',\n page_mark_region: 'İşaretli bölge',\n page_mark_default_message: 'Bu nedir?',\n file_rejected: 'Dosya türü desteklenmiyor veya dosya çok büyük.',\n dictate: 'Dikte et',\n stop_dictation: 'Dikteyi durdur',\n dictation_mic_blocked: 'Dikte etmek için mikrofon erişimine izin verin',\n dictation_unavailable: 'Dikte şu anda kullanılamıyor',\n questions_back: 'Geri',\n questions_next: 'İleri',\n questions_send: 'Gönder',\n questions_type_answer: 'Kendim yazayım',\n questions_answer_placeholder: 'Yanıtınızı yazın…',\n close_conversation_title: 'Görüşmeyi kapat',\n close_conversation_description:\n 'Bu görüşmeyi kapatmak istediğinizden emin misiniz?',\n close_conversation_cancel: 'Hayır',\n close_conversation_confirm: 'Evet',\n dialog_close: 'Kapat',\n zoom_in: 'Yakınlaştır',\n zoom_out: 'Uzaklaştır',\n reset_zoom: 'Yakınlaştırmayı sıfırla',\n support_chat_aria_label: 'Destek sohbeti',\n};\n","import type { TranslationInterface } from '.';\n\nexport const UrduLanguage: TranslationInterface = {\n write_a_message_placeholder: 'پیغام لکھیں...',\n your_issue_has_been_resolved: 'آپ کا مسئلہ حل ہو گیا ہے!',\n new_conversation: 'نئی گفتگو',\n welcome_screen_title: 'ہماری سپورٹ چیٹ میں خوش آمدید',\n welcome_screen_description:\n 'ہم مدد کے لیے حاضر ہیں! گفتگو شروع کریں اور ہم جلد از جلد آپ سے رابطہ کریں گے۔',\n your_name_placeholder: 'آپ کا نام',\n your_email_placeholder: 'آپ کا ای میل پتہ',\n start_chat_button: 'سپورٹ سے بات کریں',\n start_chat_button_loading: 'جڑ رہا ہے...',\n i_need_more_help: 'مجھے مزید مدد چاہیے',\n this_was_helpful: 'یہ مددگار تھا',\n optional: 'اختیاری',\n no_conversations_yet: 'ابھی تک کوئی گفتگو نہیں',\n back_to_conversations: 'گفتگو پر واپس جائیں',\n closed_conversations: 'بند گفتگو',\n csat_title: 'آپ کی گفتگو کیسی رہی؟',\n csat_submitted_title: 'آپ نے گفتگو کو درجہ دیا',\n csat_feedback_placeholder: 'ہمیں مزید بتائیں... (اختیاری)',\n follow_up_placeholder: 'مزید پوچھیں…',\n companion_layout_label: 'لے آؤٹ',\n companion_layout_floating: 'فلوٹنگ',\n companion_layout_sidebar: 'سائیڈ بار',\n companion_layout_fullscreen: 'مکمل اسکرین',\n companion_close: 'بند کریں',\n companion_history: 'گفتگو کی سرگزشت',\n companion_expand_chat: 'چیٹ پھیلائیں',\n companion_sidebar_dock_label: 'ڈاک',\n companion_sidebar_side_label: 'طرف',\n companion_sidebar_left: 'بائیں',\n companion_sidebar_right: 'دائیں',\n companion_resize_chat: 'چیٹ کا سائز تبدیل کریں',\n scroll_to_bottom: 'نیچے تک اسکرول کریں',\n thinking: 'سوچ رہا ہے…',\n running: 'جاری ہے…',\n steps: 'مراحل',\n step_arguments: 'آرگیومنٹس',\n step_result: 'نتیجہ',\n attach_files:\n 'تصاویر، ویڈیوز، PDF یا اسپریڈشیٹس منسلک کریں (زیادہ سے زیادہ حجم 25 MB)',\n mark_page_active:\n 'نشان لگانے کے لیے صفحے پر کسی چیز پر کلک کریں — منسوخ کرنے کے لیے Esc دبائیں',\n mark_page: 'صفحے پر کسی چیز کے بارے میں پوچھنے کے لیے اس پر نشان لگائیں',\n stop_response: 'جواب روکیں',\n copy_reply: 'جواب کاپی کریں',\n mentions_empty: 'کوئی مماثلت نہیں',\n copied: 'کاپی ہو گیا',\n send_message: 'پیغام بھیجیں',\n upload_failed: 'اپ لوڈ ناکام: {error}',\n remove_attachment: 'منسلکہ ہٹائیں',\n json_no_items: 'کوئی آئٹم نہیں',\n json_no_data: 'کوئی ڈیٹا نہیں',\n json_no_chart_data: 'چارٹ کے لیے کوئی ڈیٹا نہیں',\n json_unsupported: 'تعاون یافتہ نہیں: {type}',\n json_see_less: 'کم دیکھیں',\n json_phone_agent: 'فون ایجنٹ',\n json_phone_agent_test: 'ویب کے ذریعے آزمائیں',\n page_context_remove: 'صفحے کا سیاق ہٹائیں',\n json_see_more: 'مزید {count} دیکھیں',\n queued_label: '{count} قطار میں',\n remove_queued_message: 'پیغام کو قطار سے ہٹائیں',\n send_queued_now: 'قطار میں موجود پیغامات ابھی بھیجیں',\n turn_failed_message: 'کچھ غلط ہو گیا اور جواب موصول نہیں ہوا۔',\n turn_failed_retry: 'دوبارہ کوشش کریں',\n page_mark_hint: 'نشان لگانے کے لیے کسی چیز پر کلک کریں',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'خانہ',\n page_mark_shape_circle: 'دائرہ',\n page_mark_shape_arrow: 'تیر',\n page_mark_shape_bracket: 'قوس',\n page_mark_shape_underline: 'خط کشیدہ',\n page_mark_shape_highlight: 'نمایاں',\n page_mark_shape_strike_through: 'کاٹنے کی لکیر',\n page_mark_shape_crossed_off: 'ضرب کا نشان',\n page_mark_shape_aria: 'نشان کی شکل: {shape}',\n page_mark_note_placeholder: 'نوٹ شامل کریں… (منسلک کرنے کے لیے Enter دبائیں)',\n page_mark_attach: 'نشان منسلک کریں',\n page_mark_remove: '{label} ہٹائیں',\n page_mark_region: 'نشان زدہ علاقہ',\n page_mark_default_message: 'یہ کیا ہے؟',\n file_rejected: 'فائل کی قسم تعاون یافتہ نہیں ہے یا فائل بہت بڑی ہے۔',\n dictate: 'بول کر لکھیں',\n stop_dictation: 'ڈکٹیشن روکیں',\n dictation_mic_blocked: 'بول کر لکھنے کے لیے مائیکروفون تک رسائی کی اجازت دیں',\n dictation_unavailable: 'ڈکٹیشن اس وقت دستیاب نہیں ہے',\n questions_back: 'واپس',\n questions_next: 'اگلا',\n questions_send: 'بھیجیں',\n questions_type_answer: 'میں خود لکھوں گا',\n questions_answer_placeholder: 'اپنا جواب لکھیں…',\n close_conversation_title: 'گفتگو بند کریں',\n close_conversation_description: 'کیا آپ واقعی یہ گفتگو بند کرنا چاہتے ہیں؟',\n close_conversation_cancel: 'نہیں',\n close_conversation_confirm: 'ہاں',\n dialog_close: 'بند کریں',\n zoom_in: 'زوم اِن',\n zoom_out: 'زوم آؤٹ',\n reset_zoom: 'زوم دوبارہ ترتیب دیں',\n support_chat_aria_label: 'سپورٹ چیٹ',\n};\n","import type { TranslationInterface } from '.';\n\nexport const VietnameseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Viết tin nhắn...',\n your_issue_has_been_resolved: 'Vấn đề của bạn đã được giải quyết!',\n new_conversation: 'Cuộc trò chuyện mới',\n welcome_screen_title: 'Chào mừng đến với hỗ trợ trò chuyện của chúng tôi',\n welcome_screen_description:\n 'Chúng tôi ở đây để giúp đỡ! Bắt đầu cuộc trò chuyện và chúng tôi sẽ phản hồi sớm nhất có thể.',\n your_name_placeholder: 'Tên của bạn',\n your_email_placeholder: 'Địa chỉ email của bạn',\n start_chat_button: 'Liên hệ hỗ trợ',\n start_chat_button_loading: 'Đang kết nối...',\n i_need_more_help: 'Tôi cần thêm trợ giúp',\n this_was_helpful: 'Điều này hữu ích',\n optional: 'Tùy chọn',\n no_conversations_yet: 'Chưa có cuộc trò chuyện nào',\n back_to_conversations: 'Quay lại cuộc trò chuyện',\n closed_conversations: 'Cuộc trò chuyện đã đóng',\n csat_title: 'Cuộc trò chuyện của bạn thế nào?',\n csat_submitted_title: 'Bạn đã đánh giá cuộc trò chuyện là',\n csat_feedback_placeholder: 'Cho chúng tôi biết thêm... (tùy chọn)',\n follow_up_placeholder: 'Hỏi thêm…',\n companion_layout_label: 'Bố cục',\n companion_layout_floating: 'Nổi',\n companion_layout_sidebar: 'Thanh bên',\n companion_layout_fullscreen: 'Toàn màn hình',\n companion_close: 'Đóng',\n companion_history: 'Lịch sử trò chuyện',\n companion_expand_chat: 'Mở rộng cuộc trò chuyện',\n companion_sidebar_dock_label: 'Ghim',\n companion_sidebar_side_label: 'Phía',\n companion_sidebar_left: 'Trái',\n companion_sidebar_right: 'Phải',\n companion_resize_chat: 'Đổi kích thước cuộc trò chuyện',\n scroll_to_bottom: 'Cuộn xuống dưới cùng',\n thinking: 'Đang suy nghĩ…',\n running: 'Đang chạy…',\n steps: 'bước',\n step_arguments: 'Đối số',\n step_result: 'Kết quả',\n attach_files:\n 'Đính kèm hình ảnh, video, PDF hoặc bảng tính (kích thước tối đa 25 MB)',\n mark_page_active:\n 'Nhấp vào bất kỳ nội dung nào trên trang để đánh dấu — nhấn Esc để hủy',\n mark_page: 'Đánh dấu nội dung trên trang để hỏi về nội dung đó',\n stop_response: 'Dừng trả lời',\n copy_reply: 'Sao chép câu trả lời',\n mentions_empty: 'Không có kết quả',\n copied: 'Đã sao chép',\n send_message: 'Gửi tin nhắn',\n upload_failed: 'Tải lên không thành công: {error}',\n remove_attachment: 'Xóa tệp đính kèm',\n json_no_items: 'Không có mục nào',\n json_no_data: 'Không có dữ liệu',\n json_no_chart_data: 'Không có dữ liệu cho biểu đồ',\n json_unsupported: 'Không được hỗ trợ: {type}',\n json_see_less: 'Hiện ít hơn',\n json_phone_agent: 'Tổng đài viên',\n json_phone_agent_test: 'Thử qua web',\n page_context_remove: 'Xóa ngữ cảnh trang',\n json_see_more: 'Hiện thêm {count}',\n queued_label: '{count} Đang chờ',\n remove_queued_message: 'Xóa tin nhắn khỏi hàng đợi',\n send_queued_now: 'Gửi tin nhắn trong hàng đợi ngay',\n turn_failed_message: 'Đã xảy ra lỗi và không nhận được câu trả lời.',\n turn_failed_retry: 'Thử lại',\n page_mark_hint: 'Nhấp vào nội dung bất kỳ để đánh dấu',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Khung',\n page_mark_shape_circle: 'Hình tròn',\n page_mark_shape_arrow: 'Mũi tên',\n page_mark_shape_bracket: 'Ngoặc',\n page_mark_shape_underline: 'Gạch chân',\n page_mark_shape_highlight: 'Tô sáng',\n page_mark_shape_strike_through: 'Gạch ngang',\n page_mark_shape_crossed_off: 'Gạch chéo',\n page_mark_shape_aria: 'Hình dạng dấu: {shape}',\n page_mark_note_placeholder: 'Thêm ghi chú… (Enter để đính kèm)',\n page_mark_attach: 'Đính kèm dấu',\n page_mark_remove: 'Xóa {label}',\n page_mark_region: 'Vùng đã đánh dấu',\n page_mark_default_message: 'Đây là gì?',\n file_rejected: 'Loại tệp không được hỗ trợ hoặc tệp quá lớn.',\n dictate: 'Đọc để nhập',\n stop_dictation: 'Dừng đọc',\n dictation_mic_blocked: 'Cho phép truy cập micrô để đọc nhập',\n dictation_unavailable: 'Hiện không thể dùng tính năng đọc để nhập',\n questions_back: 'Quay lại',\n questions_next: 'Tiếp theo',\n questions_send: 'Gửi',\n questions_type_answer: 'Tôi sẽ tự nhập',\n questions_answer_placeholder: 'Nhập câu trả lời của bạn…',\n close_conversation_title: 'Đóng cuộc trò chuyện',\n close_conversation_description:\n 'Bạn có chắc muốn đóng cuộc trò chuyện này không?',\n close_conversation_cancel: 'Không',\n close_conversation_confirm: 'Có',\n dialog_close: 'Đóng',\n zoom_in: 'Phóng to',\n zoom_out: 'Thu nhỏ',\n reset_zoom: 'Đặt lại thu phóng',\n support_chat_aria_label: 'Trò chuyện hỗ trợ',\n};\n","import type { TranslationInterface } from '.';\n\nexport const ChineseSimplifiedLanguage: TranslationInterface = {\n write_a_message_placeholder: '写一条消息...',\n your_issue_has_been_resolved: '您的问题已解决!',\n new_conversation: '新对话',\n welcome_screen_title: '欢迎使用我们的客服聊天',\n welcome_screen_description:\n '我们随时为您提供帮助!开始对话,我们会尽快回复您。',\n your_name_placeholder: '您的姓名',\n your_email_placeholder: '您的电子邮件地址',\n start_chat_button: '联系客服',\n start_chat_button_loading: '连接中...',\n i_need_more_help: '我需要更多帮助',\n this_was_helpful: '这很有帮助',\n optional: '可选',\n no_conversations_yet: '暂无对话',\n back_to_conversations: '返回对话',\n closed_conversations: '已关闭的对话',\n csat_title: '您的对话感觉如何?',\n csat_submitted_title: '您将此对话评价为',\n csat_feedback_placeholder: '告诉我们更多...(可选)',\n follow_up_placeholder: '继续提问…',\n companion_layout_label: '布局',\n companion_layout_floating: '浮动',\n companion_layout_sidebar: '侧边栏',\n companion_layout_fullscreen: '全屏',\n companion_close: '关闭',\n companion_history: '对话历史',\n companion_expand_chat: '展开聊天',\n companion_sidebar_dock_label: '停靠',\n companion_sidebar_side_label: '位置',\n companion_sidebar_left: '左侧',\n companion_sidebar_right: '右侧',\n companion_resize_chat: '调整聊天大小',\n scroll_to_bottom: '滚动到底部',\n thinking: '思考中…',\n running: '运行中…',\n steps: '步骤',\n step_arguments: '参数',\n step_result: '结果',\n attach_files: '附加图片、视频、PDF 或电子表格(最大 25 MB)',\n mark_page_active: '点击页面上的任意内容进行标记 — 按 Esc 取消',\n mark_page: '标记页面上的内容以便就此提问',\n stop_response: '停止回答',\n copy_reply: '复制回复',\n mentions_empty: '没有匹配项',\n copied: '已复制',\n send_message: '发送消息',\n upload_failed: '上传失败:{error}',\n remove_attachment: '移除附件',\n json_no_items: '没有项目',\n json_no_data: '没有数据',\n json_no_chart_data: '没有可用于图表的数据',\n json_unsupported: '不支持:{type}',\n json_see_less: '收起',\n json_phone_agent: '电话客服',\n json_phone_agent_test: '通过网页测试',\n page_context_remove: '移除页面上下文',\n json_see_more: '再显示 {count} 项',\n queued_label: '{count} 排队中',\n remove_queued_message: '从队列中移除消息',\n send_queued_now: '立即发送队列中的消息',\n turn_failed_message: '出现问题,未收到回答。',\n turn_failed_retry: '重试',\n page_mark_hint: '点击任意内容进行标记',\n page_mark_escape: 'Esc',\n page_mark_shape_box: '方框',\n page_mark_shape_circle: '圆形',\n page_mark_shape_arrow: '箭头',\n page_mark_shape_bracket: '括号',\n page_mark_shape_underline: '下划线',\n page_mark_shape_highlight: '高亮',\n page_mark_shape_strike_through: '删除线',\n page_mark_shape_crossed_off: '叉号',\n page_mark_shape_aria: '标记形状:{shape}',\n page_mark_note_placeholder: '添加备注…(按 Enter 附加)',\n page_mark_attach: '附加标记',\n page_mark_remove: '移除{label}',\n page_mark_region: '已标记区域',\n page_mark_default_message: '这是什么?',\n file_rejected: '不支持该文件类型,或文件过大。',\n dictate: '语音输入',\n stop_dictation: '停止语音输入',\n dictation_mic_blocked: '请允许访问麦克风以使用语音输入',\n dictation_unavailable: '语音输入暂时不可用',\n questions_back: '返回',\n questions_next: '下一步',\n questions_send: '发送',\n questions_type_answer: '我自己输入',\n questions_answer_placeholder: '输入你的回答…',\n close_conversation_title: '结束对话',\n close_conversation_description: '确定要结束此对话吗?',\n close_conversation_cancel: '否',\n close_conversation_confirm: '是',\n dialog_close: '关闭',\n zoom_in: '放大',\n zoom_out: '缩小',\n reset_zoom: '重置缩放',\n support_chat_aria_label: '支持对话',\n};\n","import type { TranslationInterface } from '.';\n\nexport const CroatianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napišite poruku...',\n your_issue_has_been_resolved: 'Vaš problem je riješen!',\n new_conversation: 'Novi razgovor',\n welcome_screen_title: 'Dobrodošli u naš chat za podršku',\n welcome_screen_description:\n 'Ovdje smo da pomognemo! Započnite razgovor i odgovorit ćemo vam što je prije moguće.',\n your_name_placeholder: 'Vaše ime',\n your_email_placeholder: 'Vaša e-mail adresa',\n start_chat_button: 'Razgovarajte s podrškom',\n start_chat_button_loading: 'Povezivanje...',\n i_need_more_help: 'Trebam dodatnu pomoć',\n this_was_helpful: 'Ovo je bilo korisno',\n optional: 'Neobavezno',\n no_conversations_yet: 'Još nema razgovora',\n back_to_conversations: 'Natrag na razgovore',\n closed_conversations: 'Zatvoreni razgovori',\n csat_title: 'Kakav je bio vaš razgovor?',\n csat_submitted_title: 'Ocijenili ste razgovor kao',\n csat_feedback_placeholder: 'Recite nam više... (neobavezno)',\n follow_up_placeholder: 'Nastavite…',\n companion_layout_label: 'Raspored',\n companion_layout_floating: 'Plutajući',\n companion_layout_sidebar: 'Bočna traka',\n companion_layout_fullscreen: 'Cijeli zaslon',\n companion_close: 'Zatvori',\n companion_history: 'Povijest razgovora',\n companion_expand_chat: 'Proširi razgovor',\n companion_sidebar_dock_label: 'Usidravanje',\n companion_sidebar_side_label: 'Strana',\n companion_sidebar_left: 'Lijevo',\n companion_sidebar_right: 'Desno',\n companion_resize_chat: 'Promijeni veličinu razgovora',\n scroll_to_bottom: 'Pomakni se na dno',\n thinking: 'Razmišljam…',\n running: 'Izvršava se…',\n steps: 'koraci',\n step_arguments: 'Argumenti',\n step_result: 'Rezultat',\n attach_files:\n 'Priložite slike, videozapise, PDF-ove ili proračunske tablice (najveća veličina 25 MB)',\n mark_page_active:\n 'Kliknite bilo što na stranici da biste to označili — Esc za odustajanje',\n mark_page: 'Označite nešto na stranici da biste pitali o tome',\n stop_response: 'Zaustavi odgovor',\n copy_reply: 'Kopiraj odgovor',\n mentions_empty: 'Nema rezultata',\n copied: 'Kopirano',\n send_message: 'Pošalji poruku',\n upload_failed: 'Prijenos nije uspio: {error}',\n remove_attachment: 'Ukloni privitak',\n json_no_items: 'Nema stavki',\n json_no_data: 'Nema podataka',\n json_no_chart_data: 'Nema podataka za grafikon',\n json_unsupported: 'Nije podržano: {type}',\n json_see_less: 'Prikaži manje',\n json_phone_agent: 'Telefonski agent',\n json_phone_agent_test: 'Testiraj putem weba',\n page_context_remove: 'Ukloni kontekst stranice',\n json_see_more: 'Prikaži još {count}',\n queued_label: '{count} Na čekanju',\n remove_queued_message: 'Ukloni poruku iz reda čekanja',\n send_queued_now: 'Pošalji poruke iz reda čekanja sada',\n turn_failed_message: 'Nešto je pošlo po zlu i odgovor nije stigao.',\n turn_failed_retry: 'Pokušaj ponovno',\n page_mark_hint: 'Kliknite nešto da biste to označili',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Okvir',\n page_mark_shape_circle: 'Krug',\n page_mark_shape_arrow: 'Strelica',\n page_mark_shape_bracket: 'Zagrada',\n page_mark_shape_underline: 'Podcrtavanje',\n page_mark_shape_highlight: 'Isticanje',\n page_mark_shape_strike_through: 'Precrtavanje',\n page_mark_shape_crossed_off: 'Križno precrtavanje',\n page_mark_shape_aria: 'Oblik oznake: {shape}',\n page_mark_note_placeholder: 'Dodajte bilješku… (Enter za prilaganje)',\n page_mark_attach: 'Priloži oznaku',\n page_mark_remove: 'Ukloni {label}',\n page_mark_region: 'Označeno područje',\n page_mark_default_message: 'Što je ovo?',\n file_rejected: 'Vrsta datoteke nije podržana ili je datoteka prevelika.',\n dictate: 'Diktiraj',\n stop_dictation: 'Zaustavi diktiranje',\n dictation_mic_blocked: 'Dopustite pristup mikrofonu za diktiranje',\n dictation_unavailable: 'Diktiranje trenutačno nije dostupno',\n questions_back: 'Natrag',\n questions_next: 'Dalje',\n questions_send: 'Pošalji',\n questions_type_answer: 'Napisat ću sam',\n questions_answer_placeholder: 'Napišite svoj odgovor…',\n close_conversation_title: 'Zatvori razgovor',\n close_conversation_description:\n 'Jeste li sigurni da želite zatvoriti ovaj razgovor?',\n close_conversation_cancel: 'Ne',\n close_conversation_confirm: 'Da',\n dialog_close: 'Zatvori',\n zoom_in: 'Približi',\n zoom_out: 'Udalji',\n reset_zoom: 'Poništi zumiranje',\n support_chat_aria_label: 'Chat za podršku',\n};\n","import type { TranslationInterface } from '.';\n\nexport const EstonianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Kirjuta sõnum...',\n your_issue_has_been_resolved: 'Teie probleem on lahendatud!',\n new_conversation: 'Uus vestlus',\n welcome_screen_title: 'Tere tulemast meie tugiteenusesse',\n welcome_screen_description:\n 'Oleme siin, et aidata! Alustage vestlust ja vastame teile esimesel võimalusel.',\n your_name_placeholder: 'Teie nimi',\n your_email_placeholder: 'Teie e-posti aadress',\n start_chat_button: 'Räägi toega',\n start_chat_button_loading: 'Ühendamine...',\n i_need_more_help: 'Vajan rohkem abi',\n this_was_helpful: 'See oli kasulik',\n optional: 'Valikuline',\n no_conversations_yet: 'Vestlusi pole veel',\n back_to_conversations: 'Tagasi vestluste juurde',\n closed_conversations: 'Suletud vestlused',\n csat_title: 'Milline oli teie vestlus?',\n csat_submitted_title: 'Hindasite vestlust kui',\n csat_feedback_placeholder: 'Rääkige meile rohkem... (valikuline)',\n follow_up_placeholder: 'Küsi juurde…',\n companion_layout_label: 'Paigutus',\n companion_layout_floating: 'Hõljuv',\n companion_layout_sidebar: 'Külgriba',\n companion_layout_fullscreen: 'Täisekraan',\n companion_close: 'Sulge',\n companion_history: 'Vestluste ajalugu',\n companion_expand_chat: 'Laienda vestlust',\n companion_sidebar_dock_label: 'Dokk',\n companion_sidebar_side_label: 'Külg',\n companion_sidebar_left: 'Vasak',\n companion_sidebar_right: 'Parem',\n companion_resize_chat: 'Muuda vestluse suurust',\n scroll_to_bottom: 'Keri alla',\n thinking: 'Mõtlen…',\n running: 'Töötab…',\n steps: 'sammud',\n step_arguments: 'Argumendid',\n step_result: 'Tulemus',\n attach_files:\n 'Lisa pilte, videoid, PDF-e või arvutustabeleid (maksimaalne suurus 25 MB)',\n mark_page_active:\n 'Märkimiseks klõpsa lehel ükskõik millel — tühistamiseks vajuta Esc',\n mark_page: 'Märgi lehel midagi, et selle kohta küsida',\n stop_response: 'Peata vastus',\n copy_reply: 'Kopeeri vastus',\n mentions_empty: 'Vasteid pole',\n copied: 'Kopeeritud',\n send_message: 'Saada sõnum',\n upload_failed: 'Üleslaadimine nurjus: {error}',\n remove_attachment: 'Eemalda manus',\n json_no_items: 'Üksusi pole',\n json_no_data: 'Andmeid pole',\n json_no_chart_data: 'Diagrammi jaoks pole andmeid',\n json_unsupported: 'Pole toetatud: {type}',\n json_see_less: 'Näita vähem',\n json_phone_agent: 'Telefoniagent',\n json_phone_agent_test: 'Testi veebis',\n page_context_remove: 'Eemalda lehe kontekst',\n json_see_more: 'Näita veel {count}',\n queued_label: '{count} Järjekorras',\n remove_queued_message: 'Eemalda sõnum järjekorrast',\n send_queued_now: 'Saada järjekorras olevad sõnumid kohe',\n turn_failed_message: 'Midagi läks valesti ja vastus ei saabunud.',\n turn_failed_retry: 'Proovi uuesti',\n page_mark_hint: 'Märkimiseks klõpsa millelgi',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kast',\n page_mark_shape_circle: 'Ring',\n page_mark_shape_arrow: 'Nool',\n page_mark_shape_bracket: 'Sulg',\n page_mark_shape_underline: 'Allajoonimine',\n page_mark_shape_highlight: 'Esiletõst',\n page_mark_shape_strike_through: 'Läbikriipsutus',\n page_mark_shape_crossed_off: 'Ristiga maha tõmbamine',\n page_mark_shape_aria: 'Märke kuju: {shape}',\n page_mark_note_placeholder: 'Lisa märkus… (Enter lisamiseks)',\n page_mark_attach: 'Lisa märge',\n page_mark_remove: 'Eemalda {label}',\n page_mark_region: 'Märgitud ala',\n page_mark_default_message: 'Mis see on?',\n file_rejected: 'Failitüüpi ei toetata või fail on liiga suur.',\n dictate: 'Dikteeri',\n stop_dictation: 'Lõpeta dikteerimine',\n dictation_mic_blocked: 'Dikteerimiseks luba mikrofoni kasutamine',\n dictation_unavailable: 'Dikteerimine pole praegu saadaval',\n questions_back: 'Tagasi',\n questions_next: 'Edasi',\n questions_send: 'Saada',\n questions_type_answer: 'Kirjutan ise',\n questions_answer_placeholder: 'Kirjutage oma vastus…',\n close_conversation_title: 'Sulge vestlus',\n close_conversation_description:\n 'Kas soovite kindlasti selle vestluse sulgeda?',\n close_conversation_cancel: 'Ei',\n close_conversation_confirm: 'Jah',\n dialog_close: 'Sulge',\n zoom_in: 'Suurenda',\n zoom_out: 'Vähenda',\n reset_zoom: 'Lähtesta suurendus',\n support_chat_aria_label: 'Tugivestlus',\n};\n","import type { TranslationInterface } from '.';\n\nexport const HungarianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Írjon üzenetet...',\n your_issue_has_been_resolved: 'A problémája megoldódott!',\n new_conversation: 'Új beszélgetés',\n welcome_screen_title: 'Üdvözöljük az ügyfélszolgálati chatünkön',\n welcome_screen_description:\n 'Azért vagyunk itt, hogy segítsünk! Kezdjen beszélgetést, és mihamarabb válaszolunk.',\n your_name_placeholder: 'Az Ön neve',\n your_email_placeholder: 'Az Ön e-mail címe',\n start_chat_button: 'Beszélgetés az ügyfélszolgálattal',\n start_chat_button_loading: 'Csatlakozás...',\n i_need_more_help: 'További segítségre van szükségem',\n this_was_helpful: 'Ez hasznos volt',\n optional: 'Opcionális',\n no_conversations_yet: 'Még nincsenek beszélgetések',\n back_to_conversations: 'Vissza a beszélgetésekhez',\n closed_conversations: 'Lezárt beszélgetések',\n csat_title: 'Milyen volt a beszélgetése?',\n csat_submitted_title: 'A beszélgetést így értékelte',\n csat_feedback_placeholder: 'Mondjon többet... (opcionális)',\n follow_up_placeholder: 'További kérdés…',\n companion_layout_label: 'Elrendezés',\n companion_layout_floating: 'Lebegő',\n companion_layout_sidebar: 'Oldalsáv',\n companion_layout_fullscreen: 'Teljes képernyő',\n companion_close: 'Bezárás',\n companion_history: 'Beszélgetési előzmények',\n companion_expand_chat: 'Csevegés kibontása',\n companion_sidebar_dock_label: 'Dokkolás',\n companion_sidebar_side_label: 'Oldal',\n companion_sidebar_left: 'Bal',\n companion_sidebar_right: 'Jobb',\n companion_resize_chat: 'Csevegés átméretezése',\n scroll_to_bottom: 'Görgetés az aljára',\n thinking: 'Gondolkodás…',\n running: 'Folyamatban…',\n steps: 'lépés',\n step_arguments: 'Argumentumok',\n step_result: 'Eredmény',\n attach_files:\n 'Képek, videók, PDF-ek vagy táblázatok csatolása (legfeljebb 25 MB)',\n mark_page_active:\n 'Kattintson valamire az oldalon a megjelöléséhez — Esc a megszakításhoz',\n mark_page: 'Jelöljön meg valamit az oldalon, hogy kérdezhessen róla',\n stop_response: 'Válasz leállítása',\n copy_reply: 'Válasz másolása',\n mentions_empty: 'Nincs találat',\n copied: 'Másolva',\n send_message: 'Üzenet küldése',\n upload_failed: 'A feltöltés sikertelen: {error}',\n remove_attachment: 'Melléklet eltávolítása',\n json_no_items: 'Nincsenek elemek',\n json_no_data: 'Nincs adat',\n json_no_chart_data: 'Nincs megjeleníthető diagramadat',\n json_unsupported: 'Nem támogatott: {type}',\n json_see_less: 'Kevesebb megjelenítése',\n json_phone_agent: 'Telefonos ügynök',\n json_phone_agent_test: 'Tesztelés weben',\n page_context_remove: 'Oldalkontextus eltávolítása',\n json_see_more: 'További {count} megjelenítése',\n queued_label: '{count} Várólistán',\n remove_queued_message: 'Üzenet eltávolítása a várólistáról',\n send_queued_now: 'Várólistán lévő üzenetek küldése most',\n turn_failed_message: 'Hiba történt, és a válasz nem érkezett meg.',\n turn_failed_retry: 'Próbálja újra',\n page_mark_hint: 'Kattintson valamire a megjelöléséhez',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Keret',\n page_mark_shape_circle: 'Kör',\n page_mark_shape_arrow: 'Nyíl',\n page_mark_shape_bracket: 'Zárójel',\n page_mark_shape_underline: 'Aláhúzás',\n page_mark_shape_highlight: 'Kiemelés',\n page_mark_shape_strike_through: 'Áthúzás',\n page_mark_shape_crossed_off: 'Keresztezett áthúzás',\n page_mark_shape_aria: 'Jelölés alakja: {shape}',\n page_mark_note_placeholder: 'Megjegyzés hozzáadása… (Enter a csatoláshoz)',\n page_mark_attach: 'Jelölés csatolása',\n page_mark_remove: '{label} eltávolítása',\n page_mark_region: 'Megjelölt terület',\n page_mark_default_message: 'Mi ez?',\n file_rejected: 'A fájltípus nem támogatott, vagy a fájl túl nagy.',\n dictate: 'Diktálás',\n stop_dictation: 'Diktálás leállítása',\n dictation_mic_blocked: 'A diktáláshoz engedélyezze a mikrofon használatát',\n dictation_unavailable: 'A diktálás jelenleg nem érhető el',\n questions_back: 'Vissza',\n questions_next: 'Tovább',\n questions_send: 'Küldés',\n questions_type_answer: 'Inkább leírom',\n questions_answer_placeholder: 'Írja le a válaszát…',\n close_conversation_title: 'Beszélgetés lezárása',\n close_conversation_description: 'Biztosan lezárja ezt a beszélgetést?',\n close_conversation_cancel: 'Nem',\n close_conversation_confirm: 'Igen',\n dialog_close: 'Bezárás',\n zoom_in: 'Nagyítás',\n zoom_out: 'Kicsinyítés',\n reset_zoom: 'Nagyítás visszaállítása',\n support_chat_aria_label: 'Ügyfélszolgálati chat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const IcelandicLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skrifaðu skilaboð...',\n your_issue_has_been_resolved: 'Málið þitt hefur verið leyst!',\n new_conversation: 'Nýtt samtal',\n welcome_screen_title: 'Velkomin í þjónustuverið okkar',\n welcome_screen_description:\n 'Við erum hér til að hjálpa! Byrjaðu samtal og við munum svara eins fljótt og auðið er.',\n your_name_placeholder: 'Nafnið þitt',\n your_email_placeholder: 'Netfangið þitt',\n start_chat_button: 'Tala við þjónustuver',\n start_chat_button_loading: 'Tengist...',\n i_need_more_help: 'Ég þarf meiri hjálp',\n this_was_helpful: 'Þetta var gagnlegt',\n optional: 'Valfrjálst',\n no_conversations_yet: 'Engin samtöl ennþá',\n back_to_conversations: 'Til baka í samtöl',\n closed_conversations: 'Lokuð samtöl',\n csat_title: 'Hvernig var samtalið þitt?',\n csat_submitted_title: 'Þú gafst samtalinu einkunnina',\n csat_feedback_placeholder: 'Segðu okkur meira... (valfrjálst)',\n follow_up_placeholder: 'Spyrja nánar…',\n companion_layout_label: 'Útlit',\n companion_layout_floating: 'Fljótandi',\n companion_layout_sidebar: 'Hliðarstika',\n companion_layout_fullscreen: 'Allur skjárinn',\n companion_close: 'Loka',\n companion_history: 'Samtalaferill',\n companion_expand_chat: 'Stækka spjall',\n companion_sidebar_dock_label: 'Kví',\n companion_sidebar_side_label: 'Hlið',\n companion_sidebar_left: 'Vinstri',\n companion_sidebar_right: 'Hægri',\n companion_resize_chat: 'Breyta stærð spjalls',\n scroll_to_bottom: 'Fara neðst',\n thinking: 'Hugsa…',\n running: 'Í vinnslu…',\n steps: 'skref',\n step_arguments: 'Viðföng',\n step_result: 'Niðurstaða',\n attach_files:\n 'Hengja við myndir, myndskeið, PDF-skjöl eða töflureikna (hámarksstærð 25 MB)',\n mark_page_active:\n 'Smelltu á eitthvað á síðunni til að merkja það — Esc til að hætta við',\n mark_page: 'Merktu eitthvað á síðunni til að spyrja um það',\n stop_response: 'Stöðva svar',\n copy_reply: 'Afrita svar',\n mentions_empty: 'Engar niðurstöður',\n copied: 'Afritað',\n send_message: 'Senda skilaboð',\n upload_failed: 'Upphleðsla mistókst: {error}',\n remove_attachment: 'Fjarlægja viðhengi',\n json_no_items: 'Engin atriði',\n json_no_data: 'Engin gögn',\n json_no_chart_data: 'Engin gögn fyrir myndrit',\n json_unsupported: 'Ekki stutt: {type}',\n json_see_less: 'Sýna minna',\n json_phone_agent: 'Símafulltrúi',\n json_phone_agent_test: 'Prófa á vefnum',\n page_context_remove: 'Fjarlægja samhengi síðu',\n json_see_more: 'Sýna {count} í viðbót',\n queued_label: '{count} Í biðröð',\n remove_queued_message: 'Fjarlægja skilaboð úr biðröð',\n send_queued_now: 'Senda skilaboð í biðröð núna',\n turn_failed_message: 'Eitthvað fór úrskeiðis og svarið barst ekki.',\n turn_failed_retry: 'Reyna aftur',\n page_mark_hint: 'Smelltu á eitthvað til að merkja það',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rammi',\n page_mark_shape_circle: 'Hringur',\n page_mark_shape_arrow: 'Ör',\n page_mark_shape_bracket: 'Hornklofi',\n page_mark_shape_underline: 'Undirstrikun',\n page_mark_shape_highlight: 'Áherslulitun',\n page_mark_shape_strike_through: 'Yfirstrikun',\n page_mark_shape_crossed_off: 'Krossa yfir',\n page_mark_shape_aria: 'Lögun merkingar: {shape}',\n page_mark_note_placeholder: 'Bæta við athugasemd… (Enter til að hengja við)',\n page_mark_attach: 'Hengja merkingu við',\n page_mark_remove: 'Fjarlægja {label}',\n page_mark_region: 'Merkt svæði',\n page_mark_default_message: 'Hvað er þetta?',\n file_rejected: 'Skráargerðin er ekki studd eða skráin er of stór.',\n dictate: 'Lesa fyrir',\n stop_dictation: 'Hætta að lesa fyrir',\n dictation_mic_blocked: 'Leyfðu aðgang að hljóðnema til að lesa fyrir',\n dictation_unavailable: 'Fyrirlestur er ekki í boði núna',\n questions_back: 'Til baka',\n questions_next: 'Áfram',\n questions_send: 'Senda',\n questions_type_answer: 'Ég skrifa það',\n questions_answer_placeholder: 'Skrifaðu svarið þitt…',\n close_conversation_title: 'Loka samtali',\n close_conversation_description:\n 'Ertu viss um að þú viljir loka þessu samtali?',\n close_conversation_cancel: 'Nei',\n close_conversation_confirm: 'Já',\n dialog_close: 'Loka',\n zoom_in: 'Auka aðdrátt',\n zoom_out: 'Minnka aðdrátt',\n reset_zoom: 'Endurstilla aðdrátt',\n support_chat_aria_label: 'Þjónustuspjall',\n};\n","import type { TranslationInterface } from '.';\n\nexport const LatvianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Rakstiet ziņojumu...',\n your_issue_has_been_resolved: 'Jūsu problēma ir atrisināta!',\n new_conversation: 'Jauna saruna',\n welcome_screen_title: 'Laipni lūdzam mūsu atbalsta tērzēšanā',\n welcome_screen_description:\n 'Mēs esam šeit, lai palīdzētu! Sāciet sarunu, un mēs jums atbildēsim pēc iespējas ātrāk.',\n your_name_placeholder: 'Jūsu vārds',\n your_email_placeholder: 'Jūsu e-pasta adrese',\n start_chat_button: 'Sazināties ar atbalstu',\n start_chat_button_loading: 'Savienošana...',\n i_need_more_help: 'Man vajag vairāk palīdzības',\n this_was_helpful: 'Tas bija noderīgi',\n optional: 'Neobligāts',\n no_conversations_yet: 'Pagaidām nav sarunu',\n back_to_conversations: 'Atpakaļ pie sarunām',\n closed_conversations: 'Slēgtās sarunas',\n csat_title: 'Kāda bija jūsu saruna?',\n csat_submitted_title: 'Jūs novērtējāt sarunu kā',\n csat_feedback_placeholder: 'Pastāstiet mums vairāk... (neobligāti)',\n follow_up_placeholder: 'Turpināt…',\n companion_layout_label: 'Izkārtojums',\n companion_layout_floating: 'Peldošs',\n companion_layout_sidebar: 'Sānjosla',\n companion_layout_fullscreen: 'Pilnekrāns',\n companion_close: 'Aizvērt',\n companion_history: 'Sarunu vēsture',\n companion_expand_chat: 'Izvērst tērzēšanu',\n companion_sidebar_dock_label: 'Piestiprināšana',\n companion_sidebar_side_label: 'Puse',\n companion_sidebar_left: 'Pa kreisi',\n companion_sidebar_right: 'Pa labi',\n companion_resize_chat: 'Mainīt tērzēšanas izmēru',\n scroll_to_bottom: 'Ritināt uz leju',\n thinking: 'Domāju…',\n running: 'Notiek izpilde…',\n steps: 'darbības',\n step_arguments: 'Argumenti',\n step_result: 'Rezultāts',\n attach_files:\n 'Pievienot attēlus, video, PDF vai izklājlapas (maksimālais izmērs 25 MB)',\n mark_page_active:\n 'Noklikšķiniet uz kaut kā lapā, lai to atzīmētu — Esc, lai atceltu',\n mark_page: 'Atzīmējiet kaut ko lapā, lai par to pajautātu',\n stop_response: 'Apturēt atbildi',\n copy_reply: 'Kopēt atbildi',\n mentions_empty: 'Nav atbilstību',\n copied: 'Nokopēts',\n send_message: 'Sūtīt ziņu',\n upload_failed: 'Augšupielāde neizdevās: {error}',\n remove_attachment: 'Noņemt pielikumu',\n json_no_items: 'Nav vienumu',\n json_no_data: 'Nav datu',\n json_no_chart_data: 'Diagrammai nav datu',\n json_unsupported: 'Nav atbalstīts: {type}',\n json_see_less: 'Rādīt mazāk',\n json_phone_agent: 'Tālruņa aģents',\n json_phone_agent_test: 'Testēt tīmeklī',\n page_context_remove: 'Noņemt lapas kontekstu',\n json_see_more: 'Rādīt vēl {count}',\n queued_label: '{count} Rindā',\n remove_queued_message: 'Noņemt ziņu no rindas',\n send_queued_now: 'Nosūtīt rindā esošās ziņas tūlīt',\n turn_failed_message: 'Radās problēma, un atbilde nepienāca.',\n turn_failed_retry: 'Mēģināt vēlreiz',\n page_mark_hint: 'Noklikšķiniet uz kaut kā, lai to atzīmētu',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rāmis',\n page_mark_shape_circle: 'Aplis',\n page_mark_shape_arrow: 'Bulta',\n page_mark_shape_bracket: 'Iekava',\n page_mark_shape_underline: 'Pasvītrojums',\n page_mark_shape_highlight: 'Izcēlums',\n page_mark_shape_strike_through: 'Pārsvītrojums',\n page_mark_shape_crossed_off: 'Krustenisks svītrojums',\n page_mark_shape_aria: 'Atzīmes forma: {shape}',\n page_mark_note_placeholder: 'Pievienot piezīmi… (Enter, lai pievienotu)',\n page_mark_attach: 'Pievienot atzīmi',\n page_mark_remove: 'Noņemt {label}',\n page_mark_region: 'Atzīmēts apgabals',\n page_mark_default_message: 'Kas tas ir?',\n file_rejected: 'Faila tips netiek atbalstīts vai fails ir pārāk liels.',\n dictate: 'Diktēt',\n stop_dictation: 'Pārtraukt diktēšanu',\n dictation_mic_blocked: 'Atļaujiet piekļuvi mikrofonam, lai diktētu',\n dictation_unavailable: 'Diktēšana pašlaik nav pieejama',\n questions_back: 'Atpakaļ',\n questions_next: 'Tālāk',\n questions_send: 'Sūtīt',\n questions_type_answer: 'Rakstīšu pats',\n questions_answer_placeholder: 'Ierakstiet savu atbildi…',\n close_conversation_title: 'Aizvērt sarunu',\n close_conversation_description: 'Vai tiešām vēlaties aizvērt šo sarunu?',\n close_conversation_cancel: 'Nē',\n close_conversation_confirm: 'Jā',\n dialog_close: 'Aizvērt',\n zoom_in: 'Pietuvināt',\n zoom_out: 'Attālināt',\n reset_zoom: 'Atiestatīt tālummaiņu',\n support_chat_aria_label: 'Atbalsta tērzēšana',\n};\n","import type { TranslationInterface } from '.';\n\nexport const LithuanianLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Parašykite žinutę...',\n your_issue_has_been_resolved: 'Jūsų problema išspręsta!',\n new_conversation: 'Naujas pokalbis',\n welcome_screen_title: 'Sveiki atvykę į mūsų pagalbos pokalbį',\n welcome_screen_description:\n 'Mes čia, kad padėtume! Pradėkite pokalbį ir mes atsakysime kuo greičiau.',\n your_name_placeholder: 'Jūsų vardas',\n your_email_placeholder: 'Jūsų el. pašto adresas',\n start_chat_button: 'Kalbėti su pagalba',\n start_chat_button_loading: 'Jungiamasi...',\n i_need_more_help: 'Man reikia daugiau pagalbos',\n this_was_helpful: 'Tai buvo naudinga',\n optional: 'Neprivaloma',\n no_conversations_yet: 'Pokalbių dar nėra',\n back_to_conversations: 'Grįžti į pokalbius',\n closed_conversations: 'Uždaryti pokalbiai',\n csat_title: 'Koks buvo jūsų pokalbis?',\n csat_submitted_title: 'Pokalbį įvertinote kaip',\n csat_feedback_placeholder: 'Papasakokite daugiau... (neprivaloma)',\n follow_up_placeholder: 'Tęsti…',\n companion_layout_label: 'Išdėstymas',\n companion_layout_floating: 'Slankusis',\n companion_layout_sidebar: 'Šoninė juosta',\n companion_layout_fullscreen: 'Visas ekranas',\n companion_close: 'Uždaryti',\n companion_history: 'Pokalbių istorija',\n companion_expand_chat: 'Išplėsti pokalbį',\n companion_sidebar_dock_label: 'Prijungimas',\n companion_sidebar_side_label: 'Pusė',\n companion_sidebar_left: 'Kairė',\n companion_sidebar_right: 'Dešinė',\n companion_resize_chat: 'Keisti pokalbio dydį',\n scroll_to_bottom: 'Slinkti į apačią',\n thinking: 'Galvoju…',\n running: 'Vykdoma…',\n steps: 'žingsniai',\n step_arguments: 'Argumentai',\n step_result: 'Rezultatas',\n attach_files:\n 'Pridėti vaizdus, vaizdo įrašus, PDF ar skaičiuokles (didžiausias dydis 25 MB)',\n mark_page_active:\n 'Spustelėkite ką nors puslapyje, kad pažymėtumėte — Esc atšaukti',\n mark_page: 'Pažymėkite ką nors puslapyje, kad galėtumėte apie tai paklausti',\n stop_response: 'Stabdyti atsakymą',\n copy_reply: 'Kopijuoti atsakymą',\n mentions_empty: 'Atitikmenų nėra',\n copied: 'Nukopijuota',\n send_message: 'Siųsti žinutę',\n upload_failed: 'Įkelti nepavyko: {error}',\n remove_attachment: 'Pašalinti priedą',\n json_no_items: 'Elementų nėra',\n json_no_data: 'Duomenų nėra',\n json_no_chart_data: 'Diagramai nėra duomenų',\n json_unsupported: 'Nepalaikoma: {type}',\n json_see_less: 'Rodyti mažiau',\n json_phone_agent: 'Telefono agentas',\n json_phone_agent_test: 'Išbandyti internete',\n page_context_remove: 'Pašalinti puslapio kontekstą',\n json_see_more: 'Rodyti dar {count}',\n queued_label: '{count} Eilėje',\n remove_queued_message: 'Pašalinti žinutę iš eilės',\n send_queued_now: 'Išsiųsti eilėje esančias žinutes dabar',\n turn_failed_message: 'Kažkas nutiko ir atsakymas neatėjo.',\n turn_failed_retry: 'Bandyti dar kartą',\n page_mark_hint: 'Spustelėkite ką nors, kad pažymėtumėte',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rėmelis',\n page_mark_shape_circle: 'Apskritimas',\n page_mark_shape_arrow: 'Rodyklė',\n page_mark_shape_bracket: 'Skliaustas',\n page_mark_shape_underline: 'Pabraukimas',\n page_mark_shape_highlight: 'Paryškinimas',\n page_mark_shape_strike_through: 'Perbraukimas',\n page_mark_shape_crossed_off: 'Kryžminis perbraukimas',\n page_mark_shape_aria: 'Žymėjimo forma: {shape}',\n page_mark_note_placeholder: 'Pridėti pastabą… (Enter pridėti)',\n page_mark_attach: 'Pridėti žymėjimą',\n page_mark_remove: 'Pašalinti {label}',\n page_mark_region: 'Pažymėta sritis',\n page_mark_default_message: 'Kas tai?',\n file_rejected: 'Failo tipas nepalaikomas arba failas per didelis.',\n dictate: 'Diktuoti',\n stop_dictation: 'Sustabdyti diktavimą',\n dictation_mic_blocked: 'Leiskite naudoti mikrofoną, kad galėtumėte diktuoti',\n dictation_unavailable: 'Diktavimas šiuo metu nepasiekiamas',\n questions_back: 'Atgal',\n questions_next: 'Toliau',\n questions_send: 'Siųsti',\n questions_type_answer: 'Parašysiu pats',\n questions_answer_placeholder: 'Parašykite savo atsakymą…',\n close_conversation_title: 'Uždaryti pokalbį',\n close_conversation_description: 'Ar tikrai norite uždaryti šį pokalbį?',\n close_conversation_cancel: 'Ne',\n close_conversation_confirm: 'Taip',\n dialog_close: 'Uždaryti',\n zoom_in: 'Priartinti',\n zoom_out: 'Nutolinti',\n reset_zoom: 'Atstatyti mastelį',\n support_chat_aria_label: 'Pagalbos pokalbis',\n};\n","import type { TranslationInterface } from '.';\n\nexport const LuxembourgishLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Schreift eng Noriicht...',\n your_issue_has_been_resolved: 'Äert Problem gouf geléist!',\n new_conversation: 'Nei Konversatioun',\n welcome_screen_title: 'Wëllkomm bei eisem Support-Chat',\n welcome_screen_description:\n 'Mir sinn hei fir ze hëllefen! Start eng Konversatioun a mir äntweren Iech esou séier wéi méiglech.',\n your_name_placeholder: 'Ären Numm',\n your_email_placeholder: 'Är E-Mail-Adress',\n start_chat_button: 'Mat dem Support schwätzen',\n start_chat_button_loading: 'Verbindung...',\n i_need_more_help: 'Ech brauch méi Hëllef',\n this_was_helpful: 'Dat war hëllefräich',\n optional: 'Fakultativ',\n no_conversations_yet: 'Nach keng Konversatiounen',\n back_to_conversations: 'Zréck zu de Konversatiounen',\n closed_conversations: 'Zougemaachte Konversatiounen',\n csat_title: 'Wéi war Är Konversatioun?',\n csat_submitted_title: 'Dir hutt d’Konversatioun bewäert als',\n csat_feedback_placeholder: 'Sot eis méi... (fakultativ)',\n follow_up_placeholder: 'Nofroen…',\n companion_layout_label: 'Layout',\n companion_layout_floating: 'Schwebend',\n companion_layout_sidebar: 'Säitleeschte',\n companion_layout_fullscreen: 'Vollbild',\n companion_close: 'Zoumaachen',\n companion_history: 'Gespréichsverlaf',\n companion_expand_chat: 'Chat ausklappen',\n companion_sidebar_dock_label: 'Andocken',\n companion_sidebar_side_label: 'Säit',\n companion_sidebar_left: 'Lénks',\n companion_sidebar_right: 'Riets',\n companion_resize_chat: 'Chatgréisst änneren',\n scroll_to_bottom: 'No ënne scrollen',\n thinking: 'Ech denken no…',\n running: 'Gëtt ausgefouert…',\n steps: 'Schrëtt',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Biller, Videoen, PDFen oder Tabelle bäifügen (maximal Gréisst 25 MB)',\n mark_page_active:\n 'Klickt op eppes op der Säit, fir et ze markéieren — Esc fir ofzebriechen',\n mark_page: 'Markéiert eppes op der Säit, fir doriwwer ze froen',\n stop_response: 'Äntwert stoppen',\n copy_reply: 'Äntwert kopéieren',\n mentions_empty: 'Keng Treffer',\n copied: 'Kopéiert',\n send_message: 'Noriicht schécken',\n upload_failed: 'Eroplueden net gelongen: {error}',\n remove_attachment: 'Unhang ewechhuelen',\n json_no_items: 'Keng Elementer',\n json_no_data: 'Keng Donnéeën',\n json_no_chart_data: \"Keng Donnéeë fir d'Diagramm\",\n json_unsupported: 'Net ënnerstëtzt: {type}',\n json_see_less: 'Manner weisen',\n json_phone_agent: 'Telefonsagent',\n json_phone_agent_test: 'Am Web testen',\n page_context_remove: 'Säitekontext ewechhuelen',\n json_see_more: '{count} weider weisen',\n queued_label: '{count} An der Waardeschlaang',\n remove_queued_message: 'Noriicht aus der Waardeschlaang ewechhuelen',\n send_queued_now: 'Noriichten aus der Waardeschlaang elo schécken',\n turn_failed_message: \"Eppes ass schifgaangen an d'Äntwert ass net ukomm.\",\n turn_failed_retry: 'Nach eng Kéier probéieren',\n page_mark_hint: 'Klickt op eppes, fir et ze markéieren',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Këscht',\n page_mark_shape_circle: 'Krees',\n page_mark_shape_arrow: 'Pfeil',\n page_mark_shape_bracket: 'Klammer',\n page_mark_shape_underline: 'Ënnersträichen',\n page_mark_shape_highlight: 'Markéieren',\n page_mark_shape_strike_through: 'Duerchsträichen',\n page_mark_shape_crossed_off: 'Duerchkräizen',\n page_mark_shape_aria: 'Form vun der Markéierung: {shape}',\n page_mark_note_placeholder: 'Notiz derbäisetzen… (Enter fir bäizefügen)',\n page_mark_attach: 'Markéierung bäifügen',\n page_mark_remove: '{label} ewechhuelen',\n page_mark_region: 'Markéierte Beräich',\n page_mark_default_message: 'Wat ass dat?',\n file_rejected:\n 'De Fichierstyp gëtt net ënnerstëtzt oder de Fichier ass ze grouss.',\n dictate: 'Diktéieren',\n stop_dictation: 'Diktat ophalen',\n dictation_mic_blocked: 'Erlaabt den Zougang zum Mikro fir ze diktéieren',\n dictation_unavailable: 'Diktéieren ass am Moment net verfügbar',\n questions_back: 'Zréck',\n questions_next: 'Weider',\n questions_send: 'Schécken',\n questions_type_answer: 'Ech schreiwen et selwer',\n questions_answer_placeholder: 'Schreift Är Äntwert…',\n close_conversation_title: 'Konversatioun zoumaachen',\n close_conversation_description:\n 'Wëllt Dir dës Konversatioun wierklech zoumaachen?',\n close_conversation_cancel: 'Nee',\n close_conversation_confirm: 'Jo',\n dialog_close: 'Zoumaachen',\n zoom_in: 'Erazoomen',\n zoom_out: 'Erauszoomen',\n reset_zoom: 'Zoom zrécksetzen',\n support_chat_aria_label: 'Support-Chat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const MalteseLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Ikteb messaġġ...',\n your_issue_has_been_resolved: 'Il-problema tiegħek ġiet riżolta!',\n new_conversation: 'Konversazzjoni ġdida',\n welcome_screen_title: 'Merħba fis-support chat tagħna',\n welcome_screen_description:\n \"Aħna hawn biex ngħinu! Ibda konversazzjoni u nirrispondu malajr kemm jista' jkun.\",\n your_name_placeholder: 'Ismek',\n your_email_placeholder: 'L-indirizz tal-email tiegħek',\n start_chat_button: 'Kellem lis-support',\n start_chat_button_loading: 'Qed jikkonnettja...',\n i_need_more_help: 'Għandi bżonn aktar għajnuna',\n this_was_helpful: \"Dan kien ta' għajnuna\",\n optional: 'Mhux obbligatorju',\n no_conversations_yet: \"Għad m'hemmx konversazzjonijiet\",\n back_to_conversations: 'Lura għall-konversazzjonijiet',\n closed_conversations: 'Konversazzjonijiet magħluqa',\n csat_title: 'Kif kienet il-konversazzjoni tiegħek?',\n csat_submitted_title: 'Int ivvalutajt il-konversazzjoni bħala',\n csat_feedback_placeholder: 'Għidilna aktar... (mhux obbligatorju)',\n follow_up_placeholder: 'Kompli l-mistoqsija…',\n companion_layout_label: 'Tqassim',\n companion_layout_floating: 'Galleġġjanti',\n companion_layout_sidebar: 'Strixxa tal-ġenb',\n companion_layout_fullscreen: 'Skrin sħiħ',\n companion_close: 'Agħlaq',\n companion_history: 'Storja tal-konversazzjonijiet',\n companion_expand_chat: 'Kabbar iċ-chat',\n companion_sidebar_dock_label: 'Iddokkjar',\n companion_sidebar_side_label: 'Naħa',\n companion_sidebar_left: 'Xellug',\n companion_sidebar_right: 'Lemin',\n companion_resize_chat: 'Biddel id-daqs taċ-chat',\n scroll_to_bottom: 'Skrollja sal-qiegħ',\n thinking: 'Qed naħseb…',\n running: 'Qed jitħaddem…',\n steps: 'passi',\n step_arguments: 'Argumenti',\n step_result: 'Riżultat',\n attach_files:\n 'Ehmeż stampi, vidjows, PDFs jew spreadsheets (daqs massimu 25 MB)',\n mark_page_active:\n 'Ikklikkja xi ħaġa fil-paġna biex timmarkaha — Esc biex tikkanċella',\n mark_page: 'Immarka xi ħaġa fil-paġna biex tistaqsi dwarha',\n stop_response: 'Waqqaf it-tweġiba',\n copy_reply: 'Ikkopja t-tweġiba',\n mentions_empty: 'L-ebda riżultat',\n copied: 'Ikkupjat',\n send_message: 'Ibgħat messaġġ',\n upload_failed: 'It-tlugħ falla: {error}',\n remove_attachment: 'Neħħi s-sekwestru',\n json_no_items: 'L-ebda oġġett',\n json_no_data: 'L-ebda data',\n json_no_chart_data: 'L-ebda data għaċ-ċart',\n json_unsupported: 'Mhux appoġġjat: {type}',\n json_see_less: 'Ara inqas',\n json_phone_agent: 'Aġent tat-telefon',\n json_phone_agent_test: 'Ittestja fuq il-web',\n page_context_remove: 'Neħħi l-kuntest tal-paġna',\n json_see_more: 'Ara {count} oħra',\n queued_label: '{count} Fil-kju',\n remove_queued_message: 'Neħħi l-messaġġ mill-kju',\n send_queued_now: 'Ibgħat il-messaġġi fil-kju issa',\n turn_failed_message: 'Kien hemm problema u t-tweġiba ma waslitx.',\n turn_failed_retry: \"Erġa' pprova\",\n page_mark_hint: 'Ikklikkja xi ħaġa biex timmarkaha',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Kaxxa',\n page_mark_shape_circle: 'Ċirku',\n page_mark_shape_arrow: 'Vleġġa',\n page_mark_shape_bracket: 'Parentesi',\n page_mark_shape_underline: 'Issottolinjar',\n page_mark_shape_highlight: 'Immarkar',\n page_mark_shape_strike_through: \"Qtugħ b'linja\",\n page_mark_shape_crossed_off: \"Qtugħ b'salib\",\n page_mark_shape_aria: 'Forma tal-marka: {shape}',\n page_mark_note_placeholder: 'Żid nota… (Enter biex tehmeż)',\n page_mark_attach: 'Ehmeż il-marka',\n page_mark_remove: 'Neħħi {label}',\n page_mark_region: 'Żona mmarkata',\n page_mark_default_message: 'X’inhu dan?',\n file_rejected:\n 'It-tip tal-fajl mhuwiex appoġġjat jew il-fajl huwa kbir wisq.',\n dictate: 'Iddetta',\n stop_dictation: 'Waqqaf id-dettatura',\n dictation_mic_blocked: 'Ippermetti l-aċċess għall-mikrofonu biex tiddetta',\n dictation_unavailable: 'Id-dettatura mhijiex disponibbli bħalissa',\n questions_back: 'Lura',\n questions_next: 'Li jmiss',\n questions_send: 'Ibgħat',\n questions_type_answer: 'Nikteb jien',\n questions_answer_placeholder: 'Ikteb it-tweġiba tiegħek…',\n close_conversation_title: 'Agħlaq il-konversazzjoni',\n close_conversation_description: 'Żgur li trid tagħlaq din il-konversazzjoni?',\n close_conversation_cancel: 'Le',\n close_conversation_confirm: 'Iva',\n dialog_close: 'Agħlaq',\n zoom_in: 'Kabbar',\n zoom_out: 'Ċekken',\n reset_zoom: 'Irrisettja ż-zoom',\n support_chat_aria_label: 'Chat ta’ appoġġ',\n};\n","import type { TranslationInterface } from '.';\n\nexport const NorwegianBokmalLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Skriv en melding...',\n your_issue_has_been_resolved: 'Saken din er løst!',\n new_conversation: 'Ny samtale',\n welcome_screen_title: 'Velkommen til vår kundestøtte',\n welcome_screen_description:\n 'Vi er her for å hjelpe! Start en samtale, så svarer vi deg så snart som mulig.',\n your_name_placeholder: 'Ditt navn',\n your_email_placeholder: 'Din e-postadresse',\n start_chat_button: 'Snakk med kundestøtte',\n start_chat_button_loading: 'Kobler til...',\n i_need_more_help: 'Jeg trenger mer hjelp',\n this_was_helpful: 'Dette var nyttig',\n optional: 'Valgfritt',\n no_conversations_yet: 'Ingen samtaler ennå',\n back_to_conversations: 'Tilbake til samtaler',\n closed_conversations: 'Lukkede samtaler',\n csat_title: 'Hvordan var samtalen din?',\n csat_submitted_title: 'Du vurderte samtalen som',\n csat_feedback_placeholder: 'Fortell oss mer... (valgfritt)',\n follow_up_placeholder: 'Følg opp…',\n companion_layout_label: 'Oppsett',\n companion_layout_floating: 'Flytende',\n companion_layout_sidebar: 'Sidepanel',\n companion_layout_fullscreen: 'Fullskjerm',\n companion_close: 'Lukk',\n companion_history: 'Samtalehistorikk',\n companion_expand_chat: 'Utvid chatten',\n companion_sidebar_dock_label: 'Dokking',\n companion_sidebar_side_label: 'Side',\n companion_sidebar_left: 'Venstre',\n companion_sidebar_right: 'Høyre',\n companion_resize_chat: 'Endre størrelsen på chatten',\n scroll_to_bottom: 'Rull til bunnen',\n thinking: 'Tenker…',\n running: 'Kjører…',\n steps: 'trinn',\n step_arguments: 'Argumenter',\n step_result: 'Resultat',\n attach_files:\n 'Legg ved bilder, videoer, PDF-er eller regneark (maksimal størrelse 25 MB)',\n mark_page_active:\n 'Klikk på noe på siden for å markere det — Esc for å avbryte',\n mark_page: 'Marker noe på siden for å spørre om det',\n stop_response: 'Stopp svar',\n copy_reply: 'Kopier svar',\n mentions_empty: 'Ingen treff',\n copied: 'Kopiert',\n send_message: 'Send melding',\n upload_failed: 'Opplasting mislyktes: {error}',\n remove_attachment: 'Fjern vedlegg',\n json_no_items: 'Ingen elementer',\n json_no_data: 'Ingen data',\n json_no_chart_data: 'Ingen data for diagrammet',\n json_unsupported: 'Ikke støttet: {type}',\n json_see_less: 'Vis mindre',\n json_phone_agent: 'Telefonagent',\n json_phone_agent_test: 'Test via nett',\n page_context_remove: 'Fjern sidekontekst',\n json_see_more: 'Vis {count} til',\n queued_label: '{count} I kø',\n remove_queued_message: 'Fjern meldingen fra køen',\n send_queued_now: 'Send meldinger i køen nå',\n turn_failed_message: 'Noe gikk galt, og svaret kom ikke fram.',\n turn_failed_retry: 'Prøv igjen',\n page_mark_hint: 'Klikk på noe for å markere det',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Ramme',\n page_mark_shape_circle: 'Sirkel',\n page_mark_shape_arrow: 'Pil',\n page_mark_shape_bracket: 'Klamme',\n page_mark_shape_underline: 'Understreking',\n page_mark_shape_highlight: 'Utheving',\n page_mark_shape_strike_through: 'Gjennomstreking',\n page_mark_shape_crossed_off: 'Kryss ut',\n page_mark_shape_aria: 'Markeringsform: {shape}',\n page_mark_note_placeholder: 'Legg til et notat… (Enter for å legge ved)',\n page_mark_attach: 'Legg ved markering',\n page_mark_remove: 'Fjern {label}',\n page_mark_region: 'Markert område',\n page_mark_default_message: 'Hva er dette?',\n file_rejected: 'Filtypen støttes ikke, eller filen er for stor.',\n dictate: 'Dikter',\n stop_dictation: 'Stopp diktering',\n dictation_mic_blocked: 'Tillat mikrofontilgang for å diktere',\n dictation_unavailable: 'Diktering er ikke tilgjengelig akkurat nå',\n questions_back: 'Tilbake',\n questions_next: 'Neste',\n questions_send: 'Send',\n questions_type_answer: 'Jeg skriver det selv',\n questions_answer_placeholder: 'Skriv svaret ditt…',\n close_conversation_title: 'Lukk samtale',\n close_conversation_description:\n 'Er du sikker på at du vil lukke denne samtalen?',\n close_conversation_cancel: 'Nei',\n close_conversation_confirm: 'Ja',\n dialog_close: 'Lukk',\n zoom_in: 'Zoom inn',\n zoom_out: 'Zoom ut',\n reset_zoom: 'Tilbakestill zoom',\n support_chat_aria_label: 'Support-chat',\n};\n","import type { TranslationInterface } from '.';\n\nexport const SlovakLanguage: TranslationInterface = {\n write_a_message_placeholder: 'Napíšte správu...',\n your_issue_has_been_resolved: 'Váš problém bol vyriešený!',\n new_conversation: 'Nová konverzácia',\n welcome_screen_title: 'Vitajte v našom zákazníckom chate',\n welcome_screen_description:\n 'Sme tu, aby sme vám pomohli! Začnite konverzáciu a odpovieme vám čo najskôr.',\n your_name_placeholder: 'Vaše meno',\n your_email_placeholder: 'Vaša e-mailová adresa',\n start_chat_button: 'Hovoriť s podporou',\n start_chat_button_loading: 'Pripájanie...',\n i_need_more_help: 'Potrebujem ďalšiu pomoc',\n this_was_helpful: 'Toto bolo užitočné',\n optional: 'Voliteľné',\n no_conversations_yet: 'Zatiaľ žiadne konverzácie',\n back_to_conversations: 'Späť na konverzácie',\n closed_conversations: 'Uzavreté konverzácie',\n csat_title: 'Aká bola vaša konverzácia?',\n csat_submitted_title: 'Konverzáciu ste ohodnotili ako',\n csat_feedback_placeholder: 'Povedzte nám viac... (nepovinné)',\n follow_up_placeholder: 'Pokračovať…',\n companion_layout_label: 'Rozloženie',\n companion_layout_floating: 'Plávajúce',\n companion_layout_sidebar: 'Bočný panel',\n companion_layout_fullscreen: 'Celá obrazovka',\n companion_close: 'Zavrieť',\n companion_history: 'História konverzácií',\n companion_expand_chat: 'Rozbaliť chat',\n companion_sidebar_dock_label: 'Ukotvenie',\n companion_sidebar_side_label: 'Strana',\n companion_sidebar_left: 'Vľavo',\n companion_sidebar_right: 'Vpravo',\n companion_resize_chat: 'Zmeniť veľkosť chatu',\n scroll_to_bottom: 'Posunúť nadol',\n thinking: 'Premýšľam…',\n running: 'Prebieha…',\n steps: 'kroky',\n step_arguments: 'Argumenty',\n step_result: 'Výsledok',\n attach_files:\n 'Priložiť obrázky, videá, PDF súbory alebo tabuľky (maximálna veľkosť 25 MB)',\n mark_page_active:\n 'Kliknutím na čokoľvek na stránke to označíte — klávesom Esc akciu zrušíte',\n mark_page: 'Označte niečo na stránke a opýtajte sa na to',\n stop_response: 'Zastaviť odpoveď',\n copy_reply: 'Kopírovať odpoveď',\n mentions_empty: 'Žiadne zhody',\n copied: 'Skopírované',\n send_message: 'Odoslať správu',\n upload_failed: 'Nahrávanie zlyhalo: {error}',\n remove_attachment: 'Odstrániť prílohu',\n json_no_items: 'Žiadne položky',\n json_no_data: 'Žiadne údaje',\n json_no_chart_data: 'Žiadne údaje pre graf',\n json_unsupported: 'Nepodporované: {type}',\n json_see_less: 'Zobraziť menej',\n json_phone_agent: 'Telefónny agent',\n json_phone_agent_test: 'Vyskúšať na webe',\n page_context_remove: 'Odstrániť kontext stránky',\n json_see_more: 'Zobraziť ďalších {count}',\n queued_label: '{count} Vo fronte',\n remove_queued_message: 'Odstrániť správu z frontu',\n send_queued_now: 'Odoslať správy vo fronte teraz',\n turn_failed_message: 'Niečo sa pokazilo a odpoveď neprišla.',\n turn_failed_retry: 'Skúsiť znova',\n page_mark_hint: 'Kliknutím na čokoľvek to označíte',\n page_mark_escape: 'Esc',\n page_mark_shape_box: 'Rámček',\n page_mark_shape_circle: 'Kruh',\n page_mark_shape_arrow: 'Šípka',\n page_mark_shape_bracket: 'Zátvorka',\n page_mark_shape_underline: 'Podčiarknutie',\n page_mark_shape_highlight: 'Zvýraznenie',\n page_mark_shape_strike_through: 'Prečiarknutie',\n page_mark_shape_crossed_off: 'Krížové prečiarknutie',\n page_mark_shape_aria: 'Tvar označenia: {shape}',\n page_mark_note_placeholder: 'Pridať poznámku… (Enter na priloženie)',\n page_mark_attach: 'Priložiť označenie',\n page_mark_remove: 'Odstrániť {label}',\n page_mark_region: 'Označená oblasť',\n page_mark_default_message: 'Čo je to?',\n file_rejected: 'Typ súboru nie je podporovaný alebo je súbor príliš veľký.',\n dictate: 'Diktovať',\n stop_dictation: 'Zastaviť diktovanie',\n dictation_mic_blocked: 'Na diktovanie povoľte prístup k mikrofónu',\n dictation_unavailable: 'Diktovanie momentálne nie je k dispozícii',\n questions_back: 'Späť',\n questions_next: 'Ďalej',\n questions_send: 'Odoslať',\n questions_type_answer: 'Napíšem to sám',\n questions_answer_placeholder: 'Napíšte svoju odpoveď…',\n close_conversation_title: 'Uzavrieť konverzáciu',\n close_conversation_description: 'Naozaj chcete túto konverzáciu uzavrieť?',\n close_conversation_cancel: 'Nie',\n close_conversation_confirm: 'Áno',\n dialog_close: 'Zavrieť',\n zoom_in: 'Priblížiť',\n zoom_out: 'Oddialiť',\n reset_zoom: 'Obnoviť priblíženie',\n support_chat_aria_label: 'Chat podpory',\n};\n","import type { WidgetConfig } from '../types/widget-config';\nimport { ArabicLanguage } from './ar';\nimport { BengaliLanguage } from './bn';\nimport { BulgarianLanguage } from './bg';\nimport { CzechLanguage } from './cs';\nimport { DanishLanguage } from './da';\nimport { GreekLanguage } from './el';\nimport { GermanLanguage } from './de';\nimport { EnglishLanguage } from './en';\nimport { SpanishLanguage } from './es';\nimport { FilipinoLanguage } from './fil';\nimport { FinnishLanguage } from './fi';\nimport { FrenchLanguage } from './fr';\nimport { HindiLanguage } from './hi';\nimport { ItalianLanguage } from './it';\nimport { JapaneseLanguage } from './ja';\nimport { KoreanLanguage } from './ko';\nimport { DutchLanguage } from './nl';\nimport { NorwegianLanguage } from './no';\nimport { PolishLanguage } from './pl';\nimport { PortugueseLanguage } from './pt';\nimport { RomanianLanguage } from './ro';\nimport { SwedishLanguage } from './sv';\nimport { RussianLanguage } from './ru';\nimport { ThaiLanguage } from './th';\nimport { TurkishLanguage } from './tr';\nimport { UrduLanguage } from './ur';\nimport { VietnameseLanguage } from './vi';\nimport { ChineseSimplifiedLanguage } from './zh-cn';\nimport { CroatianLanguage } from './hr';\nimport { EstonianLanguage } from './et';\nimport { HungarianLanguage } from './hu';\nimport { IcelandicLanguage } from './is';\nimport { LatvianLanguage } from './lv';\nimport { LithuanianLanguage } from './lt';\nimport { LuxembourgishLanguage } from './lb';\nimport { MalteseLanguage } from './mt';\nimport { NorwegianBokmalLanguage } from './nb';\nimport { SlovakLanguage } from './sk';\n\nconst languages = {\n ar: ArabicLanguage,\n bn: BengaliLanguage,\n bg: BulgarianLanguage,\n cs: CzechLanguage,\n da: DanishLanguage,\n de: GermanLanguage,\n el: GreekLanguage,\n en: EnglishLanguage,\n es: SpanishLanguage,\n et: EstonianLanguage,\n fi: FinnishLanguage,\n fil: FilipinoLanguage,\n fr: FrenchLanguage,\n hi: HindiLanguage,\n hr: CroatianLanguage,\n hu: HungarianLanguage,\n is: IcelandicLanguage,\n it: ItalianLanguage,\n ja: JapaneseLanguage,\n ko: KoreanLanguage,\n lb: LuxembourgishLanguage,\n lt: LithuanianLanguage,\n lv: LatvianLanguage,\n mt: MalteseLanguage,\n nb: NorwegianBokmalLanguage,\n nl: DutchLanguage,\n no: NorwegianLanguage,\n pl: PolishLanguage,\n pt: PortugueseLanguage,\n ro: RomanianLanguage,\n ru: RussianLanguage,\n sk: SlovakLanguage,\n sv: SwedishLanguage,\n th: ThaiLanguage,\n tr: TurkishLanguage,\n ur: UrduLanguage,\n vi: VietnameseLanguage,\n 'zh-cn': ChineseSimplifiedLanguage,\n} as const;\n\nexport const LANGUAGES = Object.keys(languages) as (keyof typeof languages)[];\nexport type Language = (typeof LANGUAGES)[number];\n\nexport function isSupportedLanguage(\n lang: string | null | undefined,\n): lang is Language {\n return LANGUAGES.includes(lang as Language);\n}\n\n/** Languages written right-to-left; the widget flips its layout for them. */\nconst RTL_LANGUAGES: ReadonlySet<Language> = new Set<Language>(['ar', 'ur']);\n\nexport function isRtlLanguage(lang: Language): boolean {\n return RTL_LANGUAGES.has(lang);\n}\n\n/** The language the widget renders in: `config.language` when supported, else English. */\nexport function resolveLanguage(lang: string | null | undefined): Language {\n return isSupportedLanguage(lang) ? lang : 'en';\n}\n\nexport function getTranslation(\n key: TranslationKeyU,\n lang: Language,\n overrides: WidgetConfig['translationOverrides'],\n params?: Record<string, string | number>,\n): string {\n const text =\n overrides?.[lang]?.[key] ||\n languages[lang][key] ||\n EnglishLanguage[key] ||\n key;\n if (!params) return text;\n return text.replace(/\\{(\\w+)\\}/g, (match, name: string) =>\n name in params ? String(params[name]) : match,\n );\n}\n\n/** `getTranslation` for code that holds the config rather than a language. */\nexport function translate(\n config: Pick<WidgetConfig, 'language' | 'translationOverrides'>,\n key: TranslationKeyU,\n params?: Record<string, string | number>,\n): string {\n return getTranslation(\n key,\n resolveLanguage(config.language),\n config.translationOverrides,\n params,\n );\n}\n\nexport type TranslationInterface = {\n i_need_more_help: string;\n this_was_helpful: string;\n write_a_message_placeholder: string;\n your_issue_has_been_resolved: string;\n new_conversation: string;\n back_to_conversations: string;\n closed_conversations: string;\n no_conversations_yet: string;\n welcome_screen_title: string;\n welcome_screen_description: string;\n your_name_placeholder: string;\n your_email_placeholder: string;\n optional: string;\n start_chat_button: string;\n start_chat_button_loading: string;\n csat_title: string;\n csat_submitted_title: string;\n csat_feedback_placeholder: string;\n follow_up_placeholder: string;\n companion_layout_label: string;\n companion_layout_floating: string;\n companion_layout_sidebar: string;\n companion_layout_fullscreen: string;\n companion_close: string;\n companion_close_chat?: string;\n companion_history: string;\n companion_switch_chat?: string;\n companion_viewing?: string;\n companion_working?: string;\n companion_open?: string;\n companion_closed?: string;\n companion_draft?: string;\n companion_chats?: string;\n companion_chat_number?: string;\n companion_active_chats?: string;\n companion_other_sessions?: string;\n companion_working_chats?: string;\n companion_expand_chat: string;\n companion_sidebar_dock_label: string;\n companion_sidebar_side_label: string;\n companion_sidebar_left: string;\n companion_sidebar_right: string;\n companion_resize_chat: string;\n scroll_to_bottom: string;\n thinking: string;\n running: string;\n steps: string;\n step_arguments: string;\n step_result: string;\n attach_files: string;\n mark_page_active: string;\n mark_page: string;\n stop_response: string;\n copy_reply: string;\n mentions_empty: string;\n copied: string;\n dictate: string;\n stop_dictation: string;\n dictation_mic_blocked: string;\n dictation_unavailable: string;\n send_message: string;\n upload_failed: string;\n file_rejected: string;\n remove_attachment: string;\n json_no_items: string;\n json_no_data: string;\n json_no_chart_data: string;\n json_unsupported: string;\n json_see_less: string;\n /** Subtitle of a tool-built phone-agent card. */\n json_phone_agent: string;\n /** The phone-agent card's action, completed by the host page. */\n json_phone_agent_test: string;\n /** Dismisses the composer's page-context (entity) pill for one message. */\n page_context_remove: string;\n json_see_more: string;\n page_mark_hint: string;\n page_mark_escape: string;\n page_mark_shape_box: string;\n page_mark_shape_circle: string;\n page_mark_shape_arrow: string;\n page_mark_shape_bracket: string;\n page_mark_shape_underline: string;\n page_mark_shape_highlight: string;\n page_mark_shape_strike_through: string;\n page_mark_shape_crossed_off: string;\n page_mark_shape_aria: string;\n page_mark_note_placeholder: string;\n page_mark_attach: string;\n page_mark_remove: string;\n page_mark_region: string;\n page_mark_default_message: string;\n /** Header of the multi-send queue pill above the composer. */\n queued_label: string;\n /** Accessible label of the per-message remove button in the queue pill. */\n remove_queued_message: string;\n send_queued_now: string;\n /** Body of the error row shown when an agent turn failed to arrive. */\n turn_failed_message: string;\n /** Retry action in the failed-turn error row. */\n turn_failed_retry: string;\n /** Previous question in the agent's clarification card. */\n questions_back: string;\n /** Next question in the agent's clarification card. */\n questions_next: string;\n /** Submits every answer of the clarification card as one message. */\n questions_send: string;\n /** Escape from the offered chips into a free-text answer. */\n questions_type_answer: string;\n /** Placeholder of that free-text answer box. */\n questions_answer_placeholder: string;\n /** Fallbacks for the close-session confirmation; a header button's own copy wins. */\n close_conversation_title: string;\n close_conversation_description: string;\n close_conversation_cancel: string;\n close_conversation_confirm: string;\n /** Screen-reader label of the modal's corner dismiss button. */\n dialog_close: string;\n zoom_in: string;\n zoom_out: string;\n reset_zoom: string;\n /** Names the chat panel for screen readers on the host page. */\n support_chat_aria_label: string;\n};\nexport type TranslationKeyU = keyof TranslationInterface;\n","import type { ApiCaller } from '../api/api-caller';\nimport type { Dto } from '../api/client';\nimport type { CreateSessionDto, SessionDto } from '../types/dtos';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { Poller } from '../utils/Poller';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport { runCatching } from '../utils/run-catching';\nimport type { ContactCtx } from './contact.ctx';\nimport type { StorageCtx } from './storage.ctx';\nimport { log } from '../utils/log';\n\ntype SessionState = {\n /**\n * The currently selected session.\n * Can be null if no session is selected, or if in chat screen and the session is not created yet.\n */\n session: SessionDto | null;\n isCreatingSession: boolean;\n isResolvingSession: boolean;\n};\ntype SessionsState = {\n /** List of all user sessions */\n data: SessionDto[];\n /** A cursor to get the next page of sessions */\n cursor: string | undefined;\n /** Indicates if no more pages are left */\n isLastPage: boolean;\n /** Did fetch for the first time */\n didStartInitialFetch: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class SessionCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private storageCtx?: StorageCtx;\n private sessionsPollingIntervalSeconds: number;\n private sessionsRefresher = new Poller();\n /** The session id currently written to storage (null = none written). */\n private persistedSessionId: string | null = null;\n private stopPersistingSession?: () => void;\n private stopWaitingForContact?: () => void;\n private sessionAbortController = new AbortController();\n\n public sessionState = new PrimitiveState<SessionState>({\n session: null,\n isCreatingSession: false,\n isResolvingSession: false,\n });\n public sessionsState = new PrimitiveState<SessionsState>({\n data: [],\n cursor: undefined,\n isLastPage: false,\n didStartInitialFetch: false,\n /**\n * Initialize this as `true` so it always starts loading until the first fetch is done\n */\n isInitialFetchLoading: true,\n });\n\n constructor({\n config,\n api,\n contactCtx,\n storageCtx,\n sessionsPollingIntervalSeconds,\n sharedSessions,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n contactCtx: ContactCtx;\n storageCtx?: StorageCtx;\n sessionsPollingIntervalSeconds: number;\n sharedSessions?: PrimitiveState<SessionsState>;\n }) {\n this.config = config;\n this.api = api;\n this.contactCtx = contactCtx;\n this.storageCtx = storageCtx;\n this.sessionsPollingIntervalSeconds = sessionsPollingIntervalSeconds;\n\n if (sharedSessions) this.sessionsState = sharedSessions;\n else this.registerSessionsRefresherWrapper();\n this.registerActiveSessionPersistence();\n }\n\n /**\n * Remember which conversation the visitor is in, so a page reload can put\n * them back into it (`RouterCtx` does the restoring). Only OPEN sessions are\n * remembered — a closed one would reopen as a dead transcript — and the\n * pointer is dropped the moment the visitor leaves for a new chat.\n *\n * The boot value is deliberately NOT written: `subscribe` fires on changes\n * only, and clearing on a null we never set would wipe the pointer the\n * restore is about to read.\n */\n private registerActiveSessionPersistence = () => {\n const storageCtx = this.storageCtx;\n if (!storageCtx) return;\n this.stopPersistingSession = this.sessionState.subscribe(\n this.persistSession,\n );\n };\n\n /** Return persistence to the owning widget without overwriting its saved selection. */\n restoreActiveSessionTracking = () => {\n this.stopPersistingSession?.();\n this.stopPersistingSession = undefined;\n this.registerActiveSessionPersistence();\n };\n\n /** Persistence belongs to the selected conversation, never a background response. */\n trackActiveSession = (active: SessionCtx) => {\n this.stopPersistingSession?.();\n this.stopPersistingSession = active.sessionState.subscribe(\n this.persistSession,\n );\n this.persistSession(active.sessionState.get());\n };\n\n private persistSession = ({ session }: SessionState) => {\n const storageCtx = this.storageCtx;\n if (!storageCtx) return;\n const openSessionId = session?.isOpened ? session.id : null;\n if (openSessionId === this.persistedSessionId) return;\n // Nothing to forget until something was remembered.\n if (!openSessionId && this.persistedSessionId === null) return;\n this.persistedSessionId = openSessionId;\n const write = openSessionId\n ? storageCtx.setActiveSessionId(openSessionId)\n : storageCtx.clearActiveSessionId();\n // Storage is an embedder-provided adapter; a broken one must never take\n // the conversation down with it.\n void write.catch((error: unknown) => {\n log.warn('failed to persist the active session', {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n };\n\n /** The conversation the visitor was last in, from a previous page load. */\n getLastActiveSessionId = async (): Promise<string | null> => {\n if (!this.storageCtx) return null;\n try {\n return await this.storageCtx.getActiveSessionId();\n } catch {\n return null;\n }\n };\n\n /** Clears the session and stops polling */\n reset = async () => {\n this.sessionAbortController.abort();\n this.sessionAbortController = new AbortController();\n // Reset the session only, leave sessions as-is\n this.sessionState.reset();\n };\n\n private registerSessionsRefresherWrapper = () => {\n if (\n // If the widget config was initially provided with a contact token, no state change would be triggered, so we just fetch\n this.contactCtx.state.get().contact?.token &&\n !this.sessionsState.get().didStartInitialFetch\n ) {\n this.registerSessionsRefresher();\n } else {\n // In other cases where auto authenticate is fired, the token would be eventually set in state, so we wait for it\n this.stopWaitingForContact = this.contactCtx.state.subscribe(\n ({ contact }) => {\n if (\n contact?.token &&\n !this.sessionsState.get().didStartInitialFetch\n ) {\n this.registerSessionsRefresher();\n }\n },\n );\n }\n };\n\n private registerSessionsRefresher = () => {\n this.sessionsRefresher.startPolling(async () => {\n if (this.sessionsState.get().didStartInitialFetch === false) {\n this.sessionsState.setPartial({ didStartInitialFetch: true });\n }\n\n await this.refreshSessions();\n\n if (this.sessionsState.get().isInitialFetchLoading === true) {\n this.sessionsState.setPartial({ isInitialFetchLoading: false });\n }\n }, this.sessionsPollingIntervalSeconds * 1000);\n };\n\n /** Permanently stop work owned by this runtime. */\n dispose = ({ clearActiveSession = false } = {}) => {\n this.sessionsRefresher.reset();\n this.sessionAbortController.abort();\n this.stopPersistingSession?.();\n this.stopPersistingSession = undefined;\n this.stopWaitingForContact?.();\n this.stopWaitingForContact = undefined;\n this.sessionState.reset();\n if (clearActiveSession && this.storageCtx) {\n this.persistedSessionId = null;\n return this.storageCtx.clearActiveSessionId().catch((error: unknown) => {\n log.warn('failed to clear the replaced session', {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n }\n };\n\n private getParsedCustomData = (): CreateSessionDto['customData'] => {\n return Object.fromEntries<\n NonNullable<CreateSessionDto['customData']>[string]\n >(\n Object.entries(this.config.sessionCustomData || {}).map(\n ([key, value]) => {\n if (typeof value === 'string') return [key, value];\n if (typeof value === 'boolean') return [key, value];\n if (typeof value === 'number') return [key, value];\n // TODO maybe better to unnest instead of stringify-ing\n return [key, runCatching(() => JSON.stringify(value))?.data || ''];\n },\n ),\n );\n };\n\n createSession = async (): Promise<SessionDto | null> => {\n const { signal } = this.sessionAbortController;\n this.sessionState.setPartial({ session: null, isCreatingSession: true });\n try {\n const first = await this.requestSession(signal);\n if (signal.aborted) return null;\n if (first.session) return first.session;\n\n // Self-heal a stale contact token (401): drop it, mint a fresh contact,\n // then retry exactly once.\n if (\n first.status === 401 &&\n (await this.contactCtx.recoverFromStaleToken())\n ) {\n if (signal.aborted) return null;\n const retry = await this.requestSession(signal);\n if (signal.aborted) return null;\n if (retry.session) return retry.session;\n log.error('failed to create session', retry.error);\n return null;\n }\n\n log.error('failed to create session', first.error);\n return null;\n } catch (error) {\n if (!signal.aborted) log.error('failed to create session', error);\n return null;\n } finally {\n if (!signal.aborted)\n this.sessionState.setPartial({ isCreatingSession: false });\n }\n };\n\n /** One create-session request; on success the session is stored and the hook fires. */\n private requestSession = async (\n signal: AbortSignal,\n ): Promise<{\n session: SessionDto | null;\n status: number | undefined;\n error: unknown;\n }> => {\n const externalId = this.contactCtx.state.get().contact?.externalId;\n const customData: CreateSessionDto['customData'] = {\n ...this.getParsedCustomData(),\n ...(externalId ? { external_id: externalId } : {}),\n };\n const {\n data: session,\n error,\n response,\n } = await this.api.createSession(\n {\n customData: Object.keys(customData).length > 0 ? customData : undefined,\n },\n signal,\n );\n if (signal.aborted || !session)\n return { session: null, status: response?.status, error };\n\n this.sessionState.setPartial({ session });\n try {\n this.config.hooks?.onSessionCreated?.({ session });\n } catch (hookError) {\n log.error('onSessionCreated hook failed', hookError);\n }\n return { session, status: response.status, error: undefined };\n };\n\n loadMoreSessions = async () => {\n if (this.sessionsState.get().isLastPage) return;\n\n const { data } = await this.getSessions({\n cursor: this.sessionsState.get().cursor,\n });\n\n if (data) {\n const allSessions = [...this.sessionsState.get().data, ...data.items];\n // TODO sort by updated at\n const deduped = allSessions.filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n\n this.sessionsState.setPartial({\n data: deduped,\n cursor: data.next || undefined,\n isLastPage: data.next === null,\n });\n }\n };\n\n private getSessions = async ({ cursor }: { cursor: string | undefined }) => {\n if (!this.contactCtx.state.get().contact?.token) return { data: null };\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n return await this.api.getSessions({\n cursor,\n filters: externalId\n ? {\n external_id: externalId,\n }\n : {},\n });\n };\n\n setSessions = (data: SessionDto[]) => {\n const sessions = [...data, ...this.sessionsState.get().data].filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n this.sessionsState.setPartial({ data: sessions });\n };\n\n refreshSessions = async () => {\n // Get the first page only (pass no `cursor`)\n const { data } = await this.getSessions({ cursor: undefined });\n if (!data) return;\n this.setSessions(data.items);\n };\n\n resolveSession = async () => {\n const currentSession = this.sessionState.get().session;\n if (!currentSession || !currentSession.isOpened) {\n return { success: false, error: 'Session is not opened' } as const;\n }\n\n this.sessionState.setPartial({ isResolvingSession: true });\n const { signal } = this.sessionAbortController;\n const result = await this.api\n .resolveSession({ session_id: currentSession.id }, signal)\n .catch((error: unknown) => {\n if (signal.aborted) return null;\n throw error;\n });\n if (!result || signal.aborted)\n return { success: false, error: 'Session was reset' } as const;\n const { data: session, error } = result;\n\n if (session) {\n this.sessionState.setPartial({ session, isResolvingSession: false });\n return { success: true, data: session } as const;\n }\n\n this.sessionState.setPartial({ isResolvingSession: false });\n return { success: false, error } as const;\n };\n\n createStateCheckpoint = async (\n payload: Dto['WidgetCreateStateCheckpointInputDto']['payload'],\n ) => {\n const session_id = this.sessionState.get().session?.id;\n if (!session_id) return;\n\n const { data } = await this.api.createStateCheckpoint({\n session_id,\n payload,\n });\n\n if (data?.success) return { success: true } as const;\n\n return { success: false } as const;\n };\n}\n","import { ApiCaller } from '../api/api-caller';\nimport type { WidgetConfig, WidgetMention } from '../types/widget-config';\nimport {\n type MarkedElementRef,\n type WidgetAiMessage,\n type WidgetMessageU,\n type WidgetUserMessage,\n} from '../types/messages';\nimport type {\n MessageAttachmentType,\n SendMessageDto,\n SendMessageOutputDto,\n} from '../types/dtos';\nimport { translate } from '../translation';\nimport { log } from '../utils/log';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport { genUuid } from '../utils/uuid';\nimport { SessionCtx } from './session.ctx';\nimport type { ContactCtx } from './contact.ctx';\n\n/** The shape a caller passes to `sendMessage` (and `stageUserTurn`). */\nexport type SendMessageInput = {\n content: SendMessageDto['content'];\n /** Send agent context without displaying a user bubble. */\n background?: boolean;\n attachments?: SendMessageDto['attachments'];\n customData?: SendMessageDto['custom_data'];\n /**\n * Per-message AI-visible context (e.g. the composer's picked page elements),\n * merged over the config-level `context` on the wire.\n */\n clientContext?: Record<string, unknown>;\n /** Durable lifecycle marker for a connection card handled by this send. */\n connectionRequestId?: string;\n /**\n * What the visitor @-mentioned (host items picked from `config.mentions`).\n * Sent as `clientContext.mentions`.\n */\n mentions?: WidgetMention[];\n /**\n * False when the visitor dismissed the page's entity pill for this message:\n * the send goes out without `context.entity`, everything else intact.\n * @default true\n */\n withPageEntity?: boolean;\n exitModePrompt?: string;\n /**\n * Signals that the send has passed validation, has a session, and is owned\n * by a send engine. This lets composers clear immediately without changing\n * the existing blocking `sendMessage` promise (which still waits for a bot\n * reply). It is lifecycle-only and is never sent over the wire.\n *\n * @internal\n */\n onAccepted?: () => void;\n};\n\n/** What `stageUserTurn` hands the engine that finishes the send. */\nexport type StagedUserTurn = {\n sessionId: string;\n userMessage: WidgetUserMessage;\n /** Persistent greetings riding a fresh conversation's first turn. */\n initialMessages: WidgetAiMessage[];\n};\n\n/**\n * The seam the headless agent-chat provider registers so the shared\n * `sendMessage` entry point routes to its `useChat` streaming engine. Core\n * stays framework-neutral and owns only the blocking bot-chat path plus the\n * shared persisted message list.\n */\nexport type AgentChatHandlers = {\n /** Includes preparation, queued sends, live work and post-turn reconciliation. */\n hasPendingWork?: () => boolean;\n send: (input: SendMessageInput) => Promise<void> | void;\n};\n\n/**\n * The per-message wire context shared by both send engines: the host's\n * config-level `context` (resolved fresh when it is a function) with the\n * widget's own per-send page context merged over it.\n *\n * `sendsPageContext` is `WidgetCtx.features.pageContext` — the org's\n * page-context feature narrowed by the embed. Off → the widget adds nothing\n * of its own (no page marks, no picked elements) but the host's `context`\n * still rides along exactly as it did in v4; `custom_data` is unaffected.\n */\nexport const mergeSendContext = (\n config: WidgetConfig,\n input: SendMessageInput,\n { sendsPageContext }: { sendsPageContext: boolean },\n): {\n clientContext: Record<string, unknown> | undefined;\n custom_data: Record<string, unknown>;\n} => {\n const configContext = resolveConfigContext(config);\n const mentions =\n sendsPageContext && input.mentions && input.mentions.length > 0\n ? { mentions: input.mentions.map(mentionOnTheWire) }\n : undefined;\n const merged =\n sendsPageContext && (input.clientContext || mentions)\n ? { ...configContext, ...input.clientContext, ...mentions }\n : configContext;\n const lifecycleContext = input.connectionRequestId\n ? {\n ...merged,\n opencx__connection_request_id: input.connectionRequestId,\n }\n : merged;\n const context =\n input.withPageEntity === false &&\n lifecycleContext &&\n 'entity' in lifecycleContext\n ? withoutKey(lifecycleContext, 'entity')\n : lifecycleContext;\n return {\n clientContext: input.background\n ? { ...context, opencx__background: true }\n : context,\n custom_data: {\n ...(config.messageCustomData || {}),\n ...(input.customData || {}),\n },\n };\n};\n\n/** A mention as the agent reads it: what identifies it, never the icon. */\nconst mentionOnTheWire = ({ type, id, title, meta }: WidgetMention) => ({\n type,\n id,\n title,\n ...(meta ? { meta } : {}),\n});\n\nconst withoutKey = (\n record: Record<string, unknown>,\n key: string,\n): Record<string, unknown> | undefined => {\n const { [key]: _dropped, ...rest } = record;\n return Object.keys(rest).length > 0 ? rest : undefined;\n};\n\nexport const resolveConfigContext = (\n config: WidgetConfig,\n): Record<string, unknown> | undefined => {\n if (typeof config.context !== 'function') return config.context;\n try {\n return config.context();\n } catch (err) {\n log.error('context getter threw; sending without context', err);\n return undefined;\n }\n};\n\n/** Wire shape of the per-embed feature toggles (`config.features`). */\ntype SendFeaturesBody = NonNullable<SendMessageDto['features']>;\n\n/**\n * `config.features` (camelCase) → the snake_cased `features` field both send\n * engines carry. Undefined when the embedder set nothing, so the body stays\n * byte-identical to before for embeds that never touch the option.\n */\nexport const resolveSendFeatures = (\n config: WidgetConfig,\n): SendFeaturesBody | undefined => {\n const features = config.features;\n if (!features) return undefined;\n const body: SendFeaturesBody = {};\n if (features.preamble !== undefined) body.preamble = features.preamble;\n if (features.inlineUi !== undefined) body.inline_ui = features.inlineUi;\n if (features.pageContext !== undefined) {\n body.page_context = features.pageContext;\n }\n if (features.clientTools !== undefined) {\n body.client_tools = features.clientTools;\n }\n return Object.keys(body).length > 0 ? body : undefined;\n};\n\n/**\n * Everything one send carries on the wire — the SAME body for the blocking\n * send and the streaming turn (both endpoints take `WidgetSendMessageInputDto`).\n * Config is read at call time so function-form `context` and a refreshed\n * embedder config are reflected on every request.\n */\nexport const buildSendMessageBody = ({\n config,\n input,\n uuid,\n sessionId,\n content,\n initialMessages,\n sendsPageContext,\n}: {\n config: WidgetConfig;\n input: SendMessageInput;\n /** The user message's wire id (a retry sends a fresh one). */\n uuid: string;\n sessionId: string;\n /** The rendered user message text (extra collected data already prepended). */\n content: string;\n /** Persistent greetings riding a fresh conversation's first turn. */\n initialMessages: readonly WidgetAiMessage[];\n sendsPageContext: boolean;\n}): SendMessageDto => ({\n uuid,\n bot_token: config.token,\n headers: config.headers,\n query_params: config.queryParams,\n body_properties: config.bodyProperties,\n session_id: sessionId,\n content,\n attachments: input.attachments,\n ...mergeSendContext(config, input, { sendsPageContext }),\n language: config.language,\n features: resolveSendFeatures(config),\n presentation: config.presentation,\n capabilities: [\n config.capabilities?.connections,\n config.capabilities?.structuredQuestions,\n config.capabilities?.richReplies,\n config.capabilities?.pageEffects,\n ].some((value) => value !== undefined)\n ? {\n connections: config.capabilities?.connections,\n structured_questions: config.capabilities?.structuredQuestions,\n rich_replies: config.capabilities?.richReplies,\n page_effects: config.capabilities?.pageEffects,\n }\n : undefined,\n exit_mode_prompt: input.exitModePrompt,\n initial_messages:\n initialMessages.length > 0\n ? initialMessages.map((m) => ({ uuid: m.id, content: m.data.message }))\n : undefined,\n});\n\ntype MessageCtxState = {\n messages: WidgetMessageU[];\n /** Regardless of assignee */\n isSendingMessage: boolean;\n isSendingMessageToAI: boolean;\n /** A completed streamed turn can intentionally leave no assistant row. */\n settledAgentUserMessageId: string | null;\n lastAIResMightSolveUserIssue: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class MessageCtx {\n private config: WidgetConfig;\n private readonly getRequestConfig: () => WidgetConfig;\n private readonly isStreaming: () => boolean;\n private readonly getClientCapabilities: () => WidgetConfig['capabilities'];\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n\n public state = new PrimitiveState<MessageCtxState>({\n messages: [],\n isSendingMessage: false,\n isSendingMessageToAI: false,\n settledAgentUserMessageId: null,\n lastAIResMightSolveUserIssue: false,\n isInitialFetchLoading: false,\n });\n\n /** One reactive draft per conversation, including while its composer is unmounted. */\n public draftState = new PrimitiveState({\n text: '',\n mentions: [] as WidgetMention[],\n });\n\n /**\n * Current transport choice. The org or this embed may request polling\n * independently of the server's agent version.\n */\n public get streaming(): boolean {\n return this.isStreaming();\n }\n\n /**\n * `WidgetCtx.features.pageContext`: whether the widget's own page context\n * (page marks, picked elements) rides along with each message. Off → the\n * user bubble shows no page-mark chips either.\n */\n private readonly getSendsPageContext: () => boolean;\n public get sendsPageContext(): boolean {\n return this.getSendsPageContext();\n }\n\n /** Registered by the headless agent engine for the WidgetProvider lifetime. */\n private agentHandlers: AgentChatHandlers | null = null;\n\n /** Sends issued before the agent-chat surface mounts, oldest first. */\n private bufferedAgentSends: SendMessageInput[] = [];\n\n private sendMessageAbortController = new AbortController();\n\n private messageIdsDispatchedToOnMessageReceivedHook = new Set<string>();\n\n /**\n * Text of messages sent in THIS conversation, oldest first, for the\n * composer's ↑/↓ recall. Lives here rather than in the composer because the\n * quick-ask bar and the full chat composer are different mounts of the same\n * component and recall must survive the morph between them — while staying\n * scoped to one widget instance and one conversation (`reset` clears it, so\n * a new chat never recalls the previous visitor's or session's text).\n * Deliberately NOT part of `state`: nothing renders it, so it must not\n * re-render the transcript on every send.\n */\n private sentTextHistory: string[] = [];\n private static readonly SENT_TEXT_HISTORY_MAX = 50;\n\n constructor({\n config,\n api,\n sessionCtx,\n contactCtx,\n streaming,\n sendsPageContext,\n getClientCapabilities,\n getRequestConfig,\n isStreaming,\n getSendsPageContext,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n sessionCtx: SessionCtx;\n contactCtx: ContactCtx;\n streaming: boolean;\n sendsPageContext: boolean;\n /** Read renderer support at send time; React options may change after initialization. */\n getClientCapabilities?: () => WidgetConfig['capabilities'];\n getRequestConfig?: () => WidgetConfig;\n isStreaming?: () => boolean;\n getSendsPageContext?: () => boolean;\n }) {\n this.config = config;\n this.getClientCapabilities =\n getClientCapabilities ?? (() => this.getRequestConfig().capabilities);\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.contactCtx = contactCtx;\n this.isStreaming = isStreaming ?? (() => streaming);\n this.getRequestConfig = getRequestConfig ?? (() => this.config);\n this.getSendsPageContext = getSendsPageContext ?? (() => sendsPageContext);\n }\n\n reset = () => {\n this.sendMessageAbortController.abort('Resetting chat');\n this.bufferedAgentSends = [];\n this.state.reset();\n this.messageIdsDispatchedToOnMessageReceivedHook.clear();\n this.sentTextHistory = [];\n this.draftState.reset();\n };\n\n /**\n * Record sent text for ↑/↓ recall. Consecutive duplicates collapse — the\n * common case is re-sending the same line after a failure.\n */\n rememberSentText = (text: string): void => {\n const trimmed = text.trim();\n if (!trimmed || this.sentTextHistory.at(-1) === trimmed) return;\n this.sentTextHistory.push(trimmed);\n if (this.sentTextHistory.length > MessageCtx.SENT_TEXT_HISTORY_MAX) {\n this.sentTextHistory.shift();\n }\n };\n\n /** Sent text for this conversation, oldest first. */\n getSentTextHistory = (): readonly string[] => this.sentTextHistory;\n\n /**\n * Wiring for the headless agent engine: WidgetProvider registers its useChat\n * `send` here and clears it on unmount, so every streaming headless or\n * styled consumer shares the same lifecycle. Imperative sends can arrive in\n * the render gap before registration; drain those in FIFO order once ready.\n */\n registerAgentHandlers = (handlers: AgentChatHandlers): void => {\n this.agentHandlers = handlers;\n const buffered = this.bufferedAgentSends;\n this.bufferedAgentSends = [];\n buffered.forEach((input) => {\n MessageCtx.dispatchToEngine(handlers, input);\n });\n };\n\n /** Hand a send to the streaming engine; its failure can never propagate. */\n private static dispatchToEngine(\n handlers: AgentChatHandlers,\n input: SendMessageInput,\n ): void {\n try {\n Promise.resolve(handlers.send(input)).catch((err: unknown) => {\n log.error('streaming send failed', err);\n });\n } catch (err) {\n log.error('streaming send failed', err);\n }\n }\n\n get hasPendingAgentWork(): boolean {\n return (\n this.bufferedAgentSends.length > 0 ||\n (this.agentHandlers?.hasPendingWork?.() ?? false)\n );\n }\n\n unregisterAgentHandlers = (handlers: AgentChatHandlers): void => {\n // Only clear if we still own them — guards a late unmount racing a remount.\n if (this.agentHandlers === handlers) this.agentHandlers = null;\n };\n\n /**\n * Fires `config.hooks.onMessageReceived` for AI or human-agent messages exactly\n * once per id. Safe to call from any path that ingests messages from the server\n * (send-message response, polling, initial history fetch).\n */\n dispatchToOnMessageReceivedHook = (message: WidgetMessageU): void => {\n if (message.type === 'USER') return;\n if (this.messageIdsDispatchedToOnMessageReceivedHook.has(message.id))\n return;\n const session = this.sessionCtx.sessionState.get().session;\n if (!session) return;\n this.messageIdsDispatchedToOnMessageReceivedHook.add(message.id);\n this.config.hooks?.onMessageReceived?.({ message, session });\n };\n\n /**\n * Records the given message ids as already-dispatched without firing the hook.\n * Used to suppress `onMessageReceived` for historical messages that flow in\n * when an existing session is opened — the user is loading context, not\n * receiving new messages. Subsequent polls still dedupe against these ids.\n */\n markAsDispatchedToOnMessageReceivedHook = (messageIds: string[]): void => {\n messageIds.forEach((id) =>\n this.messageIdsDispatchedToOnMessageReceivedHook.add(id),\n );\n };\n\n /**\n * On the very first turn of a fresh conversation, the configured persistent\n * initial messages are inserted into the transcript above the user's first\n * message (and posted to the backend so they persist in history). Any later\n * turn returns an empty array.\n */\n private buildPersistentInitialMessages = (): WidgetAiMessage[] => {\n const shouldInsert =\n !this.sessionCtx.sessionState.get().session?.id &&\n this.state.get().messages.length === 0 &&\n this.config.advancedInitialMessages?.some((m) => m.persistent);\n if (!shouldInsert) return [];\n return (this.config.advancedInitialMessages || [])\n .filter((m) => m.persistent)\n .map(\n (m) =>\n ({\n id: genUuid(),\n component: 'bot_message',\n type: 'AI',\n timestamp: new Date().toISOString(),\n data: { message: m.message },\n agent: this.config.bot\n ? { ...this.config.bot, isAi: true, id: null }\n : undefined,\n }) satisfies WidgetAiMessage,\n );\n };\n\n /**\n * Create the session on the conversation's first send; refreshes the\n * sessions list so the new session shows up immediately. Returns `null`\n * when creation fails.\n */\n private ensureSessionId = async (): Promise<string | null> => {\n if (!this.sessionCtx.sessionState.get().session?.id) {\n const createdSession = await this.sessionCtx.createSession();\n if (!createdSession) return null;\n void this.sessionCtx.refreshSessions();\n }\n return this.sessionCtx.sessionState.get().session?.id ?? null;\n };\n\n /** Remove only this failed attempt's optimistic rows, preserving poll merges. */\n private rollbackOptimisticMessages = (\n messageIds: readonly string[],\n ): void => {\n if (messageIds.length === 0) return;\n const ids = new Set(messageIds);\n const messages = this.state.get().messages;\n const nextMessages = messages.filter((message) => !ids.has(message.id));\n if (nextMessages.length !== messages.length) {\n this.state.setPartial({ messages: nextMessages });\n }\n };\n\n /**\n * Fire the caller's `onAccepted` once a send is validated, has a session,\n * and is owned by an engine. A consumer callback must never be able to\n * break an accepted send.\n */\n notifySendAccepted = (input: SendMessageInput): void => {\n try {\n input.onAccepted?.();\n } catch (error) {\n log.error('send acceptance callback failed', error);\n }\n };\n\n /**\n * The front half every send shares, whichever engine finishes it: validate,\n * build the user message (plus the persistent greetings on a fresh\n * conversation's first turn), render it optimistically, and make sure a\n * session exists — rolling the optimistic rows back if it cannot. Returns\n * `null` when there is nothing to send or no session could be created.\n */\n stageUserTurn = async (\n input: SendMessageInput,\n { pending }: { pending: boolean },\n ): Promise<StagedUserTurn | null> => {\n const built = this.buildUserMessage(input);\n if (!built) return null;\n const userMessage = pending ? { ...built, pending: true } : built;\n\n const initialMessages = this.buildPersistentInitialMessages();\n const optimisticMessageIds = [\n ...initialMessages.map((message) => message.id),\n userMessage.id,\n ];\n this.state.setPartial({\n messages: [\n ...initialMessages,\n ...this.state.get().messages,\n ...(userMessage.background ? [] : [userMessage]),\n ],\n });\n\n let sessionId: string | null;\n try {\n sessionId = await this.ensureSessionId();\n } catch (error) {\n this.rollbackOptimisticMessages(optimisticMessageIds);\n throw error;\n }\n if (!sessionId) {\n this.rollbackOptimisticMessages(optimisticMessageIds);\n return null;\n }\n return { sessionId, userMessage, initialMessages };\n };\n\n /**\n * Build the user message for a QUEUED (multi-send) turn WITHOUT rendering\n * it into the transcript. A queued message must not appear above the still-\n * streaming response of the active turn — the surface renders it below the\n * live overlay (dimmed via `pending`) and only `appendUserMessageIfAbsent`s\n * it into `messages` when its own turn actually starts (see `useAgentChat`).\n * A session already exists here (a turn is in flight), so this never creates\n * one.\n */\n buildQueuedUserMessage = (\n input: SendMessageInput,\n ): { sessionId: string; userMessage: WidgetUserMessage } | null => {\n const built = this.buildUserMessage(input);\n if (!built) return null;\n const sessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!sessionId) return null;\n return { sessionId, userMessage: { ...built, pending: true } };\n };\n\n /** Validate the input and build its user message; `null` when empty. */\n private buildUserMessage = (\n input: SendMessageInput,\n ): WidgetUserMessage | null => {\n if (\n !input.content.trim() &&\n (!input.attachments || input.attachments.length === 0)\n ) {\n log.warn('cannot send an empty message of no content or attachments');\n return null;\n }\n return {\n ...this.toUserMessage(\n input.content.trim(),\n input.attachments || undefined,\n this.sendsPageContext\n ? MessageCtx.markedElementNames(input.clientContext)\n : undefined,\n this.sendsPageContext && input.mentions?.length\n ? input.mentions\n : undefined,\n ),\n ...(input.background ? { background: true } : {}),\n };\n };\n\n /**\n * Defensive read of `clientContext.page_marks` → the user bubble's context\n * chips: each mark contributes the element it was placed on, the note the\n * visitor wrote, and a reference back to the mark itself (the UI renders\n * the same presentation the composer showed, thumbnail included). Entries\n * without a usable name are dropped.\n */\n private static markedElementNames(\n clientContext: Record<string, unknown> | undefined,\n ): MarkedElementRef[] | undefined {\n const raw = clientContext?.['page_marks'];\n if (!Array.isArray(raw)) return undefined;\n const marked = raw.flatMap((mark: unknown): MarkedElementRef[] => {\n if (typeof mark !== 'object' || mark === null) return [];\n const elements: unknown = (mark as { elements?: unknown }).elements;\n const first = Array.isArray(elements) ? elements[0] : undefined;\n const name: unknown =\n typeof first === 'object' && first !== null && 'name' in first\n ? (first as { name: unknown }).name\n : undefined;\n if (typeof name !== 'string' || name.length === 0) return [];\n const note: unknown = (mark as { note?: unknown }).note;\n const snapshotUrl: unknown = (mark as { snapshotUrl?: unknown })\n .snapshotUrl;\n return [\n {\n name,\n ...(typeof note === 'string' && note.length > 0 ? { note } : {}),\n ...(typeof snapshotUrl === 'string' && snapshotUrl.length > 0\n ? { snapshotUrl }\n : {}),\n mark,\n },\n ];\n });\n return marked.length > 0 ? marked : undefined;\n }\n\n /** Append a user message to the transcript once, ignoring a duplicate id. */\n appendUserMessageIfAbsent = (userMessage: WidgetUserMessage): void => {\n if (userMessage.background) return;\n const messages = this.state.get().messages;\n if (messages.some((m) => m.id === userMessage.id)) return;\n this.state.setPartial({ messages: [...messages, userMessage] });\n };\n\n /**\n * Clear the `pending` flag for the user message owned by one streamed turn.\n * Later queued bubbles must remain pending until their own turn reaches the\n * server.\n */\n markUserMessageDelivered = (messageId: string): void => {\n const messages = this.state.get().messages;\n const index = messages.findIndex(\n (message) =>\n message.id === messageId && message.type === 'USER' && message.pending,\n );\n if (index === -1) return;\n const delivered = messages[index];\n if (!delivered || delivered.type !== 'USER') return;\n const nextMessages = [...messages];\n nextMessages[index] = { ...delivered, pending: false };\n this.state.setPartial({\n messages: nextMessages,\n });\n };\n\n /**\n * The blocking engine refuses a send while the AI reply is pending unless\n * the embed opted out. The streaming engine never blocks (it queues).\n */\n get blocksSendWhileAwaitingReply(): boolean {\n return (\n !this.streaming && this.config.disableSendingWhenAwaitingAIReply !== false\n );\n }\n\n sendMessage = async (input: SendMessageInput): Promise<void> => {\n // Streaming: the headless useChat engine owns the whole turn lifecycle\n // (optimistic render, streaming, interrupt-send, stop). An imperative\n // `newChat({ message })` can send before that surface's mount effect, so\n // retain the input until handlers register instead of dropping it.\n if (this.streaming) {\n if (!this.agentHandlers) {\n this.bufferedAgentSends.push(input);\n return;\n }\n await this.agentHandlers.send(input);\n return;\n }\n\n let localAbortController: AbortController | undefined;\n try {\n /* ------------------------------------------------------ */\n /* Prevent sending while waiting for AI res */\n /* ------------------------------------------------------ */\n const session = this.sessionCtx.sessionState.get().session;\n const assignee = session?.assignee.kind;\n const isAssignedToAI = assignee === 'ai';\n const isSendingToAI = this.state.get().isSendingMessageToAI;\n const lastMessage = this.state.get().messages.at(-1);\n\n if (\n this.blocksSendWhileAwaitingReply &&\n (isSendingToAI ||\n // If last message is from user, then bot response did not arrive yet\n (isAssignedToAI &&\n lastMessage?.type === 'USER' &&\n lastMessage.id !== this.state.get().settledAgentUserMessageId))\n ) {\n log.warn('cannot send messages while awaiting AI response');\n return;\n }\n\n /* ------------------------------------------------------ */\n /* Start */\n /* ------------------------------------------------------ */\n // Abort any prior in-flight send so only the latest call is awaited.\n // We rely on aggressive polling to recover any messages whose responses\n // we drop here.\n this.sendMessageAbortController.abort('Superseded by a newer message');\n this.sendMessageAbortController = new AbortController();\n localAbortController = this.sendMessageAbortController;\n this.state.setPartial({\n lastAIResMightSolveUserIssue: false,\n isSendingMessage: true,\n isSendingMessageToAI: !!isAssignedToAI || !session,\n });\n\n const staged = await this.stageUserTurn(input, { pending: false });\n if (!staged) return;\n const { sessionId, userMessage, initialMessages } = staged;\n this.notifySendAccepted(input);\n /* ------------------------------------------------------ */\n /* Send and wait for bot response */\n /* ------------------------------------------------------ */\n const { data } = await this.api.sendMessage(\n buildSendMessageBody({\n config: {\n ...this.getRequestConfig(),\n capabilities: this.getClientCapabilities(),\n },\n input,\n uuid: userMessage.id,\n sessionId,\n content: userMessage.content,\n initialMessages,\n sendsPageContext: this.sendsPageContext,\n }),\n localAbortController.signal,\n );\n\n if (data?.success) {\n /* ------------------------------------------------------ */\n /* Append bot reply if not fetched from polling */\n /* ------------------------------------------------------ */\n const botMessage = this.toBotMessage(data);\n if (botMessage) {\n const prevMessages = this.state.get().messages;\n const shouldAppend = !prevMessages.some(\n (m) => m.id === botMessage.id,\n );\n if (!shouldAppend) {\n this.state.setPartial({\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n return;\n }\n this.state.setPartial({\n messages: [...prevMessages, botMessage],\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n this.dispatchToOnMessageReceivedHook(botMessage);\n }\n if (data.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n }\n } else {\n const errorMessage = this.toBotErrorMessage(\n data?.error?.message || translate(this.config, 'turn_failed_message'),\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, errorMessage],\n });\n }\n } catch (error) {\n if (!localAbortController?.signal.aborted) {\n log.error('failed to send message', error);\n }\n } finally {\n // If our local controller was aborted, a newer send has taken over —\n // don't clear the in-flight flags out from under it.\n if (!localAbortController?.signal.aborted) {\n this.state.setPartial({\n isSendingMessage: false,\n isSendingMessageToAI: false,\n });\n }\n }\n };\n\n private toUserMessage = (\n content: string,\n attachments?: MessageAttachmentType[],\n markedElements?: MarkedElementRef[],\n mentions?: WidgetMention[],\n ): WidgetUserMessage => {\n const messageContent = (() => {\n const extraCollectedData = this.contactCtx.state.get().extraCollectedData;\n // Prepend extra collected data if this is the first message in the session\n if (\n this.state.get().messages.length === 0 &&\n extraCollectedData &&\n Object.keys(extraCollectedData).length > 0\n ) {\n const data = Object.entries(extraCollectedData)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => `${key}: ${value}`)\n .join(' \\n');\n return `${data} \\n\\n${content}`;\n }\n\n return content;\n })();\n\n return {\n id: genUuid(),\n type: 'USER',\n content: messageContent,\n attachments,\n markedElements,\n mentions,\n timestamp: new Date().toISOString(),\n };\n };\n\n private toBotMessage = (\n response: SendMessageOutputDto,\n ): WidgetAiMessage | null => {\n if (response.success && response.autopilotResponse) {\n return {\n type: 'AI',\n id: response.autopilotResponse.id || genUuid(),\n timestamp: new Date().toISOString(),\n component: 'bot_message',\n agent: this.config.bot\n ? {\n name: this.config.bot.name || '',\n isAi: true,\n // Do not set avatarUrl here... let it be taken from the config at render time\n avatarUrl: null,\n avatar: null,\n id: null,\n }\n : undefined,\n data: {\n message: response.autopilotResponse.value.content,\n action: response.uiResponse?.value.name\n ? {\n name: response.uiResponse.value.name,\n data: response.uiResponse.value.request_response,\n }\n : undefined,\n },\n };\n }\n\n return null;\n };\n\n private toBotErrorMessage = (message: string): WidgetAiMessage => {\n return {\n type: 'AI',\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: 'bot_message',\n data: {\n message,\n variant: 'error',\n action: undefined,\n },\n };\n };\n}\n","import type { SessionDto } from '../types/dtos';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { PrimitiveState } from '../utils/PrimitiveState';\nimport type { ContactCtx } from './contact.ctx';\nimport type { SessionCtx } from './session.ctx';\nimport type { WidgetCtx } from './widget.ctx';\n\nexport type ScreenU =\n | /** A welcome screen to collect user data. Useful in public non-logged-in environments */\n 'welcome'\n /** Show a list of the user's previous sessions */\n | 'sessions'\n /** Self-explanatory */\n | 'chat';\n\ntype RouterState = {\n screen: ScreenU;\n};\n\nexport class RouterCtx {\n state: PrimitiveState<RouterState>;\n private subscriptions: Array<() => void> = [];\n private disposed = false;\n\n private config: WidgetConfig;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n private resetChat: WidgetCtx['resetChat'];\n /**\n * Whether a reload returns the visitor to the conversation they were in.\n * Off by default: the home screen is the sessions list. Embedders whose\n * widget is a continuous assistant (an empty panel beside a live\n * conversation reads as data loss) opt in via `router.restoreLastSession`.\n */\n private readonly shouldRestoreLastSession: boolean;\n /** The stored pointer, until it is used or found unusable. */\n private restorableSessionId: string | null = null;\n /** Has the (async) storage read settled? Automatic routing waits for it. */\n private didReadStoredSession = false;\n\n constructor(private widget: WidgetCtx) {\n this.config = widget.config;\n this.contactCtx = widget.contactCtx;\n this.sessionCtx = widget.sessionCtx;\n this.resetChat = widget.resetChat;\n this.state = new PrimitiveState<RouterState>({\n screen: this.contactCtx.shouldCollectData()\n ? 'welcome'\n : this.config.router?.chatScreenOnly\n ? 'chat'\n : 'sessions',\n });\n this.shouldRestoreLastSession =\n this.config.router?.restoreLastSession ?? false;\n\n this.readStoredSession();\n this.registerRoutingListener();\n }\n\n /**\n * Read the remembered conversation before any automatic routing runs. The\n * read is async (the storage adapter may be), and the sessions list can land\n * first — so routing is re-run once the pointer is known.\n */\n private readStoredSession = () => {\n if (!this.shouldRestoreLastSession) {\n this.didReadStoredSession = true;\n return;\n }\n void this.sessionCtx\n .getLastActiveSessionId()\n .then((sessionId) => {\n this.restorableSessionId = sessionId;\n })\n .finally(() => {\n this.didReadStoredSession = true;\n this.routeFromSessions(this.sessionCtx.sessionsState.get());\n });\n };\n\n private registerRoutingListener = () => {\n this.subscriptions.push(\n this.contactCtx.state.subscribe(({ contact }) => {\n // Auto navigate to sessions screen after collecting user data\n if (contact?.token && this.state.get().screen === 'welcome') {\n this.state.setPartial({\n screen: this.config.router?.chatScreenOnly ? 'chat' : 'sessions',\n });\n }\n }),\n );\n\n this.subscriptions.push(\n this.sessionCtx.sessionsState.subscribe(this.routeFromSessions),\n );\n };\n\n /**\n * Every automatic route the sessions list can trigger, in one place so the\n * restore can re-run it once the stored pointer is known.\n */\n private routeFromSessions = ({\n isInitialFetchLoading,\n data,\n }: {\n isInitialFetchLoading: boolean;\n data: SessionDto[];\n }) => {\n // Hold automatic routing until we know whether there is a conversation to\n // return to: routing first and restoring second would flash the wrong\n // screen, or start a second conversation beside the live one.\n if (this.disposed || !this.didReadStoredSession) return;\n\n if (\n this.restorableSessionId &&\n !this.sessionCtx.sessionState.get().session?.id\n ) {\n const restored = data.find(\n (s) => s.id === this.restorableSessionId && s.isOpened,\n );\n if (restored) {\n this.restorableSessionId = null;\n this.toChatScreen(restored.id);\n return;\n }\n // Not in the list yet — the first page may still be loading. Once it has\n // landed, a pointer with no open session behind it (closed elsewhere,\n // deleted, another contact) is stale: drop it and route normally.\n if (isInitialFetchLoading) return;\n this.restorableSessionId = null;\n }\n\n if (\n this.config.router?.chatScreenOnly &&\n // Do not route to a chat if we are currently inside one already\n // This also applies to newly created sessions; the new session will be in `sessionState` before it is refreshed and included in `sessionsState`\n !this.sessionCtx.sessionState.get().session?.id\n ) {\n const mostRecentOpenSessionId = data.find((s) => s.isOpened)?.id;\n return mostRecentOpenSessionId\n ? this.toChatScreen(mostRecentOpenSessionId)\n : undefined;\n }\n\n if (data.length) return;\n if (this.config.router?.goToChatIfNoSessions === false) return;\n\n // Auto navigate to chat screen if contact has no previous sessions\n if (!isInitialFetchLoading && this.state.get().screen !== 'chat') {\n this.toChatScreen();\n }\n };\n\n dispose = () => {\n this.disposed = true;\n this.subscriptions.forEach((unsubscribe) => unsubscribe());\n this.subscriptions = [];\n this.navigateConversation = undefined;\n };\n\n /** A multi-chat host owns navigation without resetting background sends. */\n navigateConversation?: (sessionId?: string) => WidgetCtx | undefined;\n\n toSessionsScreen = () => {\n if (!this.navigateConversation) this.resetChat();\n this.state.setPartial({ screen: 'sessions' });\n };\n\n /**\n * @param sessionId The ID of the session to open, or `undefined` if it is a new chat session\n */\n toChatScreen = (sessionId?: string): WidgetCtx | undefined => {\n if (this.navigateConversation) return this.navigateConversation(sessionId);\n this.resetChat();\n\n let session: SessionDto | undefined;\n\n if (sessionId) {\n session = this.sessionCtx.sessionsState\n .get()\n .data.find((s) => s.id === sessionId);\n // Do not navigate if session is not found (this shouldn't happen, unless a wrong ID is passed)\n if (!session) return;\n this.sessionCtx.sessionState.setPartial({ session });\n }\n\n this.state.setPartial({ screen: 'chat' });\n\n this.config.hooks?.onNavigateToChat?.({ session });\n return this.widget;\n };\n}\n","import type { ExternalStorage } from '../types/external-storage';\nimport type {\n WidgetCompanionDefaultLayoutU,\n WidgetConfig,\n WidgetSidebarModeU,\n} from '../types/widget-config';\nimport type { WidgetSidebarSideResolvedU } from '../utils/companion-layout';\n\n/** The per-visitor companion preferences the widget remembers between visits. */\ntype CompanionPreferenceU =\n | 'pill-offset-x'\n | 'sidebar-width'\n | 'sidebar-side'\n | 'sidebar-mode'\n | 'layout';\n\nexport class StorageCtx {\n private storage: ExternalStorage;\n private config: WidgetConfig;\n\n private KEYS = {\n contactToken: (orgToken: string) =>\n `opencx-widget:org-token-${orgToken}:contact-token`,\n externalContactId: (orgToken: string) =>\n `opencx-widget:org-token-${orgToken}:external-contact-id`,\n companionPreference: (orgToken: string, preference: CompanionPreferenceU) =>\n `opencx-widget:org-token-${orgToken}:companion-${preference}`,\n activeSession: (orgToken: string) =>\n `opencx-widget:org-token-${orgToken}:active-session`,\n };\n\n constructor({\n storage,\n config,\n }: {\n storage: ExternalStorage;\n config: WidgetConfig;\n }) {\n this.storage = storage;\n this.config = config;\n }\n\n setContactToken = async (token: string) => {\n await this.storage.set(this.KEYS.contactToken(this.config.token), token);\n };\n getContactToken = async () => {\n return this.storage.get(this.KEYS.contactToken(this.config.token));\n };\n clearContactToken = async () => {\n await this.storage.remove(this.KEYS.contactToken(this.config.token));\n };\n\n /**\n * The conversation the visitor was last in. Only a POINTER lives here — the\n * messages themselves are on the backend — but without it a page reload\n * drops the visitor into an empty composer beside a conversation that is\n * still very much alive.\n */\n private activeSessionKey = (): string =>\n this.KEYS.activeSession(this.config.token);\n\n getActiveSessionId = async (): Promise<string | null> => {\n return this.storage.get(this.activeSessionKey());\n };\n setActiveSessionId = async (sessionId: string): Promise<void> => {\n await this.storage.set(this.activeSessionKey(), sessionId);\n };\n clearActiveSessionId = async (): Promise<void> => {\n await this.storage.remove(this.activeSessionKey());\n };\n\n setExternalContactId = async (id: string) => {\n await this.storage.set(this.KEYS.externalContactId(this.config.token), id);\n };\n getExternalContactId = async () => {\n return this.storage.get(this.KEYS.externalContactId(this.config.token));\n };\n\n private companionKey = (preference: CompanionPreferenceU): string =>\n this.KEYS.companionPreference(this.config.token, preference);\n\n private getFiniteNumber = async (key: string): Promise<number | null> => {\n const raw = await this.storage.get(key);\n if (raw === null) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n };\n\n getCompanionPillOffsetX = async (): Promise<number | null> =>\n this.getFiniteNumber(this.companionKey('pill-offset-x'));\n\n setCompanionPillOffsetX = async (offset: number): Promise<void> => {\n if (!Number.isFinite(offset)) return;\n await this.storage.set(this.companionKey('pill-offset-x'), String(offset));\n };\n\n getCompanionSidebarWidth = async (): Promise<number | null> =>\n this.getFiniteNumber(this.companionKey('sidebar-width'));\n\n setCompanionSidebarWidth = async (width: number): Promise<void> => {\n if (!Number.isFinite(width)) return;\n await this.storage.set(this.companionKey('sidebar-width'), String(width));\n };\n\n /**\n * The visitor's own sidebar side/mode, once they have picked one in the\n * layout menu. Absent until then, so `companion.sidebar.*` config keeps\n * deciding for a visitor who never touched the control. Unrecognized stored\n * values read as absent rather than poisoning the layout.\n */\n getCompanionSidebarSide =\n async (): Promise<WidgetSidebarSideResolvedU | null> => {\n const raw = await this.storage.get(this.companionKey('sidebar-side'));\n return raw === 'left' || raw === 'right' ? raw : null;\n };\n\n setCompanionSidebarSide = async (\n side: WidgetSidebarSideResolvedU,\n ): Promise<void> => {\n await this.storage.set(this.companionKey('sidebar-side'), side);\n };\n\n /**\n * The RESTING layout the visitor last picked in the layout menu. Absent\n * until they pick one, so `companion.defaultLayout` keeps deciding for a\n * visitor who never touched the control.\n *\n * `fullscreen` is deliberately unstorable: it is a mode the visitor enters\n * on top of a resting layout (Escape drops back out of it), so persisting\n * it would reopen every future visit full-screen over the host page.\n */\n getCompanionLayout =\n async (): Promise<WidgetCompanionDefaultLayoutU | null> => {\n const raw = await this.storage.get(this.companionKey('layout'));\n return raw === 'compact' || raw === 'sidebar' ? raw : null;\n };\n\n setCompanionLayout = async (\n layout: WidgetCompanionDefaultLayoutU,\n ): Promise<void> => {\n await this.storage.set(this.companionKey('layout'), layout);\n };\n\n getCompanionSidebarMode = async (): Promise<WidgetSidebarModeU | null> => {\n const raw = await this.storage.get(this.companionKey('sidebar-mode'));\n return raw === 'docked' || raw === 'floating' ? raw : null;\n };\n\n setCompanionSidebarMode = async (mode: WidgetSidebarModeU): Promise<void> => {\n await this.storage.set(this.companionKey('sidebar-mode'), mode);\n };\n}\n","import type { Dto } from '../api/client';\nimport type { WidgetConfig } from '../types/widget-config';\n\n/**\n * The org's agent as the embed sees it: branding, which engine serves the\n * web channel, and the features the CLIENT acts on. Features the server\n * applies on its own (preamble, inline UI) are not mirrored here — the embed\n * only forwards its toggles for those (see `resolveSendFeatures`).\n */\nexport type WidgetAgent = {\n name: string;\n avatarUrl: string | null;\n /**\n * The org's web channel runs the streaming engine (widget v5). `false`\n * means the classic blocking send.\n */\n streaming: boolean;\n /** Optional on older backends; controls the maximum visible tool detail. */\n presentation?: Dto['WidgetPresentationDto'];\n /** The org's EFFECTIVE features (entitlements already applied). */\n features: {\n dictation: boolean;\n attachments: boolean;\n pageContext: boolean;\n clientTools: boolean;\n };\n};\n\ntype ServerAgent = Dto['WidgetAgentDto'];\n\n/**\n * snake_case (backend DTO) → camelCase (widget types) at the boundary.\n *\n * A backend that predates widget v5 returns no `agent` block. Preserve its\n * blocking send and attachment support when an embed is upgraded first.\n */\nexport function resolveWidgetAgent({\n org,\n agent,\n}: {\n org: { name: string };\n agent?: ServerAgent | null;\n}): WidgetAgent {\n if (!agent) {\n return {\n name: org.name,\n avatarUrl: null,\n streaming: false,\n features: {\n dictation: false,\n attachments: true,\n pageContext: false,\n clientTools: false,\n },\n };\n }\n return {\n name: agent.name,\n avatarUrl: agent.avatar_url,\n streaming: agent.streaming,\n ...(agent.presentation ? { presentation: agent.presentation } : {}),\n features: {\n dictation: agent.features.dictation,\n attachments: agent.features.attachments,\n pageContext: agent.features.page_context,\n clientTools: agent.features.client_tools,\n },\n };\n}\n\n/**\n * The one narrowing rule for every per-embed feature toggle: the org's\n * effective feature can only be switched OFF by `config.features`, never on.\n */\nfunction narrowFeature(\n orgEnabled: boolean,\n embedToggle: boolean | undefined,\n): boolean {\n return orgEnabled && embedToggle !== false;\n}\n\n/** The client-side feature answers the UI asks for, narrowed by the embed. */\nexport function resolveClientFeatures(\n agent: WidgetAgent,\n config: WidgetConfig,\n): {\n /** The composer offers voice dictation. */\n dictation: boolean;\n /** The composer offers the attachment/upload affordance. */\n attachments: boolean;\n /**\n * The visitor can mark the page (the composer's page-mark button) and the\n * widget's own page context rides along with each message. The host's\n * `config.context` is unaffected — it always rides along, as it did in v4.\n */\n pageContext: boolean;\n /**\n * The widget performs the agent's client tools (highlight an element on\n * the host page).\n */\n clientTools: boolean;\n} {\n const toggles = config.features;\n return {\n dictation: narrowFeature(agent.features.dictation, toggles?.dictation),\n attachments: agent.features.attachments,\n pageContext: narrowFeature(\n agent.features.pageContext,\n toggles?.pageContext,\n ),\n clientTools: narrowFeature(\n agent.features.clientTools,\n toggles?.clientTools,\n ),\n };\n}\n\nexport type WidgetClientFeatures = ReturnType<typeof resolveClientFeatures>;\n","import { ApiCaller } from '../api/api-caller';\nimport type { ModeDto } from '../types/dtos';\nimport type { ExternalStorage } from '../types/external-storage';\nimport type { WidgetConfig } from '../types/widget-config';\nimport { ActiveSessionPollingCtx } from './active-session-polling.ctx';\nimport { ContactCtx } from './contact.ctx';\nimport { UploadCtx } from './upload.ctx';\nimport { CsatCtx } from './csat.ctx';\nimport { DictationCtx } from './dictation.ctx';\nimport { MessageCtx } from './message.ctx';\nimport { RouterCtx } from './router.ctx';\nimport { SessionCtx } from './session.ctx';\nimport { StorageCtx } from './storage.ctx';\nimport {\n resolveClientFeatures,\n resolveWidgetAgent,\n type WidgetAgent,\n type WidgetClientFeatures,\n} from './widget-agent';\nimport { log } from '../utils/log';\n\n/** A configuration failure that prevents the widget from choosing a safe\n * runtime. The code is stable so headless consumers can render their own\n * recovery UI without matching error-message text. */\nexport class WidgetInitializationError extends Error {\n readonly code: 'config-fetch-failed';\n readonly details: unknown;\n\n constructor(code: 'config-fetch-failed', message: string, details?: unknown) {\n super(message);\n this.name = 'WidgetInitializationError';\n this.code = code;\n this.details = details;\n }\n}\n\nexport class WidgetCtx {\n public config: WidgetConfig;\n public api: ApiCaller;\n\n public contactCtx: ContactCtx;\n public sessionCtx: SessionCtx;\n public messageCtx: MessageCtx;\n public csatCtx: CsatCtx;\n public uploadCtx: UploadCtx;\n public dictationCtx: DictationCtx;\n public routerCtx: RouterCtx;\n public storageCtx?: StorageCtx;\n public modes: ModeDto[] = [];\n\n public org: {\n id: string;\n name: string;\n };\n /**\n * The org's agent — branding plus which engine serves it — resolved by the\n * backend at init. The `bot` option overrides the branding at render time.\n */\n public readonly agent: WidgetAgent;\n\n /**\n * Choose the transport from the org's default and the current embed opt-out.\n * The backend chooses the agent version independently of this transport.\n */\n private readonly getRequestConfig: () => WidgetConfig;\n private readonly getClientCapabilities?: () => WidgetConfig['capabilities'];\n\n public get streaming(): boolean {\n // Accepted sends keep their transport through preparation, queue draining\n // and reconciliation. Never let a prop update detach their owner.\n if (this.messageCtx?.hasPendingAgentWork) return true;\n if (this.messageCtx?.state.get().isSendingMessage) return false;\n return this.agent.streaming && this.getRequestConfig().streaming !== false;\n }\n\n /**\n * The org's features narrowed by this embed's `config.features` — the\n * answers the UI asks for, resolved against the current options.\n */\n public get features(): WidgetClientFeatures {\n return resolveClientFeatures(this.agent, this.getRequestConfig());\n }\n\n private static pollingIntervalsSeconds: {\n session: number;\n sessions: number;\n } | null = null;\n private activeSessionPollingCtx: ActiveSessionPollingCtx;\n private disposed = false;\n\n private constructor({\n config,\n storage,\n getClientCapabilities,\n getRequestConfig,\n modes,\n org,\n agent,\n parent,\n }: {\n config: WidgetConfig;\n storage?: ExternalStorage;\n getClientCapabilities?: () => WidgetConfig['capabilities'];\n getRequestConfig?: () => WidgetConfig;\n modes: ModeDto[];\n org: {\n id: string;\n name: string;\n };\n agent: WidgetAgent;\n parent?: WidgetCtx;\n }) {\n if (!WidgetCtx.pollingIntervalsSeconds) {\n throw Error(\n 'Widget polling values are not defined, did you call WidgetCtx.initialize()',\n );\n }\n\n this.config = config;\n this.getRequestConfig = getRequestConfig ?? (() => this.config);\n this.getClientCapabilities = getClientCapabilities;\n this.org = org;\n this.agent = agent;\n this.api = parent?.api ?? new ApiCaller({ config });\n this.storageCtx =\n parent?.storageCtx ??\n (storage ? new StorageCtx({ storage, config }) : undefined);\n this.modes = modes;\n\n this.contactCtx =\n parent?.contactCtx ??\n new ContactCtx({\n api: this.api,\n config: this.config,\n storageCtx: this.storageCtx,\n });\n\n this.sessionCtx = new SessionCtx({\n config: this.config,\n api: this.api,\n contactCtx: this.contactCtx,\n // Remembers the open conversation so a reload can return to it.\n storageCtx: parent ? undefined : this.storageCtx,\n sharedSessions: parent?.sessionCtx.sessionsState,\n sessionsPollingIntervalSeconds:\n WidgetCtx.pollingIntervalsSeconds.sessions,\n });\n\n this.messageCtx = new MessageCtx({\n config: this.config,\n api: this.api,\n sessionCtx: this.sessionCtx,\n contactCtx: this.contactCtx,\n // Streaming orgs send their turns over the AI SDK transport instead of\n // the blocking bot-chat send.\n streaming: this.streaming,\n isStreaming: () => this.streaming,\n sendsPageContext: this.features.pageContext,\n getSendsPageContext: () => this.features.pageContext,\n getClientCapabilities,\n getRequestConfig,\n });\n\n this.uploadCtx = new UploadCtx(this.api);\n this.csatCtx = new CsatCtx({\n api: this.api,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n });\n\n this.dictationCtx = new DictationCtx({\n api: this.api,\n config: this.config,\n });\n\n this.activeSessionPollingCtx = new ActiveSessionPollingCtx({\n api: this.api,\n config: this.config,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n sessionPollingIntervalSeconds: WidgetCtx.pollingIntervalsSeconds.session,\n });\n\n this.routerCtx = new RouterCtx(this);\n }\n\n static initialize = async ({\n config,\n storage,\n getClientCapabilities,\n getRequestConfig,\n }: {\n config: WidgetConfig;\n storage?: ExternalStorage;\n getClientCapabilities?: () => WidgetConfig['capabilities'];\n getRequestConfig?: () => WidgetConfig;\n }) => {\n const externalConfig = await new ApiCaller({\n config,\n }).getExternalWidgetConfig();\n\n if (!externalConfig.data) {\n // Surface the backend's reason instead of failing mutely.\n log.error('widget config fetch failed', externalConfig.error);\n throw new WidgetInitializationError(\n 'config-fetch-failed',\n 'Failed to fetch widget config',\n externalConfig.error,\n );\n }\n\n this.pollingIntervalsSeconds = {\n session: externalConfig.data?.sessionPollingIntervalSeconds || 10,\n sessions: externalConfig.data?.sessionsPollingIntervalSeconds || 60,\n };\n\n return new WidgetCtx({\n config,\n storage,\n getClientCapabilities,\n getRequestConfig,\n modes: externalConfig.data.modes || [],\n org: {\n id: externalConfig.data.org.id,\n name: externalConfig.data.org.name,\n },\n agent: resolveWidgetAgent(externalConfig.data),\n });\n };\n\n /** Independent send/history lifecycle, sharing the authenticated visitor and session list. */\n createConversation = (): WidgetCtx => {\n const conversation = new WidgetCtx({\n config: {\n ...this.config,\n router: {\n ...this.config.router,\n restoreLastSession: false,\n chatScreenOnly: false,\n goToChatIfNoSessions: false,\n },\n },\n modes: this.modes,\n org: this.org,\n agent: this.agent,\n parent: this,\n getRequestConfig: this.getRequestConfig,\n getClientCapabilities: this.getClientCapabilities,\n });\n conversation.routerCtx.state.setPartial({\n screen: this.contactCtx.shouldCollectData() ? 'welcome' : 'chat',\n });\n return conversation;\n };\n\n /** Release a closed companion runtime after its last send has settled. */\n releaseConversation = () => this.dispose();\n\n /** Permanently stop all polling, subscriptions and in-flight work. */\n dispose = ({ clearActiveSession = false } = {}) => {\n if (this.disposed) return;\n this.disposed = true;\n this.routerCtx.dispose();\n this.activeSessionPollingCtx.dispose();\n const cleanup = this.sessionCtx.dispose({ clearActiveSession });\n this.messageCtx.reset();\n this.uploadCtx.reset();\n this.dictationCtx.stop();\n return cleanup;\n };\n\n resetChat = () => {\n this.sessionCtx.reset();\n this.messageCtx.reset();\n this.uploadCtx.reset();\n };\n\n /**\n * Ingest the canonical rows the backend persisted for a streamed turn.\n * Called by the agent-chat surface when a turn finishes; the polling\n * context owns history mapping/dedupe, so this delegates to it.\n */\n reconcileAfterStream = (sessionId: string): Promise<void> =>\n this.activeSessionPollingCtx.reconcileAfterStream(sessionId);\n}\n","import type { WidgetAgent } from './widget-agent';\nimport type { WidgetConfig } from '../types/widget-config';\n\n/** The embed may hide more activity, but cannot reveal details the org hides. */\nexport function resolveClientPresentation(\n org: WidgetAgent['presentation'],\n client: WidgetConfig['presentation'],\n): WidgetConfig['presentation'] {\n if (!org) return client;\n return {\n streaming: org.streaming && client?.streaming !== false,\n toolActivity:\n org.toolActivity === 'hidden' || client?.toolActivity === 'hidden'\n ? 'hidden'\n : org.toolActivity === 'status' || client?.toolActivity === 'status'\n ? 'status'\n : 'details',\n reasoning: org.reasoning && client?.reasoning !== false,\n };\n}\n","/**\n * Asymmetric level smoother shared by every voice meter: fast attack so the\n * UI kicks with speech, slow release so it settles instead of twitching.\n * One implementation so the mic bars, edge glow, and width swell can never\n * drift apart in feel — only in their chosen constants.\n */\nexport class DictationLevelSmoother {\n private readonly attack: number;\n private readonly release: number;\n private value = 0;\n\n constructor({ attack, release }: { attack: number; release: number }) {\n this.attack = attack;\n this.release = release;\n }\n\n next(target: number): number {\n this.value +=\n (target - this.value) *\n (target > this.value ? this.attack : this.release);\n return this.value;\n }\n\n current(): number {\n return this.value;\n }\n}\n","import type {\n WidgetCompanionLayoutU,\n WidgetSidebarModeU,\n} from '../types/widget-config';\n\n/** The sidebar side after `auto` has been resolved against the host dir. */\nexport type WidgetSidebarSideResolvedU = 'left' | 'right';\n\nexport const DEFAULT_COMPANION_LAYOUTS = [\n 'compact',\n 'sidebar',\n 'fullscreen',\n] as const satisfies readonly WidgetCompanionLayoutU[];\n\nconst COMPANION_LAYOUTS = new Set<WidgetCompanionLayoutU>(\n DEFAULT_COMPANION_LAYOUTS,\n);\n\nfunction isCompanionLayout(value: unknown): value is WidgetCompanionLayoutU {\n return COMPANION_LAYOUTS.has(value as WidgetCompanionLayoutU);\n}\n\n/**\n * Resolve the layouts available to the companion. Configured order is part of\n * the public contract, so it is preserved while duplicates and invalid runtime\n * values are discarded. An omitted or unusable list falls back to every\n * layout, keeping the result non-empty for all consumers.\n */\nexport function normalizeCompanionLayouts(\n layouts?: unknown,\n): readonly WidgetCompanionLayoutU[] {\n if (!Array.isArray(layouts)) return DEFAULT_COMPANION_LAYOUTS;\n\n const normalized: WidgetCompanionLayoutU[] = [];\n const seen = new Set<WidgetCompanionLayoutU>();\n for (const layout of layouts) {\n if (!isCompanionLayout(layout) || seen.has(layout)) continue;\n seen.add(layout);\n normalized.push(layout);\n }\n\n return normalized.length > 0 ? normalized : DEFAULT_COMPANION_LAYOUTS;\n}\n\n/** Choose an allowed initial/fallback layout for the companion shell. */\nexport function resolveCompanionDefaultLayout(\n configuredDefault: unknown,\n allowedLayouts: readonly WidgetCompanionLayoutU[],\n): WidgetCompanionLayoutU {\n if (\n isCompanionLayout(configuredDefault) &&\n allowedLayouts.includes(configuredDefault)\n ) {\n return configuredDefault;\n }\n return allowedLayouts[0] ?? DEFAULT_COMPANION_LAYOUTS[0];\n}\n\n/**\n * Resolve the physical edge the sidebar occupies. `auto` (and any unusable\n * runtime value) follows the host document's direction — the inline-end edge,\n * which is the historical behavior — while an explicit side wins in both\n * directions.\n */\nexport function resolveSidebarSide(\n side: unknown,\n dir: string,\n): WidgetSidebarSideResolvedU {\n if (side === 'left' || side === 'right') return side;\n return dir === 'rtl' ? 'left' : 'right';\n}\n\n/** Resolve how the sidebar coexists with the page; anything but `docked` floats. */\nexport function resolveSidebarMode(mode: unknown): WidgetSidebarModeU {\n return mode === 'docked' ? 'docked' : 'floating';\n}\n"],"names":["isAgentStreamKeepalive","part","isTurnSteeredPart","option","z","field","elicitationListSchema","approvalPreferencesSchema","PREFIX","log","message","details","defaultOnError","onErrorOptions","basicClient","options","client","createClient","middlewares","ConnectionRequestExpiredError","ConnectionAttemptUnavailableError","STREAM_PATH","RECONNECT_PATH","streamUrl","baseUrl","path","sessionId","ApiCaller","config","token","headers","request","key","value","response","serverId","signal","requestId","answer","data","error","attemptId","definedHeaders","presentation","language","body","abortSignal","cursor","filters","file","onProgress","resolve","reject","formData","xhr","event","percentage","uploadUrl","_a","_b","isExhaustive","funcName","PrimitiveState","state","newState","isEqual","_s","callback","Poller","cb","intervalMs","timeouts","poll","runCatching","result","ActiveSessionPollingCtx","api","sessionCtx","messageCtx","sessionPollingIntervalSeconds","session","unsubscribe","isInitialFetch","prevMessages","newMessages","msg","newMsg","existingMsg","m","newMessage","history","commonFields","action","responseBodyText","parsed","ContactCtx","storageCtx","_c","_d","persistedToken","_e","_g","_f","_h","_j","_i","_l","_k","_n","_m","payload","extraCollectedData","e","persistedExternalId","externalId","v4","UploadCtx","files","pending","id","controller","update","progress","genUuid","uuidv4","CsatCtx","currentSessionId","uuid","COMMANDS","SUPPORTED_LANGUAGES","isCommandLanguage","escapeRegex","s","buildGrammar","languages","entries","c","lang","phrase","alternation","a","b","before","grammarCache","grammarFor","grammar","deleteLastSentence","text","trimmed","cut","i","ch","LOWERCASE_AFTER_BREAK_REGEX","capitalizeAfterBreaks","brk","endsAtSentenceBoundary","DictationCommandUtils","raw","pendingTail","consumable","regex","out","control","match","maxLen","len","start","tail","candidate","DRIP_INTERVAL_MS","DRIP_BACKLOG_CHARS","DictationDripUtils","displayed","processed","backlog","locale","lower","primary","REUSE_SAFETY_MARGIN_MS","DictationMintCache","expiresAtMs","mintFresh","valid","mint","isRecord","parseServerEvent","REALTIME_CALLS_URL","MAX_SESSION_MS","CONNECT_TIMEOUT_MS","DISCONNECT_GRACE_MS","DictationMicrophoneError","DictationSession","mintToken","onDelta","onState","onError","onLevel","micPromise","stream","t","pc","track","dc","offer","sdpResponse","answerSdp","type","delta","audioContext","source","analyser","tick","sum","centered","rms","code","SILENCE_COMMAND_MS","IDLE","DictationCtx","target","level","sessionState","silenceControl","endingSession","endingTarget","send","ArabicLanguage","BengaliLanguage","BulgarianLanguage","CzechLanguage","DanishLanguage","GreekLanguage","GermanLanguage","EnglishLanguage","SpanishLanguage","FilipinoLanguage","FinnishLanguage","FrenchLanguage","HindiLanguage","ItalianLanguage","JapaneseLanguage","KoreanLanguage","DutchLanguage","NorwegianLanguage","PolishLanguage","PortugueseLanguage","RomanianLanguage","SwedishLanguage","RussianLanguage","ThaiLanguage","TurkishLanguage","UrduLanguage","VietnameseLanguage","ChineseSimplifiedLanguage","CroatianLanguage","EstonianLanguage","HungarianLanguage","IcelandicLanguage","LatvianLanguage","LithuanianLanguage","LuxembourgishLanguage","MalteseLanguage","NorwegianBokmalLanguage","SlovakLanguage","LANGUAGES","isSupportedLanguage","RTL_LANGUAGES","isRtlLanguage","resolveLanguage","getTranslation","overrides","params","name","translate","SessionCtx","contactCtx","sessionsPollingIntervalSeconds","sharedSessions","active","openSessionId","contact","clearActiveSession","first","retry","customData","hookError","deduped","self","sessions","currentSession","session_id","mergeSendContext","input","sendsPageContext","configContext","resolveConfigContext","mentions","mentionOnTheWire","merged","lifecycleContext","context","withoutKey","title","meta","record","_dropped","rest","err","resolveSendFeatures","features","buildSendMessageBody","content","initialMessages","_MessageCtx","streaming","getClientCapabilities","getRequestConfig","isStreaming","getSendsPageContext","handlers","buffered","messageIds","ids","messages","nextMessages","built","userMessage","optimisticMessageIds","messageId","index","delivered","localAbortController","isAssignedToAI","isSendingToAI","lastMessage","staged","botMessage","errorMessage","currentMessages","attachments","markedElements","messageContent","_","clientContext","marked","mark","elements","note","snapshotUrl","MessageCtx","RouterCtx","widget","isInitialFetchLoading","restored","mostRecentOpenSessionId","StorageCtx","storage","orgToken","preference","offset","width","side","layout","mode","resolveWidgetAgent","org","agent","narrowFeature","orgEnabled","embedToggle","resolveClientFeatures","toggles","WidgetInitializationError","_WidgetCtx","modes","parent","conversation","cleanup","externalConfig","WidgetCtx","resolveClientPresentation","DictationLevelSmoother","attack","release","DEFAULT_COMPANION_LAYOUTS","COMPANION_LAYOUTS","isCompanionLayout","normalizeCompanionLayouts","layouts","normalized","seen","resolveCompanionDefaultLayout","configuredDefault","allowedLayouts","resolveSidebarSide","dir","resolveSidebarMode"],"mappings":"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"}