/** * @oxpulse/chat-widget — i18n locale table. * * The widget accepted a `lang` constructor/attribute option since W2.1 but never * read it for any string — every user-facing string (tombstone, unseal-error, * composer, aria-labels) was hardcoded English. This module is the fix: a flat * `Record>` lookup + a `t()` helper. * * No external i18n library — the widget is zero-dependency by design and the * CDN bundle is size-budgeted (see esbuild.cdn.mjs FF-1 gate, 250 KB gzip). * A plain table + `{placeholder}` substitution covers every string this * package renders without pulling in ICU/CLDR plural-rule machinery. * * Interpolation: templates use `{name}` placeholders, substituted by `t()`. * Fallback chain: requested locale → `en` (per-key, via `lookupWithFallback`) * → the raw key itself as an absolute last resort — `t()` never returns * `undefined` or throws. */ export type Locale = 'en' | 'ru'; /** Locales the widget ships a translation table for. */ export declare const SUPPORTED_LOCALES: readonly Locale[]; export type LocaleKey = 'tombstone' | 'unsealError' | 'unsealErrorAria' | 'senderYou' | 'bubbleAriaLabel' | 'addReactionAria' | 'removeReactionAria' | 'heartButtonTitle' | 'retryLoadingMessagesAria' | 'retry' | 'sendFailedUploadInterrupted' | 'sendFailedUploadFailed' | 'dismissFailedMessage' | 'dismissFailedMessageAria' | 'reactionsGroupAria' | 'chooseReactionAria' | 'youReactedSuffix' | 'replyToMessageAria' | 'replyingToMessageAria' | 'cancelReply' | 'replyToLabel' | 'replyOriginalUnavailable' | 'composerPlaceholder' | 'messageInputAria' | 'sendMessageAria' | 'send' | 'messageEmpty' | 'sendingMessage' | 'messageExceedsLimit' | 'charactersRemaining' | 'retrySendingMessageAria' | 'attachFilesAria' | 'recordVoiceMessageAria' | 'recordVoiceMessageTitle' | 'stopRecordingAria' | 'cancelRecordingAria' | 'recordingLabel' | 'voicePreviewLabel' | 'sendVoiceMessageAria' | 'discardVoiceMessageAria' | 'voiceSlideHint' | 'voiceReleaseToCancelHint' | 'voiceBubbleGroupAria' | 'voicePlayAria' | 'voicePauseAria' | 'voiceSpeedAria' | 'voiceWaveformSeekAria' | 'voicePlaybackErrorAria' | 'attachFilesTitle' | 'chooseFilesToAttachAria' | 'attachmentTrayAria' | 'cancelUploadOfAria' | 'uploadingProgressAria' | 'announceUploadingFile' | 'announceFileUploaded' | 'announceUploadFailedFile' | 'uploadFailed' | 'queueUploadingCount' | 'queueDoneCount' | 'queueFailedCount' | 'attachmentUnavailableAria' | 'imageAria' | 'audioAria' | 'fileAria' | 'productViewAria' | 'productCardAttached' | 'removeProductCard' | 'productPickerAria' | 'productPickerSearch' | 'productPickerSearchAria' | 'productPickerLoading' | 'productPickerLoadError' | 'productPickerNoProducts' | 'productPickerNoMatches' | 'productPickerBtnAria' | 'productPickerList' | 'productPickerUntitled' | 'sessionExpired' | 'refresh' | 'refreshSessionAria' | 'connectionLostReconnecting' | 'connected' | 'couldNotReconnect' | 'reconnect' | 'retryConnectionManuallyAria' | 'chatLoading' | 'roleBadgeModerator' | 'roleBadgeOwner' | 'typingOneUser' | 'typingTwoUsers' | 'typingMultiple' | 'typingAriaLabel' | 'presenceOnline' | 'presenceLastSeen' | 'presenceLastSeenAria' | 'readReceiptSent' | 'readReceiptDelivered' | 'readReceiptRead' | 'readReceiptReadBy' | 'readReceiptAria' | 'emojiPickerAria' | 'emojiPickerSearch' | 'emojiPickerSearchAria' | 'emojiPickerNoResults' | 'emojiPickerBtnAria' | 'threadTitle' | 'threadReplies' | 'threadReplyCount' | 'threadCloseAria' | 'threadSendReply' | 'threadReplyPlaceholder' | 'threadLoading' | 'threadEmpty' | 'threadError' | 'pinnedBannerTitle' | 'pinnedBannerPinnedBy' | 'pinnedBannerLoading' | 'pinnedBannerNotLoaded' | 'pinnedBannerCloseAria' | 'pinnedBannerPrevAria' | 'pinnedBannerNextAria' | 'pinnedBannerJumpAria' | 'pinMessageAria' | 'unpinMessageAria'; /** * Look up `key` in `table`, falling back to `fallback`'s value, then to the * raw key itself as an absolute last resort. Exported standalone (rather than * inlined in `t()`) so the fallback CHAIN is unit-testable against fixture * tables, independent of the production locale data — which, by design, is * always fully translated (so the "missing key" branch is otherwise * unreachable with real keys until a future key ships ahead of its * translation). */ export declare function lookupWithFallback(table: Partial>, fallback: Partial>, key: string): string; /** * Resolve a BCP-47 language tag (the `lang` constructor/attribute option, or * `undefined` when not set) to a supported `Locale`. * * Chain: explicit `lang` → `navigator.language` prefix → `'en'`. Only the * primary subtag is matched (`ru-RU` → `ru`), and any tag we don't ship a * translation for collapses to `en` — never throws, never returns undefined. */ export declare function resolveLocale(lang?: string | null): Locale; /** * Translate `key` for `lang`, substituting `{name}` placeholders from `params`. * Falls back to `en` for a key missing from `lang`'s table (see * `lookupWithFallback`); a `lang` outside `SUPPORTED_LOCALES` (reachable only * via a type-unsafe cast, since `Locale` is a closed union) falls back to * `en`'s table entirely. */ export declare function t(key: LocaleKey, lang: Locale, params?: Record): string; export declare function formatPrice(price: number, currency: string, lang: Locale): string; //# sourceMappingURL=i18n.d.ts.map