langie 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/index.ts","/builds/codelits/langie-sdk/src/components/LanguageSelect.vue","#style-inject:#style-inject","../../src/styles/teleport.css","../../src/utils/lazyTransliterate.ts","../../src/language-aliases/european.ts","../../src/language-aliases/asian.ts","../../src/language-aliases/african.ts","../../src/language-aliases/index.ts","../../src/search-utils.ts","../../src/utils/displayNative.ts","../../src/utils/flagUrl.ts","../../src/constants/colors.ts","../../src/components/LanguageSelect.vue","/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue","../../src/useLangie.ts","../../src/constants.ts","../../src/core.ts","../../src/composables/useLangie-core.ts","../../src/utils/debug.ts","../../src/utils/getCountryCode.ts","../../src/utils/cache.ts","../../src/utils/localizeLanguageNames.ts","../../src/composables/useLangie-batching.ts","../../src/components/InterfaceLanguageSelect.vue","/builds/codelits/langie-sdk/src/components/lt.vue","../../src/components/lt.vue"],"sourcesContent":["export { default as LanguageSelect } from './LanguageSelect.vue'\nexport { default as InterfaceLanguageSelect } from './InterfaceLanguageSelect.vue'\nexport { default as lt } from './lt.vue'\n\nexport * from './types'\n","<template>\n <div class=\"language-select\" :class=\"{ 'is-dark': isDark }\">\n <!-- Show multiselect when we have languages OR when not loading -->\n <Multiselect\n v-if=\"validLanguages.length > 0 || !isLoading\"\n ref=\"multiselectRef\"\n :key=\"multiselectKey\"\n v-model=\"selectedLanguage\"\n :options=\"filteredLanguages\"\n :searchable=\"true\"\n @search-change=\"handleSearch\"\n :can-clear=\"false\"\n :allow-empty=\"false\"\n :object=\"true\"\n :placeholder=\"validLanguages.length === 0 ? 'No languages available' : placeholder\"\n :disabled=\"props.disabled || validLanguages.length === 0\"\n :loading=\"isLoading\"\n track-by=\"code\"\n label=\"name\"\n value-prop=\"code\"\n :filter-results=\"false\"\n :id=\"multiselectId\"\n :aria=\"COMBOBOX_ARIA\"\n :attrs=\"searchInputAttrs\"\n @keydown=\"handleKeydown\"\n >\n <template #singlelabel=\"{ value }\">\n <div v-if=\"value\" class=\"multiselect-single-label\">\n <img\n v-if=\"value.code\"\n :key=\"selectedLanguageKey\"\n :src=\"getFlagImageUrl(value)\"\n class=\"lang-flag\"\n :alt=\"`${value.native_name || value.name} flag`\"\n :data-custom-flag=\"isReadyFlagUrl(getFlagCode(value)) || undefined\"\n @error=\"onFlagError\"\n />\n <span class=\"language-text\"\n >{{ value.name }}\n <span v-if=\"value.native_name && value.native_name !== value.name\" class=\"native-name\"\n >({{ displayNative(value.name, value.native_name) }})</span\n ></span\n >\n </div>\n </template>\n <template #option=\"{ option }\">\n <div class=\"multiselect-option\" :data-lang-code=\"option.code\">\n <img\n :key=\"`${option.code}-${option.flag_country || 'fallback'}`\"\n :src=\"getFlagImageUrl(option)\"\n class=\"lang-flag\"\n :alt=\"`${option.name} flag`\"\n :data-custom-flag=\"isReadyFlagUrl(getFlagCode(option)) || undefined\"\n @error=\"onFlagError\"\n />\n <span class=\"language-text\"\n >{{ option.name }}\n <span\n v-if=\"option.native_name && option.native_name !== option.name\"\n class=\"native-name\"\n >({{ displayNative(option.name, option.native_name) }})</span\n ></span\n >\n </div>\n </template>\n <template #noresults>\n <div class=\"multiselect-no-results\">No languages found.</div>\n </template>\n <template #nooptions>\n <div class=\"multiselect-no-options\">\n {{\n validLanguages.length === 0\n ? 'Please provide languages via the :languages prop'\n : 'No languages available.'\n }}\n </div>\n </template>\n </Multiselect>\n <!-- Only show skeleton loader when actually loading AND we have no languages yet -->\n <div v-else-if=\"isLoading && validLanguages.length === 0\" class=\"skeleton-loader\"></div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport '@vueform/multiselect/themes/default.css'\nimport '../styles/teleport.css'\nimport { ref, shallowRef, computed, nextTick, useId } from 'vue'\nimport type { PropType } from 'vue'\nimport Multiselect from '@vueform/multiselect'\nimport Fuse from 'fuse.js'\nimport type { FuseResult } from 'fuse.js'\nimport { loadTransliterate } from '../utils/lazyTransliterate'\nimport type { Transliterate } from '../utils/lazyTransliterate'\nimport { applyLanguageAlias } from '../search-utils'\nimport { displayNative } from '../utils/displayNative'\nimport { flagImageUrl, isReadyFlagUrl } from '../utils/flagUrl'\nimport { THEME_COLORS, COLORS } from '../constants/colors'\nimport type { TranslatorLanguage } from '../types'\n\n// role=\"combobox\" supports neither aria-multiselectable nor aria-placeholder (see\n// axe-core's role table), but @vueform/multiselect emits both on the search input.\n// The `aria` prop is merged last, so an undefined value drops the attribute instead\n// of shipping invalid ARIA. The placeholder comes back as a native one below, which\n// screen readers announce and validators accept.\nconst COMBOBOX_ARIA = { 'aria-multiselectable': undefined, 'aria-placeholder': undefined }\n\n// Without an id, vueform hardcodes `multiselect-options` on the listbox and\n// `assist` on its description, so two pickers on one page (source + target) hand\n// assistive tech duplicate ids and the wrong `aria-controls` target. useId is\n// SSR-safe — a module counter would drift between the server process and the\n// client and break hydration.\nconst multiselectId = useId()\n\nconst getFlagCode = (lang: TranslatorLanguage): string => {\n const flagCode = lang.flag_country || lang.code\n return flagCode\n}\n\n// Local flags are downloaded during build for offline support and faster\n// loading; on a miss the onerror handler falls back to the CDN.\nconst getFlagImageUrl = (lang: TranslatorLanguage): string => flagImageUrl(getFlagCode(lang))\n\nconst props = defineProps({\n modelValue: {\n type: Object as PropType<TranslatorLanguage | null | undefined>,\n default: undefined\n },\n languages: {\n type: Array as PropType<TranslatorLanguage[]>,\n default: () => []\n },\n placeholder: {\n type: String,\n default: 'Select language'\n },\n disabled: {\n type: Boolean,\n default: false\n },\n isDark: {\n type: Boolean,\n default: false\n }\n})\n\nconst emit = defineEmits(['update:modelValue'])\n\nconst multiselectRef = ref<{ setPointerFirst?: () => void } | null>(null)\n\nconst isLoading = computed(() => {\n return props.languages.length <= 0\n})\nconst searchQuery = ref('')\nconst transliterate = shallowRef<Transliterate | null>(null)\n\nconst searchInputAttrs = computed(() => ({ placeholder: props.placeholder }))\n\nconst validLanguages = computed(() => {\n return props.languages.filter((lang) => lang && lang.code && lang.name && lang.native_name)\n})\n\nconst fuse = computed(() => {\n if (!validLanguages.value.length) return null\n\n return new Fuse(validLanguages.value, {\n keys: ['name', 'native_name', 'search_alias', 'code'],\n includeScore: true,\n threshold: 0.4, // Trim fuzzy noise; short abbreviations (e.g. \"сша\") no longer rank below it\n ignoreLocation: true, // Match anywhere in the field, not just near position 0\n isCaseSensitive: false,\n minMatchCharLength: 1 // Allow single character matches\n })\n})\n\nconst multiselectKey = computed(() => {\n // Create a key that changes when the language data structure changes\n const hasApiData = props.languages.length > 0 && props.languages[0].flag_country !== null\n return hasApiData ? 'api-data' : 'fallback-data'\n})\n\nconst selectedLanguageKey = computed(() => {\n if (!props.modelValue || !props.modelValue.code) return 'no-selection'\n const key = `${props.modelValue.code}-${props.modelValue.flag_country || 'fallback'}`\n return key\n})\n\nconst selectedLanguage = computed({\n get: () => props.modelValue || null,\n set: (value) => {\n if (value && value.code) {\n emit('update:modelValue', value)\n }\n }\n})\n\nconst filteredLanguages = computed(() => {\n const query = searchQuery.value.trim()\n\n let results: TranslatorLanguage[]\n if (!query) {\n // When no search query, return all valid languages (bypass Fuse.js)\n results = validLanguages.value\n } else {\n // Only use Fuse.js when there's an actual search query\n if (!fuse.value) return []\n\n // Get the most likely alias or the original term\n const aliasResult = applyLanguageAlias(query)\n const searchTerm = Array.isArray(aliasResult.primary)\n ? aliasResult.primary[0]\n : aliasResult.primary\n\n // Merge Fuse hits into `results`, skipping languages already present.\n const mergeByCode = (hits: FuseResult<TranslatorLanguage>[]) => {\n hits.forEach((hit) => {\n if (!results.some((r) => r.code === hit.item.code)) results.push(hit.item)\n })\n }\n\n // Always use Fuse.js for the main search (both original query and alias result)\n results = fuse.value.search(searchTerm).map((result) => result.item)\n\n // If the search term is different from query (alias was applied), also search the original query\n if (searchTerm !== query) {\n mergeByCode(fuse.value.search(query))\n }\n\n // Transliterate the query to Latin so a foreign-script keyboard still matches the\n // Latin `name`/`native_name` when no localized `search_alias` exists (e.g. English\n // interface). Helps cognates: Cyrillic \"браз\" → \"braz\" → Brazilian.\n const latinQuery = transliterate.value ? transliterate.value(query) : ''\n if (latinQuery && latinQuery.toLowerCase() !== query.toLowerCase()) {\n mergeByCode(fuse.value.search(latinQuery))\n }\n\n // Add suggested languages to expand the results\n if (aliasResult.suggestions.length > 0) {\n aliasResult.suggestions.forEach((suggestion) => {\n const suggestedLang = validLanguages.value.find((lang) => {\n const langName = lang.name.toLowerCase()\n const suggestion_lower = suggestion.toLowerCase()\n\n // Try multiple matching strategies\n return (\n langName === suggestion_lower || // Exact match\n langName.includes(suggestion_lower) || // Contains match\n lang.code.toLowerCase() === suggestion_lower || // Code match\n langName.startsWith(suggestion_lower) || // Starts with match\n // Handle common variations\n (suggestion_lower === 'tatar' && langName.includes('tatar')) ||\n (suggestion_lower === 'belarusian' &&\n (langName.includes('belarus') || langName.includes('belarusian'))) ||\n (suggestion_lower === 'moldovan' &&\n (langName.includes('moldov') || langName.includes('moldova')))\n )\n })\n if (suggestedLang && !results.some((r) => r.code === suggestedLang.code)) {\n results.push(suggestedLang)\n }\n })\n }\n\n // Special handling for very short queries (e.g. \"се\")\n if (query.length === 2) {\n const lowerQuery = query.toLowerCase()\n const manualResults = validLanguages.value.filter(\n (lang) =>\n lang.name.toLowerCase().startsWith(lowerQuery) ||\n lang.native_name.toLowerCase().startsWith(lowerQuery)\n )\n manualResults.forEach((lang) => {\n if (!results.some((r) => r.code === lang.code)) {\n results.push(lang)\n }\n })\n }\n }\n\n // Remove the currently selected language from the options\n const filtered = results.filter(\n (lang) => !props.modelValue || !props.modelValue.code || lang.code !== props.modelValue.code\n )\n\n return filtered\n})\n\nfunction handleSearch(query: string) {\n searchQuery.value = query\n if (!query.trim()) return\n\n // Typing is the first moment the charmap can matter; the results recompute on\n // their own once the ref lands, so the first keystrokes stay Latin-only.\n if (!transliterate.value) {\n void loadTransliterate().then((fn) => {\n transliterate.value = fn\n })\n }\n\n // We feed our own fuzzy-filtered list (`filter-results=false`), so vueform's search\n // watcher runs setPointerFirst against the OLD options before our list re-renders —\n // leaving a STALE internal pointer that Enter/arrows then act on (random selection).\n // Re-point to the first option once the fresh list has rendered, and reset the scroll\n // so the best match is at the top. This drives vueform's real pointer (which owns the\n // `is-pointed` highlight and keyboard selection), not just the visual class.\n nextTick(() => {\n multiselectRef.value?.setPointerFirst?.()\n const dropdown = document.querySelector('.multiselect-dropdown')\n if (dropdown) dropdown.scrollTop = 0\n })\n}\n\n// Enter/Tab selects the currently highlighted option. `data-lang-code` lives on our inner\n// slot div, not vueform's outer `.multiselect-option` wrapper — read it from the pointed\n// row (falling back to the first) so selection matches what the user sees highlighted.\nfunction handleKeydown(event: Event) {\n const keyboardEvent = event as KeyboardEvent\n if (keyboardEvent.key !== 'Tab' && keyboardEvent.key !== 'Enter') return\n if (!searchQuery.value.trim()) return\n\n const dropdown = document.querySelector('.multiselect-dropdown')\n const pointed =\n dropdown?.querySelector('.multiselect-option.is-pointed [data-lang-code]') ||\n dropdown?.querySelector('.multiselect-option [data-lang-code]')\n const langCode = pointed?.getAttribute('data-lang-code')\n if (!langCode) return\n\n const language = validLanguages.value.find((lang) => lang.code === langCode)\n if (language) {\n selectedLanguage.value = language\n searchQuery.value = ''\n keyboardEvent.preventDefault()\n }\n}\n\nconst onFlagError = (event: Event) => {\n const target = event.target as HTMLImageElement\n const currentSrc = target.src\n\n // A custom flag is final: its slug is a language code, so the CDN fallback\n // below would silently serve an unrelated country — \"cv\" is Chuvash to us\n // and Cape Verde to flagcdn, \"ba\" Bashkir and Bosnia. Wrong flag beats no\n // flag only if you never look at it. Hide instead.\n if (target.dataset.customFlag) {\n target.style.display = 'none'\n return\n }\n\n // If loading from local cache failed, try CDN\n if (currentSrc && currentSrc.includes('/flags/')) {\n const match = currentSrc.match(/\\/flags\\/([a-z]{2})\\.svg/)\n if (match) {\n const countryCode = match[1]\n // Fallback to CDN\n target.src = `https://flagcdn.com/${countryCode}.svg`\n // If CDN also fails, hide the image\n target.onerror = () => {\n target.style.display = 'none'\n }\n return\n }\n }\n\n // If CDN or any other source fails, hide the image\n target.style.display = 'none'\n}\n</script>\n\n<style scoped>\n.language-select {\n position: relative;\n min-height: 40px; /* To prevent layout shift while loading */\n}\n\n.skeleton-loader {\n width: 100%;\n height: 40px;\n background-color: #e2e8f0;\n border-radius: 4px;\n animation: pulse 1.5s infinite ease-in-out;\n}\n\n.is-dark .skeleton-loader {\n background-color: #374151;\n}\n\n@keyframes pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n\n:deep(.multiselect) {\n --ms-font-size: 1rem;\n --ms-line-height: 1.5;\n --ms-bg: v-bind('THEME_COLORS.light.background');\n --ms-bg-disabled: v-bind('THEME_COLORS.light.backgroundDisabled');\n --ms-border-color: v-bind('THEME_COLORS.light.border');\n --ms-border-width: 1px;\n --ms-radius: 4px;\n --ms-py: 0.3rem;\n --ms-px: 0.875rem;\n --ms-ring-width: 3px;\n --ms-ring-color: v-bind('THEME_COLORS.light.ring');\n --ms-placeholder-color: v-bind('THEME_COLORS.light.placeholder');\n --ms-color: #1f2937; /* Explicit text color for light theme */\n\n /* Options */\n --ms-option-font-size: 1rem;\n --ms-option-line-height: 1;\n --ms-option-py: 0.2rem;\n --ms-option-px: 0.5rem;\n --ms-option-bg-pointed: v-bind('THEME_COLORS.light.optionPointed');\n --ms-option-color-pointed: v-bind('THEME_COLORS.light.optionPointedText');\n --ms-option-bg-selected: v-bind('THEME_COLORS.light.optionSelected');\n --ms-option-color-selected: v-bind('THEME_COLORS.light.optionSelectedText');\n --ms-option-bg-disabled: #fff;\n --ms-option-color-disabled: #d1d5db;\n\n /* Dropdown */\n --ms-dropdown-bg: v-bind('THEME_COLORS.light.dropdownBackground');\n --ms-dropdown-border-color: v-bind('THEME_COLORS.light.dropdownBorder');\n --ms-dropdown-color: v-bind('THEME_COLORS.light.dropdownText');\n\n /* Others */\n --ms-tag-bg: v-bind('THEME_COLORS.light.tagBackground');\n}\n\n.is-dark :deep(.multiselect) {\n --ms-bg: v-bind('THEME_COLORS.dark.background');\n --ms-bg-disabled: v-bind('THEME_COLORS.dark.backgroundDisabled');\n --ms-border-color: v-bind('THEME_COLORS.dark.border');\n --ms-placeholder-color: v-bind('THEME_COLORS.dark.placeholder');\n --ms-ring-color: v-bind('THEME_COLORS.dark.ring');\n --ms-color: v-bind('THEME_COLORS.dark.dropdownText'); /* typed search text; base is dark #1f2937 → invisible on dark bg */\n\n /* Options */\n --ms-option-bg-pointed: v-bind('THEME_COLORS.dark.optionPointed');\n --ms-option-color-pointed: v-bind('THEME_COLORS.dark.optionPointedText');\n --ms-option-bg-selected: v-bind('THEME_COLORS.dark.optionSelected');\n --ms-option-color-selected: v-bind('THEME_COLORS.dark.optionSelectedText');\n\n /* Dropdown */\n --ms-dropdown-bg: v-bind('THEME_COLORS.dark.dropdownBackground');\n --ms-dropdown-border-color: v-bind('THEME_COLORS.dark.dropdownBorder');\n --ms-dropdown-color: v-bind('THEME_COLORS.dark.dropdownText');\n}\n\n:deep(.lang-flag) {\n width: 20px;\n height: 15px;\n border: 1px solid v-bind('COLORS.border.flag');\n border-radius: 2px;\n object-fit: cover;\n flex-shrink: 0;\n display: block;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.is-dark :deep(.lang-flag) {\n border-color: v-bind('COLORS.border.dark');\n}\n\n:deep(.multiselect-single-label),\n:deep(.multiselect-option) {\n display: flex !important;\n align-items: center !important;\n min-width: 0 !important;\n width: 100% !important;\n padding: 4px 8px !important;\n gap: 8px !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n flex-wrap: nowrap !important;\n}\n\n:deep(.multiselect-option) {\n text-align: left !important;\n transition: background-color 0.15s ease !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n flex-wrap: nowrap !important;\n}\n\n:deep(.language-text) {\n display: inline-block !important;\n min-width: 0 !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n flex: 1 !important;\n line-height: 1.4 !important;\n color: v-bind('THEME_COLORS.light.dropdownText') !important;\n word-break: keep-all !important;\n word-wrap: normal !important;\n word-spacing: normal !important;\n max-width: 100% !important;\n}\n\n.is-dark :deep(.language-text) {\n color: v-bind('THEME_COLORS.dark.dropdownText') !important;\n}\n\n:deep(.native-name) {\n color: v-bind('COLORS.text.secondary');\n margin-left: 0.5rem;\n font-size: 0.9em;\n white-space: nowrap !important;\n display: inline !important;\n}\n\n.is-dark :deep(.native-name) {\n color: v-bind('COLORS.neutral.gray400');\n}\n\n:deep(.multiselect) {\n width: 100%;\n min-width: 200px;\n color: v-bind('THEME_COLORS.light.dropdownText');\n position: relative;\n z-index: 1;\n}\n\n.is-dark :deep(.multiselect) {\n color: v-bind('THEME_COLORS.dark.dropdownText');\n}\n\n/* Lift the open select above sibling selects (each is its own z-index:1 stacking context) */\n:deep(.multiselect.is-active) {\n z-index: 2;\n}\n\n:deep(.multiselect-dropdown) {\n padding: 2px 0 !important;\n z-index: 1000 !important;\n}\n\n:deep(.multiselect-dropdown .multiselect-option) {\n padding: 4px 8px !important;\n margin: 0 !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n flex-wrap: nowrap !important;\n}\n\n:deep(.multiselect-dropdown .language-text) {\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n word-break: keep-all !important;\n word-wrap: normal !important;\n word-spacing: normal !important;\n max-width: 100% !important;\n}\n\n:deep(.multiselect-no-results),\n:deep(.multiselect-no-options) {\n padding: 0.5rem 0.875rem;\n color: v-bind('COLORS.text.secondary');\n}\n\n.is-dark :deep(.multiselect-no-results),\n.is-dark :deep(.multiselect-no-options) {\n color: v-bind('COLORS.neutral.gray400');\n}\n</style>\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".multiselect-single-label,\\n.multiselect-option {\\n display: flex;\\n align-items: center;\\n}\\n.lang-flag {\\n width: 20px;\\n height: 15px;\\n margin-right: 10px;\\n border: 1px solid var(--langie-flag-border, #eee);\\n border-radius: 2px;\\n object-fit: cover;\\n}\\n.is-dark .lang-flag {\\n border-color: var(--langie-flag-border-dark, #4b5563);\\n}\\n.native-name {\\n color: var(--langie-text-secondary, #6b7280);\\n margin-left: 0.5rem;\\n font-size: 0.9em;\\n}\\n.is-dark .native-name {\\n color: var(--langie-text-secondary-dark, #9ca3af);\\n}\\n.multiselect-no-results,\\n.multiselect-no-options {\\n padding: 0.5rem 0.875rem;\\n color: var(--langie-text-secondary, #6b7280);\\n}\\n.is-dark .multiselect-no-results,\\n.is-dark .multiselect-no-options {\\n color: var(--langie-text-secondary-dark, #9ca3af);\\n}\\n\")","export type Transliterate = (input: string) => string\n\nlet pending: Promise<Transliterate> | null = null\n\n/**\n * `transliteration` ships a ~200 KB charmap — a third of a consumer's entry\n * chunk — but it is only needed once somebody types a non-Latin query, so it is\n * pulled on demand instead of at import time. The promise is cached, so the\n * charmap is fetched once per session no matter how many pickers ask for it.\n */\nexport function loadTransliterate(): Promise<Transliterate> {\n if (!pending) {\n pending = import('transliteration').then((m) => m.transliterate)\n }\n return pending\n}\n","import type { AliasEntry } from './types'\n\nexport const EUROPEAN_LANGUAGES: AliasEntry[] = [\n // Major European Languages\n {\n lang: 'english',\n match: [\n 'eng',\n 'en',\n 'английский',\n 'англ',\n 'united states',\n 'united states of america',\n 'usa',\n 'us',\n 'great britain',\n 'britain',\n 'british',\n 'england',\n 'united kingdom',\n 'uk'\n ],\n suggest: ['irish', 'scottish', 'welsh']\n },\n // English variants: country name / abbreviation → the specific variant CODE.\n // `lang` here is a variant code (not a language name) so Fuse matches it against\n // the `code` key and ranks that exact variant first (e.g. \"сша\" → en-US #1).\n // Latin \"usa\"/\"us\" stay on the `english` entry above (surface the whole group);\n // these cover the Cyrillic exonyms the translated names never contain.\n {\n lang: 'en-us',\n match: ['сша', 'штаты', 'америка', 'соединённые штаты', 'соединенные штаты'],\n suggest: []\n },\n {\n lang: 'en-au',\n match: ['австралия'],\n suggest: []\n },\n {\n lang: 'en-ca',\n match: ['канада'],\n suggest: []\n },\n {\n lang: 'en-ie',\n match: ['ирландия'],\n suggest: []\n },\n {\n lang: 'spanish',\n match: [\n 'spa',\n 'es',\n 'esp',\n 'spain',\n 'español',\n 'mexico',\n 'mexican',\n 'argentina',\n 'colombia',\n 'venezuela'\n ],\n suggest: ['catalan', 'galician', 'basque']\n },\n {\n lang: 'french',\n match: [\n 'fra',\n 'fr',\n 'fre',\n 'france',\n 'français',\n 'canada',\n 'canadian',\n 'quebec',\n 'belgium',\n 'swiss'\n ],\n suggest: ['occitan', 'breton', 'corsican']\n },\n {\n lang: 'german',\n match: [\n 'ger',\n 'de',\n 'deu',\n 'germany',\n 'deutsch',\n 'austria',\n 'austrian',\n 'switzerland',\n 'swiss'\n ],\n suggest: ['bavarian', 'saxon', 'luxembourgish']\n },\n {\n lang: 'italian',\n match: ['ita', 'it', 'italy', 'italiano', 'swiss italian'],\n suggest: ['sardinian', 'neapolitan', 'venetian']\n },\n {\n lang: 'portuguese',\n match: ['por', 'pt', 'portugal', 'brazil', 'brazilian', 'braz', 'mozambique', 'angola'],\n suggest: ['galician', 'mirandese']\n },\n {\n lang: 'dutch',\n match: ['dut', 'nl', 'nld', 'netherlands', 'holland', 'flemish', 'belgium'],\n suggest: ['frisian', 'afrikaans']\n },\n\n // Slavic Languages\n {\n lang: 'russian',\n match: ['rus', 'ru', 'russia', 'belarus'],\n suggest: ['kazakh', 'tatar', 'belarusian', 'tajik', 'uzbek', 'moldovan']\n },\n {\n lang: 'ukrainian',\n match: ['ukr', 'uk', 'ukraine'],\n suggest: ['russian', 'belarusian']\n },\n {\n lang: 'polish',\n match: ['pol', 'pl', 'poland'],\n suggest: ['silesian', 'kashubian']\n },\n {\n lang: 'czech',\n match: ['ces', 'cs', 'cze', 'czech republic', 'czechia'],\n suggest: ['slovak', 'moravian']\n },\n {\n lang: 'slovak',\n match: ['slk', 'sk', 'slovakia'],\n suggest: ['czech', 'rusyn']\n },\n {\n lang: 'croatian',\n match: ['hrv', 'hr', 'croatia'],\n suggest: ['serbian', 'bosnian', 'montenegrin']\n },\n {\n lang: 'serbian',\n match: [\n 'srp',\n 'sr',\n 'ser',\n 'serbia',\n 'serbian',\n 'srpski',\n 'србија',\n 'српски',\n 'серб',\n 'сербский',\n 'сербс'\n ],\n suggest: ['croatian', 'bosnian', 'montenegrin']\n },\n {\n lang: 'bulgarian',\n match: ['bul', 'bg', 'bulgaria'],\n suggest: ['macedonian']\n },\n {\n lang: 'slovenian',\n match: ['slv', 'sl', 'slovenia'],\n suggest: ['croatian']\n },\n\n // Nordic Languages\n {\n lang: 'swedish',\n match: ['swe', 'sv', 'sweden'],\n suggest: ['norwegian', 'danish', 'finnish']\n },\n {\n lang: 'norwegian',\n match: ['nor', 'no', 'norway'],\n suggest: ['swedish', 'danish']\n },\n {\n lang: 'danish',\n match: ['dan', 'da', 'denmark'],\n suggest: ['norwegian', 'swedish']\n },\n {\n lang: 'finnish',\n match: ['fin', 'fi', 'finland'],\n suggest: ['estonian', 'swedish']\n },\n {\n lang: 'icelandic',\n match: ['isl', 'is', 'iceland'],\n suggest: ['faroese', 'norwegian']\n },\n\n // Other European Languages\n {\n lang: 'greek',\n match: ['ell', 'el', 'gre', 'greece', 'hellenic'],\n suggest: ['macedonian', 'albanian']\n },\n {\n lang: 'romanian',\n match: ['ron', 'ro', 'rum', 'romania'],\n suggest: ['moldovan', 'hungarian']\n },\n {\n lang: 'hungarian',\n match: ['hun', 'hu', 'hungary', 'magyar'],\n suggest: ['romanian', 'slovak']\n },\n {\n lang: 'albanian',\n match: ['sqi', 'sq', 'alb', 'albania', 'kosovo'],\n suggest: ['greek', 'macedonian']\n },\n {\n lang: 'lithuanian',\n match: ['lit', 'lt', 'lithuania'],\n suggest: ['latvian', 'polish']\n },\n {\n lang: 'latvian',\n match: ['lav', 'lv', 'latvia'],\n suggest: ['lithuanian', 'estonian']\n },\n {\n lang: 'estonian',\n match: ['est', 'et', 'estonia'],\n suggest: ['finnish', 'latvian']\n },\n\n // Celtic Languages\n {\n lang: 'irish',\n match: ['gle', 'ga', 'ireland', 'gaelic'],\n suggest: ['scottish', 'welsh']\n },\n {\n lang: 'welsh',\n match: ['cym', 'cy', 'wales', 'cymru'],\n suggest: ['irish', 'cornish']\n },\n {\n lang: 'scottish',\n match: ['gla', 'gd', 'scotland', 'scots gaelic'],\n suggest: ['irish', 'english']\n },\n\n // Additional Languages\n {\n lang: 'esperanto',\n match: ['epo', 'eo', 'esperanto'],\n suggest: []\n },\n {\n lang: 'latin',\n match: ['lat', 'la', 'latin'],\n suggest: ['italian', 'spanish', 'french']\n }\n]\n","import type { AliasEntry } from './types'\n\nexport const ASIAN_LANGUAGES: AliasEntry[] = [\n // Asian Languages\n {\n lang: 'chinese',\n match: [\n 'chi',\n 'zh',\n 'zho',\n 'zh-cn',\n 'cn',\n 'china',\n 'mandarin',\n 'zhongwen',\n 'simplified',\n 'traditional'\n ],\n suggest: ['cantonese', 'taiwanese', 'hakka']\n },\n {\n lang: 'japanese',\n match: ['jpn', 'ja', 'jp', 'japan', 'nihongo'],\n suggest: ['okinawan']\n },\n {\n lang: 'korean',\n match: ['kor', 'ko', 'kr', 'korea', 'hangul', 'south korea', 'north korea'],\n suggest: ['jeju']\n },\n {\n lang: 'hindi',\n match: ['hin', 'hi', 'india', 'indian', 'devanagari'],\n suggest: ['urdu', 'punjabi', 'gujarati', 'marathi', 'bengali']\n },\n {\n lang: 'arabic',\n match: ['ara', 'ar', 'arab', 'saudi', 'egypt', 'egyptian', 'gulf', 'levantine', 'maghreb'],\n suggest: ['persian', 'hebrew', 'urdu']\n },\n {\n lang: 'thai',\n match: ['tha', 'th', 'thailand', 'siam'],\n suggest: ['lao', 'khmer']\n },\n {\n lang: 'vietnamese',\n match: ['vie', 'vi', 'vietnam'],\n suggest: ['khmer', 'lao']\n },\n {\n lang: 'indonesian',\n match: ['ind', 'id', 'indonesia', 'bahasa'],\n suggest: ['malay', 'javanese', 'sundanese']\n },\n {\n lang: 'malay',\n match: ['msa', 'ms', 'malaysia', 'brunei'],\n suggest: ['indonesian']\n },\n\n // Central Asian & Turkic Languages\n {\n lang: 'kazakh',\n match: ['kaz', 'kk', 'kazlat', 'kazakh', 'kazakhstan', 'казах', 'казахский', 'казахс'],\n suggest: ['russian', 'kyrgyz', 'uzbek']\n },\n {\n lang: 'turkish',\n match: ['tur', 'tr', 'turkey'],\n suggest: ['kurdish', 'azerbaijani']\n },\n {\n lang: 'uzbek',\n match: ['uzb', 'uz', 'uzbekistan'],\n suggest: ['tajik', 'kazakh', 'kyrgyz']\n },\n {\n lang: 'kyrgyz',\n match: ['kir', 'ky', 'kyrgyzstan'],\n suggest: ['kazakh', 'uzbek']\n },\n {\n lang: 'tajik',\n match: ['tgk', 'tg', 'tajikistan'],\n suggest: ['persian', 'uzbek']\n },\n {\n lang: 'azerbaijani',\n match: ['aze', 'az', 'azerbaijan'],\n suggest: ['turkish', 'persian']\n },\n\n // Middle Eastern Languages\n {\n lang: 'persian',\n match: ['fas', 'fa', 'per', 'iran', 'farsi', 'dari', 'afghanistan'],\n suggest: ['tajik', 'kurdish', 'pashto']\n },\n {\n lang: 'hebrew',\n match: ['heb', 'he', 'israel', 'israeli'],\n suggest: ['arabic', 'yiddish']\n },\n {\n lang: 'kurdish',\n match: ['kur', 'ku', 'kurdistan', 'kurmanji', 'sorani'],\n suggest: ['turkish', 'persian', 'arabic']\n },\n\n // South Asian Languages\n {\n lang: 'urdu',\n match: ['urd', 'ur', 'pakistan', 'pakistani'],\n suggest: ['hindi', 'punjabi']\n },\n {\n lang: 'bengali',\n match: ['ben', 'bn', 'bangladesh', 'bengal'],\n suggest: ['hindi', 'assamese']\n },\n {\n lang: 'punjabi',\n match: ['pan', 'pa', 'punjab'],\n suggest: ['hindi', 'urdu']\n },\n {\n lang: 'gujarati',\n match: ['guj', 'gu', 'gujarat'],\n suggest: ['hindi', 'marathi']\n },\n {\n lang: 'marathi',\n match: ['mar', 'mr', 'maharashtra'],\n suggest: ['hindi', 'gujarati']\n },\n {\n lang: 'tamil',\n match: ['tam', 'ta', 'tamil nadu', 'sri lanka'],\n suggest: ['malayalam', 'telugu', 'kannada']\n },\n {\n lang: 'telugu',\n match: ['tel', 'te', 'andhra pradesh'],\n suggest: ['tamil', 'kannada']\n },\n {\n lang: 'kannada',\n match: ['kan', 'kn', 'karnataka'],\n suggest: ['tamil', 'telugu', 'malayalam']\n },\n {\n lang: 'malayalam',\n match: ['mal', 'ml', 'kerala'],\n suggest: ['tamil', 'kannada']\n },\n {\n lang: 'nepali',\n match: ['nep', 'ne', 'nepal'],\n suggest: ['hindi']\n },\n {\n lang: 'sinhala',\n match: ['sin', 'si', 'sri lanka', 'ceylon'],\n suggest: ['tamil']\n },\n\n // Southeast Asian Languages\n {\n lang: 'burmese',\n match: ['mya', 'my', 'myanmar', 'burma'],\n suggest: ['thai']\n },\n {\n lang: 'khmer',\n match: ['khm', 'km', 'cambodia', 'cambodian'],\n suggest: ['vietnamese', 'thai']\n },\n {\n lang: 'lao',\n match: ['lao', 'lo', 'laos'],\n suggest: ['thai', 'vietnamese']\n },\n {\n lang: 'tagalog',\n match: ['tgl', 'tl', 'philippines', 'filipino'],\n suggest: ['cebuano', 'ilocano']\n }\n]\n","import type { AliasEntry } from './types'\n\nexport const AFRICAN_LANGUAGES: AliasEntry[] = [\n // African Languages\n {\n lang: 'swahili',\n match: ['swa', 'sw', 'kiswahili', 'tanzania', 'kenya'],\n suggest: ['arabic']\n },\n {\n lang: 'amharic',\n match: ['amh', 'am', 'ethiopia', 'ethiopian'],\n suggest: ['tigrinya', 'oromo']\n },\n {\n lang: 'yoruba',\n match: ['yor', 'yo', 'nigeria', 'benin'],\n suggest: ['igbo', 'hausa']\n },\n {\n lang: 'zulu',\n match: ['zul', 'zu', 'south africa'],\n suggest: ['xhosa', 'afrikaans']\n }\n]\n","import type { AliasEntry } from './types'\nimport { EUROPEAN_LANGUAGES } from './european'\nimport { ASIAN_LANGUAGES } from './asian'\nimport { AFRICAN_LANGUAGES } from './african'\n\nexport const LANGUAGE_ALIAS_TABLE: AliasEntry[] = [\n ...EUROPEAN_LANGUAGES,\n ...ASIAN_LANGUAGES,\n ...AFRICAN_LANGUAGES\n]\n\nexport type { AliasEntry }\n","// Map various common synonyms, country names, and demonyms to a canonical\n// language label. The canonical label must match the `name` field found in the\n// languages list returned by the backend (e.g. \"English\", \"French\", ...).\n\nimport { LANGUAGE_ALIAS_TABLE } from './language-aliases'\n\nexport function applyLanguageAlias(term = ''): {\n primary: string | string[]\n suggestions: string[]\n} {\n const s = term.toLowerCase().trim()\n if (!s) return { primary: term, suggestions: [] }\n\n // Helper decides whether a candidate alias matches the typed search string\n const isMatch = (alias: string, input: string): boolean => {\n if (input === alias) return true // exact match\n // Input fully contains the alias (and alias has 3+ chars) → e.g., \"germ\" vs \"german\"\n if (alias.length >= 3 && input.length >= alias.length && input.startsWith(alias)) return true\n // Alias contains the input (user typed prefix, at least 2 chars) → e.g., \"ge\" → \"german\"\n if (input.length >= 2 && alias.startsWith(input)) return true\n return false\n }\n\n const hits = new Set<string>()\n const suggestions = new Set<string>()\n\n for (const { lang, match, suggest } of LANGUAGE_ALIAS_TABLE) {\n // Check primary matches\n for (const m of match) {\n if (isMatch(m, s)) {\n hits.add(lang)\n // If this language has suggestions, add them\n if (suggest) {\n suggest.forEach((sug: string) => suggestions.add(sug))\n }\n }\n }\n }\n\n let primary: string | string[]\n if (hits.size === 0) {\n primary = term\n } else if (hits.size === 1) {\n primary = Array.from(hits)[0]\n } else {\n primary = Array.from(hits)\n }\n\n return { primary, suggestions: Array.from(suggestions) }\n}\n","// Matches a trailing parenthetical (ASCII or fullwidth) plus surrounding space:\n// \"Português (Brasil)\" -> the \" (Brasil)\" tail. Inner text must not contain\n// parens so nested groups don't over-match.\nconst TRAILING_PAREN = /\\s*[((][^()()]*[))]\\s*$/\n\n/**\n * Native-name label for a language option.\n *\n * When BOTH `name` and `native_name` carry a trailing region parenthetical\n * (regional variants like pt-BR: \"Portuguese (Brazil)\" / \"Português (Brasil)\"),\n * the region would read twice, so the native's tail is dropped. When only the\n * native has one (e.g. \"Chinese (Simplified)\" / \"中文\") it is kept. Exact\n * duplicates return unchanged (the caller already guards on `name !== native`).\n */\nexport function displayNative(name = '', native = ''): string {\n return name !== native && TRAILING_PAREN.test(name) && TRAILING_PAREN.test(native)\n ? native.replace(TRAILING_PAREN, '')\n : native\n}\n","/**\n * A consumer may supply a ready flag path or absolute URL instead of a country\n * code: languages with no country flag of their own (Tatar, Chuvash, Bashkir…)\n * are mapped to a hand-placed SVG such as \"/flags/cv.svg\". Those are final.\n */\nexport const isReadyFlagUrl = (flagCode: string): boolean =>\n flagCode.startsWith('/') || /^https?:\\/\\//i.test(flagCode)\n\n/**\n * The <img src> for a language's flag. Country codes are wrapped into the local\n * flag path (with a CDN fallback on error); a ready path/URL is passed through,\n * since wrapping it again yields \"/flags//flags/cv.svg.svg\" → 404.\n */\nexport const flagImageUrl = (flagCode: string): string =>\n isReadyFlagUrl(flagCode) ? flagCode : `/flags/${flagCode}.svg`\n","// Color constants for the langie\n// These colors are used across components for consistent theming\n\nexport const COLORS = {\n // Primary colors\n primary: {\n blue: '#3b82f6',\n blueLight: '#60a5fa',\n blueDark: '#2563eb',\n blueAlpha30: '#3b82f630',\n blueAlpha50: '#3b82f650'\n },\n\n // Neutral colors\n neutral: {\n white: '#fff',\n gray50: '#f9fafb',\n gray100: '#f3f4f6',\n gray200: '#e5e7eb',\n gray300: '#d1d5db',\n gray400: '#9ca3af',\n gray500: '#6b7280',\n gray600: '#4b5563',\n gray700: '#374151',\n gray800: '#1f2937',\n gray900: '#111827'\n },\n\n // Border colors\n border: {\n light: '#d1d5db',\n dark: '#4b5563',\n flag: '#eee'\n },\n\n // Text colors\n text: {\n primary: '#1f2937',\n secondary: '#6b7280',\n placeholder: '#9ca3af',\n inverse: '#f9fafb'\n }\n} as const\n\n// Theme-specific color mappings\nexport const THEME_COLORS = {\n light: {\n background: COLORS.neutral.white,\n backgroundDisabled: COLORS.neutral.gray100,\n border: COLORS.border.light,\n placeholder: COLORS.text.placeholder,\n ring: COLORS.primary.blueAlpha30,\n optionPointed: COLORS.neutral.gray100,\n optionPointedText: COLORS.text.primary,\n optionSelected: COLORS.primary.blue,\n optionSelectedText: COLORS.neutral.white,\n dropdownBackground: COLORS.neutral.white,\n dropdownBorder: COLORS.border.light,\n dropdownText: COLORS.text.primary,\n tagBackground: COLORS.primary.blue\n },\n dark: {\n background: COLORS.neutral.gray800,\n backgroundDisabled: COLORS.neutral.gray700,\n border: COLORS.border.dark,\n placeholder: COLORS.text.placeholder,\n ring: COLORS.primary.blueAlpha50,\n optionPointed: COLORS.neutral.gray700,\n optionPointedText: COLORS.neutral.gray50,\n optionSelected: COLORS.primary.blue,\n optionSelectedText: COLORS.neutral.white,\n dropdownBackground: COLORS.neutral.gray800,\n dropdownBorder: COLORS.border.dark,\n dropdownText: COLORS.neutral.gray50,\n tagBackground: COLORS.primary.blue\n }\n} as const\n\n// CSS variable names for easy reference\nexport const CSS_VARS = {\n // Multiselect variables\n multiselect: {\n bg: '--ms-bg',\n bgDisabled: '--ms-bg-disabled',\n borderColor: '--ms-border-color',\n placeholderColor: '--ms-placeholder-color',\n ringColor: '--ms-ring-color',\n optionBgPointed: '--ms-option-bg-pointed',\n optionColorPointed: '--ms-option-color-pointed',\n optionBgSelected: '--ms-option-bg-selected',\n optionColorSelected: '--ms-option-color-selected',\n dropdownBg: '--ms-dropdown-bg',\n dropdownBorderColor: '--ms-dropdown-border-color',\n dropdownColor: '--ms-dropdown-color',\n tagBg: '--ms-tag-bg'\n }\n} as const\n","import script from \"/builds/codelits/langie-sdk/src/components/LanguageSelect.vue?type=script\"\nexport * from \"/builds/codelits/langie-sdk/src/components/LanguageSelect.vue?type=script\"\n\nimport \"/builds/codelits/langie-sdk/src/components/LanguageSelect.vue?type=style&index=0\"\nexport default script\nscript.__scopeId = \"data-v-5b09cc17\"","<template>\n <div class=\"interface-language-select-wrapper\">\n <LanguageSelect\n :key=\"`interface-lang-${effectiveLanguages.length}-${effectiveLanguages[0]?.code || 'empty'}`\"\n :model-value=\"currentLanguageObject\"\n :languages=\"effectiveLanguages\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled || isChangingLanguage\"\n :is-dark=\"props.isDark\"\n @update:model-value=\"handleLanguageChange\"\n />\n\n <!-- Loading overlay -->\n <div\n v-if=\"isChangingLanguage\"\n class=\"language-change-loader\"\n :class=\"{ 'is-dark': props.isDark }\"\n >\n <div class=\"loader-spinner\"></div>\n <span class=\"loader-text\">{{ lr('Changing language...', 'ui') }}</span>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, watch, onMounted, ref } from 'vue'\nimport LanguageSelect from './LanguageSelect.vue'\nimport { useLangie } from '../useLangie'\nimport type { TranslatorLanguage } from '../types'\nimport { getCountryCode } from '../utils/getCountryCode'\n\n// Loading state for language change\nconst isChangingLanguage = ref(false)\n\nconst props = defineProps({\n placeholder: {\n type: String,\n default: 'Select interface language'\n },\n disabled: {\n type: Boolean,\n default: false\n },\n isDark: {\n type: Boolean,\n default: false\n },\n translatorHost: {\n type: String,\n default: ''\n },\n apiKey: {\n type: String,\n default: ''\n },\n languages: {\n type: Array as () => TranslatorLanguage[],\n default: () => []\n }\n})\n\nconst emit = defineEmits(['update:modelValue'])\n\n// Use the same SDK instance as the main app\nconst { availableLanguages, currentLanguage, setLanguage, fetchLanguages, lr } = useLangie()\n\n// Use provided languages if available, otherwise use SDK's languages\nconst effectiveLanguages = computed(() => {\n const languages =\n props.languages && props.languages.length > 0 ? props.languages : availableLanguages.value\n\n // Ensure all languages have required fields to prevent jumping\n const processed = languages.map((lang) => ({\n ...lang,\n native_name: lang.native_name || lang.name,\n flag_country: lang.flag_country || lang.code\n }))\n\n // Important: Keep API order (by popularity from language_popularity table)\n // Do NOT sort alphabetically - multiselect may reorder, but we preserve source order\n return processed\n})\n\nconst currentLanguageObject = computed(() => {\n if (!currentLanguage.value) return null\n return effectiveLanguages.value.find((lang) => lang.code === currentLanguage.value) || null\n})\n\n// Function to detect browser language from available languages\nfunction detectBrowserLanguage(languages: TranslatorLanguage[]): string | null {\n if (languages.length === 0) return null\n\n // Get browser languages in order of preference\n const browserLanguages = navigator.languages || [navigator.language || 'en']\n\n // Try to find exact match first\n for (const browserLang of browserLanguages) {\n const langCode = browserLang.toLowerCase().split('-')[0] // Extract language code (e.g., 'en' from 'en-US')\n const exactMatch = languages.find((lang) => lang.code.toLowerCase() === langCode)\n if (exactMatch) {\n return exactMatch.code\n }\n }\n\n // If no exact match, try with full locale (e.g., 'en-US')\n for (const browserLang of browserLanguages) {\n const fullLangCode = browserLang.toLowerCase()\n const localeMatch = languages.find((lang) => lang.code.toLowerCase() === fullLangCode)\n if (localeMatch) {\n return localeMatch.code\n }\n }\n\n return null\n}\n\nasync function handleLanguageChange(selectedLanguage: TranslatorLanguage | null) {\n if (selectedLanguage) {\n // Start loading\n isChangingLanguage.value = true\n\n try {\n setLanguage(selectedLanguage.code)\n // Save to localStorage when user manually changes language\n localStorage.setItem('interface_language', selectedLanguage.code)\n emit('update:modelValue', selectedLanguage)\n } finally {\n // End loading\n isChangingLanguage.value = false\n }\n }\n}\n\n// Watch for current language changes to save to localStorage\nwatch(currentLanguage, (newLangCode) => {\n if (newLangCode) {\n localStorage.setItem('interface_language', newLangCode)\n }\n})\n\n// Watch for changes in effective languages to set browser language\nwatch(\n () => effectiveLanguages.value,\n (newLanguages) => {\n if (newLanguages.length > 0 && !currentLanguage.value) {\n // Only set browser language if no language is currently selected\n const savedLanguageCode = localStorage.getItem('interface_language')\n\n if (savedLanguageCode) {\n // Check if saved language exists in the provided languages\n const savedLangExists = newLanguages.find((lang) => lang.code === savedLanguageCode)\n if (savedLangExists) {\n setLanguage(savedLanguageCode)\n return\n }\n }\n\n // If no saved language or saved language doesn't exist, detect browser language\n const browserLang = detectBrowserLanguage(newLanguages)\n if (browserLang) {\n setLanguage(browserLang)\n }\n }\n },\n { immediate: true }\n)\n\n// Load saved language from localStorage on initialization\nonMounted(async () => {\n // Only fetch languages if not provided via props\n if (!props.languages || props.languages.length === 0) {\n // Get country code from browser for better language ordering\n const countryCode = await getCountryCode()\n await fetchLanguages({ country: countryCode || undefined })\n }\n\n const savedLanguageCode = localStorage.getItem('interface_language')\n\n if (savedLanguageCode && savedLanguageCode !== currentLanguage.value) {\n // Check if saved language exists in current languages\n const currentLanguages = effectiveLanguages.value\n const savedLangExists = currentLanguages.find((lang) => lang.code === savedLanguageCode)\n\n if (savedLangExists) {\n setLanguage(savedLanguageCode)\n } else if (currentLanguages.length > 0) {\n // If saved language doesn't exist, try to detect browser language\n const browserLang = detectBrowserLanguage(currentLanguages)\n if (browserLang) {\n setLanguage(browserLang)\n }\n }\n } else if (!currentLanguage.value && effectiveLanguages.value.length > 0) {\n // If no saved language and no current language, detect browser language\n const browserLang = detectBrowserLanguage(effectiveLanguages.value)\n if (browserLang) {\n setLanguage(browserLang)\n }\n }\n})\n\n// Emit the current language when it changes\nwatch(\n currentLanguageObject,\n (newValue) => {\n if (newValue) {\n emit('update:modelValue', newValue)\n }\n },\n { immediate: true }\n)\n</script>\n\n<style scoped>\n.interface-language-select-wrapper {\n position: relative;\n display: inline-block;\n width: 100%;\n min-width: 200px;\n}\n\n/* Override styles for the language select component */\n.interface-language-select-wrapper :deep(.multiselect-option) {\n padding: 5px 10px !important;\n margin: 0;\n border-radius: 0;\n}\n\n.interface-language-select-wrapper :deep(.multiselect-option > div) {\n padding: 0 !important;\n margin: 0;\n}\n\n.interface-language-select-wrapper :deep(.multiselect-dropdown) {\n padding: 2px 0 !important;\n}\n\n.language-change-loader {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.95);\n border-radius: 6px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n z-index: 10;\n backdrop-filter: blur(2px);\n border: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.language-change-loader.is-dark {\n background: rgba(30, 30, 30, 0.95);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.loader-spinner {\n width: 24px;\n height: 24px;\n border: 3px solid #e5e7eb;\n border-top: 3px solid #3b82f6;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-bottom: 8px;\n}\n\n.language-change-loader.is-dark .loader-spinner {\n border-color: #374151;\n border-top-color: #3b82f6;\n}\n\n.loader-text {\n font-size: 12px;\n color: #6b7280;\n font-weight: 500;\n text-align: center;\n}\n\n.language-change-loader.is-dark .loader-text {\n color: #9ca3af;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n</style>\n","import { watch } from 'vue'\nimport type {\n TranslatorOptions,\n TranslateServiceResponse,\n TranslatorLanguage,\n TranslationSeed\n} from './types'\nimport { translateBatch } from './core'\nimport { useLangieCore, __resetLangieCoreForTests } from './composables/useLangie-core'\nimport { TranslationBatching } from './composables/useLangie-batching'\nimport {\n API_FIELD_TEXT,\n API_FIELD_FROM,\n API_FIELD_TO,\n API_FIELD_CTX,\n API_FIELD_TRANSLATIONS,\n API_FIELD_ERROR\n} from './constants'\nimport { setCache, getCache } from './utils/cache'\nimport { devDebug } from './utils/debug'\n\n// Global singleton instance\ntype LangieInstance = ReturnType<typeof createLangieInstance> & { translatorHost?: string }\nlet globalLangieInstance: LangieInstance | null = null\n\n// Preserve singleton across hot module reloads\nif (\n typeof window !== 'undefined' &&\n (window as unknown as Record<string, unknown>).__LANGIE_SINGLETON__\n) {\n globalLangieInstance = (window as unknown as Record<string, unknown>)\n .__LANGIE_SINGLETON__ as ReturnType<typeof createLangieInstance>\n}\n\n// Helper for safe localStorage access\nfunction safeLocalStorageAccess<T>(operation: () => T): T | undefined {\n if (typeof window === 'undefined') return undefined\n try {\n return operation()\n } catch (e) {\n devDebug('[useLangie] localStorage error:', e)\n return undefined\n }\n}\n\n// Also check if we have a stored singleton in localStorage as backup\nif (!globalLangieInstance && typeof window !== 'undefined') {\n const stored = safeLocalStorageAccess(() => localStorage.getItem('__LANGIE_SINGLETON_URL__'))\n if (stored) {\n // Use stored URL to prevent recreation with wrong options\n const storedOptions = { translatorHost: stored }\n globalLangieInstance = createLangieInstance(storedOptions)\n }\n}\n\n// Extended type for translation objects that includes ctx\ninterface TranslationWithContext extends TranslateServiceResponse {\n [API_FIELD_CTX]?: string\n translated_text?: string\n}\n\nfunction createLangieInstance(options: TranslatorOptions = {}) {\n const core = useLangieCore(options)\n const {\n availableLanguages,\n translations,\n uiTranslations,\n currentLanguage,\n isLoading,\n setLanguage,\n fetchLanguages,\n invalidateLanguages,\n translatorHost,\n clearTranslations\n } = core\n\n // Global defaults for lt component\n const ltDefaults = {\n ctx: 'ui',\n orig: ''\n }\n\n // Functions to manage lt component defaults\n const setLtDefaults = (defaults: { ctx?: string; orig?: string }) => {\n Object.assign(ltDefaults, defaults)\n }\n\n const getLtDefaults = () => ({ ...ltDefaults })\n\n // Synchronous SSR seed: language → \"text|ctx\" → translation. Unlike the reactive\n // caches it is NOT cleared on language switch, so a server-rendered value stays\n // resolvable through hydration (client seeds the same map → no mismatch).\n const seed: TranslationSeed = {}\n if (options.ssrTranslations) seedTranslations(options.ssrTranslations)\n\n function seedTranslations(entries: TranslationSeed) {\n for (const lang of Object.keys(entries)) {\n seed[lang] = { ...(seed[lang] || {}), ...entries[lang] }\n }\n }\n\n const getSeed = (lang: string, text: string, ctx: string): string | undefined =>\n seed[lang]?.[`${text}|${ctx}`]\n\n // localStorage cache management\n const CACHE_KEY = 'langie_translations_cache'\n const UI_CACHE_KEY = 'langie_ui_translations_cache'\n const LANGUAGES_CACHE_KEY = 'langie_languages_cache'\n\n // Load cached translations from localStorage for current language\n const loadCachedTranslations = () => {\n if (typeof window === 'undefined') return\n\n const cachedTranslations = getCache<Record<string, Record<string, string>>>(CACHE_KEY)\n const cachedUiTranslations = getCache<Record<string, Record<string, string>>>(UI_CACHE_KEY)\n\n if (cachedTranslations) {\n // Load translations for current language only\n const currentLang = currentLanguage.value\n const langTranslations = cachedTranslations[currentLang] || {}\n Object.assign(translations, langTranslations)\n }\n\n if (cachedUiTranslations) {\n // Load UI translations for current language only\n const currentLang = currentLanguage.value\n const langUiTranslations = cachedUiTranslations[currentLang] || {}\n Object.assign(uiTranslations, langUiTranslations)\n }\n }\n\n // Save translations to localStorage for current language\n const saveCachedTranslations = () => {\n if (typeof window === 'undefined') return\n\n // Load existing cache\n const existingTranslations = getCache<Record<string, Record<string, string>>>(CACHE_KEY) || {}\n const existingUiTranslations =\n getCache<Record<string, Record<string, string>>>(UI_CACHE_KEY) || {}\n\n // Save current language translations\n const currentLang = currentLanguage.value\n existingTranslations[currentLang] = { ...translations }\n existingUiTranslations[currentLang] = { ...uiTranslations }\n\n // Save with TTL (7 days for translations)\n setCache(CACHE_KEY, existingTranslations, 7 * 24 * 60 * 60 * 1000)\n setCache(UI_CACHE_KEY, existingUiTranslations, 7 * 24 * 60 * 60 * 1000)\n }\n\n // Load cached languages from localStorage\n const loadCachedLanguages = () => {\n if (typeof window === 'undefined') return\n\n const cachedLanguages = getCache<TranslatorLanguage[]>(LANGUAGES_CACHE_KEY)\n if (cachedLanguages) {\n availableLanguages.value = cachedLanguages\n }\n }\n\n // Load cached translations and languages on initialization\n loadCachedTranslations()\n loadCachedLanguages()\n\n // Watch for language changes to load cached translations\n watch(currentLanguage, () => {\n // Clear current translations before loading new ones\n Object.keys(translations).forEach((key) => delete translations[key])\n Object.keys(uiTranslations).forEach((key) => delete uiTranslations[key])\n loadCachedTranslations()\n })\n\n // Create batching instance\n const batching = new TranslationBatching(\n {\n initialBatchDelay: options.initialBatchDelay,\n followupBatchDelay: options.followupBatchDelay,\n maxBatchSize: options.maxBatchSize,\n maxWaitTime: options.maxWaitTime,\n getTurnstileToken: options.getTurnstileToken\n },\n translatorHost,\n () => currentLanguage.value,\n (results, requests) => {\n // Process batch results and update translations\n // Batch complete\n\n // Clear recently queued cache to make translations immediately available\n requests.forEach((req) => {\n const cacheKey = `${req[API_FIELD_TEXT]}|${req[API_FIELD_CTX]}`\n const languageCacheKey = `${cacheKey}|${req[API_FIELD_FROM]}|${req[API_FIELD_TO]}`\n recentlyQueued.delete(languageCacheKey)\n })\n\n // --- PATCH: Map translations to requests by index (since ctx is not present in response) ---\n // Flatten all translation arrays from results\n let translationsArray: TranslationWithContext[] = []\n results.forEach((result) => {\n if (Array.isArray(result)) {\n translationsArray = translationsArray.concat(result)\n } else if (result.translations && Array.isArray(result.translations)) {\n translationsArray = translationsArray.concat(result.translations)\n }\n })\n\n translationsArray.forEach((translation, idx) => {\n const request = requests[idx]\n if (!request) {\n devDebug('[useLangie] No matching request for translation:', translation)\n return\n }\n const originalText = request[API_FIELD_TEXT]\n const originalCtx = request[API_FIELD_CTX] ?? (ltDefaults.ctx || 'ui')\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n devDebug(\n '[useLangie] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n\n // Record the error for future reference\n const errorKey = `${originalText}|${originalCtx}|${request[API_FIELD_FROM]}|${request[API_FIELD_TO]}`\n translationErrors.set(errorKey, translation[API_FIELD_ERROR])\n\n return // Don't cache translations with errors\n }\n\n // Handle language detection response\n if (translation[API_FIELD_FROM] && !translation[API_FIELD_TEXT]) {\n return\n }\n\n const translatedText = translation[API_FIELD_TEXT]\n if (translatedText) {\n // PATCH: Only skip as outdated if toLang was not explicitly set\n const requestedLanguage = request[API_FIELD_TO]\n const explicitToLang = request.__explicitToLang\n if (!explicitToLang && requestedLanguage !== currentLanguage.value) {\n devDebug('[useLangie] Skipping outdated translation:', {\n original: originalText,\n translated: translatedText,\n requestedLanguage,\n currentLanguage: currentLanguage.value\n })\n return\n }\n\n // Skip caching if translation equals original text\n if (translatedText === originalText) {\n devDebug('[useLangie] Skipping cache for identical translation:', {\n original: originalText,\n translated: translatedText,\n context: originalCtx\n })\n return\n }\n\n const effectiveCtx = originalCtx\n // Store under the exact key the read side queued with: explicit-target\n // requests carry a language-qualified key (see translateInternal).\n const cacheKey = request.cacheKey || `${originalText}|${effectiveCtx}`\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n\n // Cache the translation\n cache[cacheKey] = translatedText\n\n // Debug logging\n devDebug('[useLangie] Cached translation:', {\n original: originalText,\n translated: translatedText,\n context: effectiveCtx,\n cacheKey,\n language: requestedLanguage\n })\n\n // Save to localStorage\n saveCachedTranslations()\n }\n })\n }\n )\n\n // Simple cache to track recently queued translations\n const recentlyQueued = new Set<string>()\n // Set to track timeout ids for cleanup\n const pendingTimeouts = new Set<ReturnType<typeof setTimeout>>()\n\n // Track translation errors\n const translationErrors = new Map<string, string>()\n\n // Internal translation logic shared by l and lr\n const translateInternal = (\n text: string,\n ctx?: string,\n originalLang?: string,\n toLang?: string,\n reactive = false\n ) => {\n if (reactive) {\n void currentLanguage.value // For Vue reactivity\n }\n const from = originalLang || ltDefaults.orig || ''\n const to = toLang || currentLanguage.value\n\n // Skip translation if source and target languages are the same\n if (from === to) {\n return text\n }\n\n // Use provided context or global defaults, but don't fallback to 'ui' if ctx is explicitly provided\n const effectiveCtx = ctx !== undefined ? ctx : ltDefaults.ctx || 'ui'\n const baseKey = `${text}|${effectiveCtx}`\n // The caches are scoped to currentLanguage (cleared on language switch), so an\n // unqualified key is only valid when translating INTO the interface language.\n // Explicit targets (lr(text, ctx, from, to)) must carry the language pair in the\n // key, otherwise translations to different targets collide on the same entry.\n const cacheKey = to !== currentLanguage.value ? `${baseKey}|${from}|${to}` : baseKey\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n\n // Return cached translation if available\n if (cache[cacheKey]) {\n return cache[cacheKey]\n }\n\n // Fall back to a synchronous SSR seed (live translations above take precedence).\n const seeded = getSeed(to, text, effectiveCtx)\n if (seeded) {\n return seeded\n }\n\n // Check if we have a recorded error for this translation\n const errorKey = `${text}|${effectiveCtx}|${from}|${to}`\n if (translationErrors.has(errorKey)) {\n return text // Return original text for failed translations\n }\n\n // Check if we've recently queued this translation\n const languageCacheKey = `${baseKey}|${from}|${to}`\n if (recentlyQueued.has(languageCacheKey)) {\n return text\n }\n\n // Cold miss: let the host record it so it can warm the string after render.\n options.onTranslationMiss?.({ text, ctx: effectiveCtx, from, to })\n\n // Queue for translation, pass __explicitToLang if toLang is set\n batching.queueTranslation(text, effectiveCtx, from, to, cacheKey, toLang !== undefined)\n\n // Mark as recently queued\n recentlyQueued.add(languageCacheKey)\n\n // Clear the recently queued cache after a short delay\n // Use a shorter delay for tests to allow retries\n const clearDelay = 100 // Always use short delay for faster updates\n const timeoutId = setTimeout(() => {\n recentlyQueued.delete(languageCacheKey)\n pendingTimeouts.delete(timeoutId)\n }, clearDelay)\n pendingTimeouts.add(timeoutId)\n\n // Return original text for now (will be updated when translation arrives)\n return text\n }\n\n /**\n * l(): Non-reactive translation for plain JavaScript usage.\n * Returns translation or original text. Does NOT auto-update on language change.\n */\n const l = (text: string, ctx?: string, originalLang?: string, toLang?: string) =>\n translateInternal(text, ctx, originalLang, toLang, false)\n\n /**\n * lr(): Reactive translation for Vue usage.\n * Returns translation or original text. Auto-updates on language change (reactive).\n * Use in templates or computed properties.\n */\n const lr = (text: string, ctx?: string, originalLang?: string, toLang?: string) =>\n translateInternal(text, ctx, originalLang, toLang, true)\n\n /**\n * peekTranslation(): read-only lookup with NO queueing side effect. Returns a\n * live-cached or seeded translation, else the original text. Used on the server\n * so `<lt>` emits a seeded translation without queuing a doomed SSR request.\n */\n const peekTranslation = (text: string, ctx?: string, toLang?: string): string => {\n const effectiveCtx = ctx !== undefined ? ctx : ltDefaults.ctx || 'ui'\n const from = ltDefaults.orig || ''\n const to = toLang || currentLanguage.value\n if (from === to) return text\n const baseKey = `${text}|${effectiveCtx}`\n const cacheKey = to !== currentLanguage.value ? `${baseKey}|${from}|${to}` : baseKey\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n return cache[cacheKey] || getSeed(to, text, effectiveCtx) || text\n }\n\n /**\n * warmTranslations(): fetch translations for the given keys and merge them into\n * the SSR seed. Returns the resolved `\"text|ctx\" → translation` map for `lang`\n * so the host can persist it (e.g. Redis) and serialize it into the SSR payload.\n */\n const warmTranslations = async (\n keys: Array<{ text: string; ctx?: string }>,\n lang: string,\n from: string = ltDefaults.orig || ''\n ): Promise<Record<string, string>> => {\n const valid = keys.filter((k) => k && k.text)\n if (valid.length === 0) return {}\n\n const items = valid.map((k) => ({\n [API_FIELD_TEXT]: k.text,\n [API_FIELD_FROM]: from,\n [API_FIELD_TO]: lang,\n [API_FIELD_CTX]: k.ctx ?? ltDefaults.ctx ?? 'ui'\n }))\n\n const results = await translateBatch(items, {\n translatorHost,\n apiKey: options.apiKey,\n apiKeyEnv: options.apiKeyEnv\n })\n\n const resolved: Record<string, string> = {}\n results.forEach((res, i) => {\n const src = valid[i]\n const translated = res?.[API_FIELD_TEXT]\n if (src && translated && translated !== src.text) {\n const ctx = src.ctx ?? ltDefaults.ctx ?? 'ui'\n resolved[`${src.text}|${ctx}`] = translated\n }\n })\n\n if (Object.keys(resolved).length > 0) seedTranslations({ [lang]: resolved })\n return resolved\n }\n\n const fetchAndCacheBatch = async (\n items: { [API_FIELD_TEXT]: string; [API_FIELD_CTX]?: string }[],\n from?: string,\n to = currentLanguage.value,\n globalCtx?: string\n ) => {\n if (items.length === 0) return\n\n // Use global defaults for from language if not provided\n const effectiveFrom = from || ltDefaults.orig || ''\n\n // Skip translation if source and target languages are the same\n if (effectiveFrom === to) {\n return\n }\n\n isLoading.value = true\n\n try {\n // Use global context if provided, otherwise fall back to global defaults or 'ui'\n const effectiveCtx = globalCtx || ltDefaults.ctx || 'ui'\n\n const response = await fetch(`${translatorHost}/translate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n translations: items.map((item) => ({\n [API_FIELD_TEXT]: item[API_FIELD_TEXT],\n [API_FIELD_CTX]: item[API_FIELD_CTX] || effectiveCtx\n })),\n [API_FIELD_FROM]: effectiveFrom,\n [API_FIELD_TO]: to\n })\n })\n\n if (!response.ok) {\n throw new Error(`Translation request failed: ${response.status}`)\n }\n\n const result = await response.json()\n\n // Handle top-level error responses\n if (result[API_FIELD_ERROR]) {\n devDebug('[useLangie] Top-level API error:', result[API_FIELD_ERROR])\n\n // Create error responses for all items\n const errorResponses = items.map((item) => ({\n [API_FIELD_TEXT]: item[API_FIELD_TEXT],\n [API_FIELD_ERROR]: result[API_FIELD_ERROR]\n }))\n\n // Process error responses\n errorResponses.forEach((translation: TranslationWithContext, index: number) => {\n const item = items[index]\n const originalText = item?.[API_FIELD_TEXT]\n if (!originalText) {\n return\n }\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n devDebug(\n '[useLangie] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n\n // Record the error for future reference\n const errorKey = `${originalText}|${item[API_FIELD_CTX] || effectiveCtx}|${effectiveFrom}|${to}`\n translationErrors.set(errorKey, translation[API_FIELD_ERROR])\n\n return // Don't cache translations with errors\n }\n })\n\n return // Skip normal processing\n }\n\n if (result[API_FIELD_TRANSLATIONS]) {\n result[API_FIELD_TRANSLATIONS].forEach(\n (translation: TranslationWithContext, index: number) => {\n const item = items[index]\n const originalText = item?.[API_FIELD_TEXT]\n if (!originalText) {\n return\n }\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n devDebug(\n '[useLangie] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n return // Don't cache translations with errors\n }\n\n // Handle language detection response\n if (translation[API_FIELD_FROM] && !translation[API_FIELD_TEXT]) {\n // Не кешируем детекцию\n return\n }\n\n // Handle translation response\n const translatedText = translation[API_FIELD_TEXT]\n if (translatedText) {\n // Check if the target language is still current\n if (to !== currentLanguage.value) {\n devDebug('[useLangie] Skipping outdated translation (batch):', {\n original: originalText,\n translated: translatedText,\n requestedLanguage: to,\n currentLanguage: currentLanguage.value\n })\n return\n }\n\n // Skip caching if translation equals original text\n if (translatedText === originalText) {\n devDebug('[useLangie] Skipping cache for identical translation (batch):', {\n original: originalText,\n translated: translatedText,\n context: item[API_FIELD_CTX] || effectiveCtx\n })\n return\n }\n\n // Use the context from the original item, not from the response\n const originalCtx = item[API_FIELD_CTX]\n const translationCtx = originalCtx !== undefined ? originalCtx : effectiveCtx\n const cacheKey = `${originalText}|${translationCtx}`\n const cache = translationCtx === 'ui' ? uiTranslations : translations\n cache[cacheKey] = translatedText\n\n // Debug logging\n devDebug('[useLangie] Cached translation (batch):', {\n original: originalText,\n translated: translatedText,\n context: translationCtx,\n cacheKey,\n language: to\n })\n\n // Save to localStorage\n saveCachedTranslations()\n }\n }\n )\n }\n } catch (error) {\n console.error('[useLangie] Translation error:', error)\n } finally {\n isLoading.value = false\n }\n }\n\n // Watch for language changes - load translations for new language\n watch(currentLanguage, () => {\n // Clear recently queued cache to prevent race conditions\n recentlyQueued.clear()\n\n // Load cached translations for new language\n loadCachedTranslations()\n\n // Cleanup batching to cancel pending requests\n batching.cleanup()\n })\n\n return {\n // Core functionality\n availableLanguages,\n translations,\n uiTranslations,\n currentLanguage,\n isLoading,\n setLanguage,\n fetchLanguages,\n invalidateLanguages,\n translatorHost,\n\n // Translation functions\n l,\n lr,\n peekTranslation,\n fetchAndCacheBatch,\n\n // SSR translation seam\n seedTranslations,\n warmTranslations,\n\n // Error handling\n getTranslationError: (text: string, ctx?: string, from?: string, to?: string) => {\n const effectiveCtx = ctx !== undefined ? ctx : ltDefaults.ctx || 'ui'\n const effectiveFrom = from || ltDefaults.orig || ''\n const effectiveTo = to || currentLanguage.value\n const errorKey = `${text}|${effectiveCtx}|${effectiveFrom}|${effectiveTo}`\n return translationErrors.get(errorKey) || null\n },\n\n // Utility functions\n cleanup: () => {\n clearTranslations()\n batching.cleanup()\n // Очистка всех таймеров\n pendingTimeouts.forEach((id) => clearTimeout(id))\n pendingTimeouts.clear()\n translationErrors.clear()\n },\n getBatchingStats: () => batching.getStats(),\n\n // lt component defaults management\n setLtDefaults,\n getLtDefaults\n }\n}\n\n// --- GLOBAL SINGLETON LOGIC ---\n// Always use window.__LANGIE_SINGLETON__ as the source of truth\nfunction getGlobalLangieInstance(): LangieInstance | null {\n if (typeof window !== 'undefined') {\n return (\n (window as unknown as { __LANGIE_SINGLETON__?: LangieInstance }).__LANGIE_SINGLETON__ || null\n )\n }\n return globalLangieInstance\n}\nfunction setGlobalLangieInstance(instance: LangieInstance, options?: TranslatorOptions) {\n if (typeof window !== 'undefined') {\n ;(window as unknown as { __LANGIE_SINGLETON__?: LangieInstance }).__LANGIE_SINGLETON__ =\n instance\n if (options && options.translatorHost) {\n safeLocalStorageAccess(() =>\n localStorage.setItem('__LANGIE_SINGLETON_URL__', options.translatorHost!)\n )\n }\n }\n globalLangieInstance = instance\n}\n\nexport function useLangie(options: TranslatorOptions = {}) {\n const globalInstance: LangieInstance | null = getGlobalLangieInstance()\n\n // If no options or options match, always return the global instance if it exists\n if (globalInstance) {\n const currentHost = globalInstance.translatorHost\n const newHost = options.translatorHost\n if (!options.translatorHost || currentHost === newHost) {\n return globalInstance\n }\n }\n\n // Otherwise, create a new instance\n const instance: LangieInstance = createLangieInstance(options)\n setGlobalLangieInstance(instance, options)\n return instance\n}\n\nexport function __resetLangieSingletonForTests() {\n if (globalLangieInstance) {\n globalLangieInstance.cleanup()\n }\n globalLangieInstance = null\n\n // Clear localStorage backup\n if (typeof window !== 'undefined') {\n safeLocalStorageAccess(() => localStorage.removeItem('__LANGIE_SINGLETON_URL__'))\n try {\n delete (window as unknown as Record<string, unknown>).__LANGIE_SINGLETON__\n } catch (e) {\n devDebug('[useLangie] window singleton delete error:', e)\n }\n }\n\n __resetLangieCoreForTests()\n}\n\n// Global lt component defaults management\nexport function setLtDefaults(defaults: { ctx?: string; orig?: string }) {\n const instance = getGlobalLangieInstance()\n if (instance && instance.setLtDefaults) {\n instance.setLtDefaults(defaults)\n }\n}\n\nexport function getLtDefaults() {\n const instance = getGlobalLangieInstance()\n if (instance && instance.getLtDefaults) {\n return instance.getLtDefaults()\n }\n return { ctx: 'ui', orig: '' }\n}\n","/**\n * Default API configuration constants\n */\nexport const DEFAULT_API_HOST = 'https://api.langie.uk/v1'\n\n/**\n * Development/Demo API host for local testing.\n * Uses the keyless first-party `/frontend` proxy (the backend injects\n * PAGES_API_KEY); the raw `/v1` endpoints require a client API key.\n */\nexport const DEV_API_HOST = 'http://localhost:8081/frontend'\n\n/**\n * Default translator options\n */\nexport const DEFAULT_TRANSLATOR_OPTIONS = {\n translatorHost: DEFAULT_API_HOST,\n defaultLanguage: 'en',\n fallbackLanguage: 'en'\n} as const\n\n/**\n * API field constants\n * Used throughout the SDK to ensure consistency\n */\n\n// Translation text field\nexport const API_FIELD_TEXT = 't'\n\n// Source language field\nexport const API_FIELD_FROM = 'from'\n\n// Target language field\nexport const API_FIELD_TO = 'to'\n\n// Context field\nexport const API_FIELD_CTX = 'ctx'\n\n// Glossary term-forcing fields (optional): render API_FIELD_GLOSSARY_SRC as exactly\n// API_FIELD_GLOSSARY_TGT so a headword and its example stay consistent. Only\n// providers with an inline glossary honour them; the API ignores the pair otherwise.\nexport const API_FIELD_GLOSSARY_SRC = 'gs'\nexport const API_FIELD_GLOSSARY_TGT = 'gt'\n\n// Translated text field (same as text field for response)\nexport const API_FIELD_TRANSLATED = 't'\n\n// Translations array field\nexport const API_FIELD_TRANSLATIONS = 'translations'\n\n// Error field for API responses\nexport const API_FIELD_ERROR = 'error'\n\n// Cloudflare Turnstile token field — anti-abuse on the keyless /frontend/translate proxy\nexport const API_FIELD_TURNSTILE = 'turnstileToken'\n","/**\n * Core translation functions\n */\nimport type {\n TranslateRequestBody,\n TranslateServiceResponse,\n TranslatorLanguage,\n TranslatorOptions\n} from './types'\nimport {\n API_FIELD_TEXT,\n API_FIELD_FROM,\n API_FIELD_TO,\n API_FIELD_CTX,\n API_FIELD_GLOSSARY_SRC,\n API_FIELD_GLOSSARY_TGT,\n API_FIELD_TRANSLATIONS,\n API_FIELD_ERROR,\n API_FIELD_TURNSTILE\n} from './constants'\n\nconst DEFAULT_TRANSLATOR_HOST = 'http://localhost:8081'\nconst DEFAULT_API_KEY_ENV = 'TRANSLATOR_API_KEY'\n\n/**\n * Resolve the API key: explicit `apiKey` wins, then a host-configured env var\n * name (`apiKeyEnv`), then the default `TRANSLATOR_API_KEY`.\n */\nfunction resolveApiKey(options: TranslatorOptions): string | undefined {\n if (options.apiKey) return options.apiKey\n const env = typeof process !== 'undefined' ? process.env : undefined\n if (!env) return undefined\n return env[options.apiKeyEnv || DEFAULT_API_KEY_ENV]\n}\n\n// Optional glossary pair, included only when both terms are set. Shared by the\n// cache key and the request body so a forced request never collides with a plain one.\nfunction glossaryFields(t: TranslateRequestBody): Record<string, string> {\n const src = t[API_FIELD_GLOSSARY_SRC]\n const tgt = t[API_FIELD_GLOSSARY_TGT]\n return src && tgt ? { [API_FIELD_GLOSSARY_SRC]: src, [API_FIELD_GLOSSARY_TGT]: tgt } : {}\n}\n\n// --- Translation cache ---\nconst translationCache = new Map<string, Promise<TranslateServiceResponse[]>>()\n\nfunction getTranslationCacheKey(\n serviceTranslations: TranslateRequestBody[],\n options: TranslatorOptions\n): string {\n // Create a stable cache key based on translations and options\n return JSON.stringify({\n translations: serviceTranslations.map((t) => ({\n [API_FIELD_TEXT]: t[API_FIELD_TEXT],\n [API_FIELD_FROM]: t[API_FIELD_FROM],\n [API_FIELD_TO]: t[API_FIELD_TO],\n [API_FIELD_CTX]: t[API_FIELD_CTX] || options[API_FIELD_CTX] || 'ui',\n ...glossaryFields(t)\n })),\n host: options.translatorHost || DEFAULT_TRANSLATOR_HOST,\n context: options[API_FIELD_CTX] || 'ui'\n })\n}\n\n/**\n * Translates a batch of texts\n *\n * @param translations Array of translation requests\n * @param options Configuration options\n * @returns Array of translated texts\n */\nexport async function translateBatch(\n translations: TranslateRequestBody[] = [],\n options: TranslatorOptions = {}\n): Promise<TranslateServiceResponse[]> {\n // const startTime = Date.now()\n\n // try {\n // console.debug('[translator-sdk] translateBatch called', {\n // count: translations.length,\n // sample: translations.slice(0, 3).map((t) => ({\n // text: t.text?.slice?.(0, 30) ?? '',\n // from: t.from_lang,\n // to: t.to_lang\n // })),\n // opts: { ...options }\n // })\n // } catch (_) {\n // // Ignore logging errors – never block translation\n // }\n\n if (!Array.isArray(translations) || translations.length === 0) {\n // console.error('[translator-sdk] Invalid translations input:', { translations })\n throw new Error('translations must be a non-empty array')\n }\n\n const translatorHost = options.translatorHost || DEFAULT_TRANSLATOR_HOST\n const apiKey = resolveApiKey(options)\n\n // console.debug('[translator-sdk] Configuration', {\n // translatorHost,\n // hasApiKey: !!apiKey,\n // apiKeyLength: apiKey?.length || 0\n // })\n\n // Partition translations: identical language pairs can be returned as-is\n const serviceTranslations: TranslateRequestBody[] = []\n const indexMap: number[] = []\n\n translations.forEach((tr, idx) => {\n const from = (tr[API_FIELD_FROM] || '').toLowerCase()\n const to = (tr[API_FIELD_TO] || '').toLowerCase()\n if (from === to) {\n // console.debug('[translator-sdk] Skipping translation (same language)', { from, to, text: tr.t?.slice(0, 20) })\n return // no need to translate\n }\n serviceTranslations.push(tr)\n indexMap.push(idx)\n })\n\n // console.debug('[translator-sdk] Translation partitioning', {\n // total: translations.length,\n // needsTranslation: serviceTranslations.length,\n // skipped: translations.length - serviceTranslations.length\n // })\n\n let serviceResults: TranslateServiceResponse[] = []\n if (serviceTranslations.length > 0) {\n // Check cache first\n const cacheKey = getTranslationCacheKey(serviceTranslations, options)\n if (translationCache.has(cacheKey)) {\n // console.debug('[translator-sdk] Cache hit for translation batch')\n serviceResults = await translationCache.get(cacheKey)!\n } else {\n // const requestStartTime = Date.now()\n // console.debug('[translator-sdk] Sending request to translator', {\n // host: translatorHost,\n // apiKeySnippet: apiKey ? `${apiKey.slice(0, 4)}…${apiKey.slice(-4)}` : 'none',\n // batchCount: serviceTranslations.length,\n // requestSize: JSON.stringify({ translations: serviceTranslations }).length\n // })\n\n const translationPromise = (async () => {\n try {\n // Fresh Turnstile token per flush (single-use); only the keyless\n // /frontend/translate proxy requires it, other hosts ignore the field.\n const turnstileToken = options.getTurnstileToken\n ? await options.getTurnstileToken()\n : undefined\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), 5000) // 5s timeout\n\n const resp = await fetch(`${translatorHost}/translate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { Authorization: `Bearer ${apiKey}`, 'X-Api-Key': apiKey } : {})\n },\n body: JSON.stringify({\n [API_FIELD_TRANSLATIONS]: serviceTranslations.map((t) => ({\n [API_FIELD_TEXT]: t[API_FIELD_TEXT],\n [API_FIELD_FROM]: t[API_FIELD_FROM],\n [API_FIELD_TO]: t[API_FIELD_TO],\n [API_FIELD_CTX]: t[API_FIELD_CTX] || options[API_FIELD_CTX] || 'ui',\n ...glossaryFields(t)\n })),\n [API_FIELD_CTX]: options[API_FIELD_CTX] || 'ui',\n ...(turnstileToken ? { [API_FIELD_TURNSTILE]: turnstileToken } : {})\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeoutId)\n // const requestDuration = Date.now() - requestStartTime\n\n // console.debug('[translator-sdk] Translator response received', {\n // status: resp.status,\n // statusText: resp.statusText,\n // duration: `${requestDuration}ms`,\n // contentType: resp.headers.get('content-type'),\n // contentLength: resp.headers.get('content-length')\n // })\n\n if (!resp.ok) {\n console.error(\n '[translator-sdk] Translator error response:',\n resp.status,\n resp.statusText\n )\n throw new Error(`Translator service error: ${resp.status} ${resp.statusText}`)\n }\n\n let parsed: {\n translations?: TranslateServiceResponse[]\n t?: string\n error?: string\n } | null\n try {\n parsed = await resp.clone().json()\n // console.debug('[translator-sdk] Response parsed successfully', {\n // hasTranslations: !!parsed?.translations,\n // translationCount: parsed?.translations?.length || 0,\n // hasLegacyT: !!parsed?.t\n // })\n } catch (jsonErr) {\n console.error('[translator-sdk] Failed to parse JSON response:', jsonErr)\n throw new Error(`Failed to parse JSON response: ${jsonErr}`)\n }\n\n // if (parsed) {\n // console.debug(\n // '[translator-sdk] Translator response sample',\n // JSON.stringify(parsed).slice(0, 500)\n // )\n // }\n\n const data = parsed || {}\n\n // Handle top-level error responses\n if (data[API_FIELD_ERROR]) {\n console.warn(`[translator-sdk] Top-level API error:`, data[API_FIELD_ERROR])\n\n // Create error responses for all translations\n return serviceTranslations.map((translation) => ({\n [API_FIELD_TEXT]: translation[API_FIELD_TEXT],\n [API_FIELD_ERROR]: data[API_FIELD_ERROR]\n }))\n }\n\n const results = Array.isArray(data[API_FIELD_TRANSLATIONS])\n ? data[API_FIELD_TRANSLATIONS].map((translation, index) => {\n const originalText = serviceTranslations[index]?.[API_FIELD_TEXT] || ''\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n console.warn(\n `[translator-sdk] Translation error for \"${originalText}\":`,\n translation[API_FIELD_ERROR]\n )\n return {\n [API_FIELD_TEXT]: originalText, // Return original text on error\n [API_FIELD_ERROR]: translation[API_FIELD_ERROR]\n }\n }\n\n // Handle language detection response\n if (translation[API_FIELD_FROM] && !translation[API_FIELD_TEXT]) {\n return {\n [API_FIELD_TEXT]: originalText, // For detection, return original text\n [API_FIELD_FROM]: translation[API_FIELD_FROM]\n }\n }\n\n // Handle translation response\n return {\n [API_FIELD_TEXT]: translation[API_FIELD_TEXT] || originalText\n }\n })\n : data[API_FIELD_TEXT]\n ? [{ [API_FIELD_TEXT]: data[API_FIELD_TEXT] }]\n : []\n\n // console.debug('[translator-sdk] Service results processed', {\n // resultCount: results.length,\n // expectedCount: serviceTranslations.length\n // })\n\n return results\n } catch (error: unknown) {\n // Remove from cache on error\n translationCache.delete(cacheKey)\n\n if (error instanceof Error && error.name === 'AbortError') {\n const message = `Translator request to ${translatorHost} timed out after 5 seconds.`\n console.error(message)\n throw new Error(message)\n }\n const message = `Failed to connect to translator at ${translatorHost}. Is the service running?`\n console.error(message)\n throw new Error(message)\n }\n })()\n\n // Cache the promise\n translationCache.set(cacheKey, translationPromise)\n serviceResults = await translationPromise\n }\n }\n\n // Assemble final results in original order\n const final = translations.map((tr, idx) => {\n const from = (tr[API_FIELD_FROM] || '').toLowerCase()\n const to = (tr[API_FIELD_TO] || '').toLowerCase()\n if (from === to) return { [API_FIELD_TEXT]: tr[API_FIELD_TEXT] }\n\n const svcIdx = indexMap.indexOf(idx)\n if (svcIdx !== -1) return serviceResults[svcIdx] || { [API_FIELD_TEXT]: tr[API_FIELD_TEXT] }\n return { [API_FIELD_TEXT]: tr[API_FIELD_TEXT] }\n })\n\n // const totalDuration = Date.now() - startTime\n // console.debug('[translator-sdk] translateBatch completed', {\n // totalDuration: `${totalDuration}ms`,\n // resultCount: final.length,\n // successCount: final.filter(r => r.translated && r.translated !== r.text).length\n // })\n\n return final as TranslateServiceResponse[]\n}\n\n// --- Cache management functions ---\nexport function clearTranslationCache(): void {\n translationCache.clear()\n}\n\nexport function getTranslationCacheSize(): number {\n return translationCache.size\n}\n\n/**\n * Vendor/legacy codes whose primary subtag isn't their BCP-47 base language.\n * Folding `kazlat` → `kk` treats Latin and Cyrillic Kazakh as siblings, so a\n * popularity-passing variant keeps its below-floor sibling visible (both scripts\n * stay selectable). It does NOT dedup them — both rows survive.\n */\nconst BASE_CODE_ALIASES: Record<string, string> = {\n kazlat: 'kk' // Kazakh (Latin) — vendor code, not \"kk-latn\"\n}\n\n/**\n * Reduce a language code to its BCP-47 primary subtag, so script/region variants\n * share a base: `sr-cyrl`/`sr-latn` → `sr`, `kk`/`kazlat` → `kk`.\n */\nexport function baseLanguageCode(code: string): string {\n const c = (code || '').trim().toLowerCase().replace(/_/g, '-')\n return BASE_CODE_ALIASES[c] ?? (c.split('-')[0] || c)\n}\n\n/**\n * Fetches available languages from the translation service\n *\n * @param options Configuration options\n * @returns Array of available languages\n */\nexport async function fetchAvailableLanguages(\n options: TranslatorOptions = {}\n): Promise<TranslatorLanguage[]> {\n // const startTime = Date.now()\n\n // console.debug('[translator-sdk] fetchAvailableLanguages called', { options })\n\n const translatorHost = options.translatorHost || DEFAULT_TRANSLATOR_HOST\n const apiKey = resolveApiKey(options)\n // Popularity filtering is opt-in. Default 0 returns the full catalog so the\n // caller (e.g. a searchable picker) gets every language and every script\n // variant; a host env var must not silently prune the list.\n const minPop = options.minPopularity !== undefined ? Number(options.minPopularity) : 0\n\n // console.debug('[translator-sdk] Languages request config', {\n // translatorHost,\n // hasApiKey: !!apiKey,\n // minPopularity: minPop,\n // country: options.country,\n // region: options.region\n // })\n\n const queryParams = []\n if (options.country) queryParams.push(`country=${encodeURIComponent(options.country)}`)\n if (options.region) queryParams.push(`region=${encodeURIComponent(options.region)}`)\n const queryStr = queryParams.length ? `?${queryParams.join('&')}` : ''\n\n const requestUrl = `${translatorHost}/languages${queryStr}`\n\n try {\n const resp = await fetch(requestUrl, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { Authorization: `Bearer ${apiKey}`, 'X-Api-Key': apiKey } : {})\n }\n })\n\n if (!resp.ok) {\n throw new Error(`Translator languages error: ${resp.status}`)\n }\n\n const data = await resp.json()\n const languages: TranslatorLanguage[] = Array.isArray(data) ? data : data.languages || []\n\n if (minPop <= 0) return languages\n\n const passes = (lang: TranslatorLanguage): boolean =>\n lang.popularity === undefined || lang.popularity === null || Number(lang.popularity) >= minPop\n\n // Keep every script/region variant of a base language that has at least one\n // passing entry, so a low-popularity variant (e.g. Kazakh Cyrillic with\n // popularity 0) survives next to its popular sibling and the UI can still\n // offer the \"which variant?\" choice. Otherwise a flat floor splits the pair.\n const keptBases = new Set(languages.filter(passes).map((l) => baseLanguageCode(l.code)))\n return languages.filter((lang) => passes(lang) || keptBases.has(baseLanguageCode(lang.code)))\n } catch (error) {\n console.error('[translator-sdk] Languages fetch error:', error)\n throw error\n }\n}\n","import { ref, reactive } from 'vue'\nimport type { Ref } from 'vue'\nimport type { TranslatorOptions, TranslatorLanguage } from '../types'\nimport { DEFAULT_API_HOST } from '../constants'\nimport { devDebug } from '../utils/debug'\nimport { getCountryCode } from '../utils/getCountryCode'\nimport { setCache, getCache, clearCache } from '../utils/cache'\nimport { localizeLanguageNames } from '../utils/localizeLanguageNames'\n\nconst availableLanguages: Ref<TranslatorLanguage[]> = ref([])\nconst translations: { [key: string]: string } = reactive({})\nconst uiTranslations: { [key: string]: string } = reactive({})\nconst currentLanguage: Ref<string> = ref('en')\n\n// Global state for the translator host\nlet _translatorHost: string = DEFAULT_API_HOST\n\n// Prevent repeated auto-selection of interface language\nlet _autoSelected = false\n\n// Module-scope cache for languages so multiple composable instances / hot-reload don't refetch\nlet _languagesCache: TranslatorLanguage[] | null = null\nlet _languagesCacheAt = 0\nlet _languagesPromise: Promise<TranslatorLanguage[]> | null = null\n\nconst LANGUAGES_CACHE_KEY = 'langie_languages_cache'\n\n// Test reset function\nexport function __resetLangieCoreForTests() {\n availableLanguages.value = []\n Object.keys(translations).forEach((key) => delete translations[key])\n Object.keys(uiTranslations).forEach((key) => delete uiTranslations[key])\n currentLanguage.value = 'en'\n _translatorHost = DEFAULT_API_HOST\n _autoSelected = false\n _languagesCache = null\n _languagesCacheAt = 0\n _languagesPromise = null\n\n // Clear localStorage for tests\n if (typeof window !== 'undefined') {\n localStorage.removeItem('interface_language')\n clearCache() // Clear all langie cache items\n }\n}\n\nexport function useLangieCore(options: TranslatorOptions = {}) {\n // If a host is provided in options, it overrides the global host for all instances.\n // This ensures that the first initialization (e.g., from App.vue) sets the host correctly.\n if (options.translatorHost) {\n _translatorHost = options.translatorHost\n }\n\n const translatorHost = _translatorHost // Use the shared host\n const defaultLanguage = options.defaultLanguage || 'en'\n\n const isLoading = ref(false)\n\n // Initialize shared currentLanguage with default if not already set\n // Always respect the defaultLanguage option if it's different from 'en'\n if (defaultLanguage !== 'en' && currentLanguage.value === 'en') {\n currentLanguage.value = defaultLanguage\n }\n\n // Restore saved language from localStorage if available\n if (typeof window !== 'undefined' && currentLanguage.value === 'en') {\n const savedLanguage = localStorage.getItem('interface_language')\n if (savedLanguage) {\n currentLanguage.value = savedLanguage\n }\n }\n\n // Seed the language list from localStorage for an instant first paint, but\n // deliberately DON'T prime _languagesCache: leaving it null makes the first\n // fetchLanguages() of the session revalidate against the network instead of\n // short-circuiting on the cache. Stale-while-revalidate — the cache paints\n // immediately, the fetched catalog is the source of truth. Without this a list\n // cached during a backend outage (e.g. a truncated fallback) would stick for\n // the full 7-day TTL and the picker would never recover.\n if (typeof window !== 'undefined') {\n const cachedLanguages = getCache<TranslatorLanguage[]>(LANGUAGES_CACHE_KEY)\n if (cachedLanguages && availableLanguages.value.length === 0) {\n availableLanguages.value = cachedLanguages\n devDebug('[useLangie] Seeded languages from cache (will revalidate):', cachedLanguages.length)\n } else if (cachedLanguages) {\n devDebug(\n '[useLangie] Cache exists but languages already loaded:',\n availableLanguages.value.length\n )\n } else {\n devDebug('[useLangie] No cached languages found')\n }\n }\n\n // Fill each language's `search_alias` with its name in `lang` so the picker's\n // fuzzy search matches names typed in the user's own language/script. Fire and\n // forget: cached per language, swaps the list in once resolved (unless a\n // concurrent refetch already replaced it).\n const applyLocalizedNames = (lang: string) => {\n const base = availableLanguages.value\n if (!base.length) return\n localizeLanguageNames(base, lang, { translatorHost })\n .then((localized) => {\n if (localized !== base && availableLanguages.value === base) {\n availableLanguages.value = localized\n }\n })\n .catch(() => {})\n }\n\n const setLanguage = (lang: string) => {\n if (lang && lang !== currentLanguage.value) {\n // debugOnlyDev(`[useLangie] setLanguage: ${currentLanguage.value} → ${lang}`)\n }\n currentLanguage.value = lang\n\n // Save to localStorage for persistence\n if (typeof window !== 'undefined') {\n localStorage.setItem('interface_language', lang)\n }\n\n applyLocalizedNames(lang)\n }\n\n const fetchLanguages = async (\n opts: { force?: boolean; country?: string; maxAgeMs?: number } = {}\n ) => {\n const { force = false, country: explicitCountry, maxAgeMs } = opts\n // const startTime = Date.now()\n\n // A cached catalogue is fresh unless maxAgeMs is set and it has aged past it,\n // giving hosts a short cross-session TTL without throwing away the cache via force.\n const cacheFresh =\n !!_languagesCache && (maxAgeMs === undefined || Date.now() - _languagesCacheAt < maxAgeMs)\n\n devDebug('[useLangie] fetchLanguages called:', {\n force,\n maxAgeMs,\n cacheFresh,\n hasCache: !!_languagesCache,\n hasPromise: !!_languagesPromise,\n availableLanguagesLength: availableLanguages.value.length\n })\n\n if (!force) {\n if (cacheFresh) {\n devDebug('[useLangie] Returning cached languages:', _languagesCache!.length)\n return _languagesCache!\n }\n if (_languagesPromise) {\n devDebug('[useLangie] Returning existing promise')\n return _languagesPromise\n }\n }\n\n try {\n // Determine country hint - but only if we don't have cached languages\n let countryHint = explicitCountry || null\n if (\n !countryHint &&\n !_languagesCache &&\n availableLanguages.value &&\n availableLanguages.value.length\n ) {\n const currentLang = currentLanguage.value\n const entry = availableLanguages.value.find(\n (l: TranslatorLanguage) => l.code === currentLang\n )\n if (entry) {\n const c = Array.isArray(entry.flag_country)\n ? entry.flag_country[0]\n : typeof entry.flag_country === 'string'\n ? (entry.flag_country as string).split(',')[0]\n : null\n if (c) countryHint = c.toUpperCase()\n }\n }\n if (!countryHint && !_languagesCache && typeof window !== 'undefined') {\n // Use only browser locale for country hint (synchronous)\n const cc = await getCountryCode()\n countryHint = cc\n }\n\n let url = '/languages'\n // Добавляем language и timezone\n const language =\n (typeof navigator !== 'undefined' && navigator.languages && navigator.languages[0]) ||\n (typeof navigator !== 'undefined' && navigator.language) ||\n ''\n const timezone =\n (typeof Intl !== 'undefined' && Intl.DateTimeFormat().resolvedOptions().timeZone) || ''\n const params = new URLSearchParams()\n if (countryHint) params.append('country', countryHint)\n if (language) params.append('language', language)\n if (timezone) params.append('timezone', timezone)\n if (Array.from(params).length > 0) url += `?${params.toString()}`\n\n // Note: /languages endpoint should NOT increase usage count\n _languagesPromise = fetch(`${translatorHost}${url}`).then((res) => res.json())\n const response = (await _languagesPromise) as\n | TranslatorLanguage[]\n | { languages: TranslatorLanguage[] }\n const rawList: TranslatorLanguage[] = Array.isArray(response)\n ? response\n : response.languages || []\n\n // normalise to expected structure\n const mapped: TranslatorLanguage[] = rawList.map(\n (lang: TranslatorLanguage & { flag_country?: string | string[] }) => {\n let flag = lang.flag_country || lang.code\n if (Array.isArray(flag)) {\n flag = flag[0]\n }\n return {\n ...lang,\n value: lang.code,\n flag_country: flag\n }\n }\n )\n\n // Keep only desired Serbian variants\n const filtered: TranslatorLanguage[] = mapped.filter((l) => {\n if (l.code.startsWith('sr')) {\n return l.code === 'sr-latn' || l.code === 'sr-cyrl'\n }\n return true\n })\n\n availableLanguages.value = filtered\n devDebug('[useLangie] Set availableLanguages:', filtered.length)\n\n // Save languages to localStorage with TTL (7 days for languages)\n if (typeof window !== 'undefined') {\n const saved = setCache(LANGUAGES_CACHE_KEY, filtered, 7 * 24 * 60 * 60 * 1000)\n devDebug(\n '[useLangie] Saved languages to cache:',\n saved ? 'success' : 'failed',\n filtered.length\n )\n }\n\n // Auto-select browser language only once if not previously saved\n if (!_autoSelected && !localStorage.getItem('interface_language')) {\n const locale =\n typeof navigator !== 'undefined'\n ? navigator.languages?.[0] || navigator.language || ''\n : ''\n const browserCode = locale.split('-')[0]\n\n if (browserCode) {\n let pick: TranslatorLanguage | undefined = undefined\n\n // Handle Serbian variants\n if (browserCode === 'sr') {\n const isLatin = /latn/i.test(locale) || locale === 'sr'\n const target = isLatin ? 'sr-latn' : 'sr-cyrl'\n pick = mapped.find((l) => l.value === target)\n } else if (browserCode === 'sh') {\n pick =\n mapped.find((l) => l.value === 'sr-latn') ||\n mapped.find((l) => l.code.startsWith('sr'))\n } else {\n // Try exact match first\n pick = mapped.find((l) => l.value === browserCode)\n\n // If no exact match, try prefix match\n if (!pick) {\n pick = mapped.find((l) => l.code.startsWith(browserCode))\n }\n }\n\n if (pick && pick.value) {\n setLanguage(pick.value)\n }\n }\n _autoSelected = true\n }\n _languagesCache = filtered\n _languagesCacheAt = Date.now()\n _languagesPromise = null\n\n applyLocalizedNames(currentLanguage.value)\n\n return filtered\n } catch (error) {\n // const totalDuration = Date.now() - startTime\n devDebug('[useLangie] Language fetch error:', { error })\n return []\n }\n }\n\n // Drop the cached catalogue so the next fetchLanguages() revalidates against the\n // network. Hosts call this on deploy (or a version-change signal) to bust a stale\n // list without waiting out the 7-day TTL.\n const invalidateLanguages = () => {\n _languagesCache = null\n _languagesCacheAt = 0\n _languagesPromise = null\n if (typeof window !== 'undefined') {\n clearCache(LANGUAGES_CACHE_KEY)\n }\n }\n\n const clearTranslations = () => {\n Object.keys(translations).forEach((key) => delete translations[key])\n Object.keys(uiTranslations).forEach((key) => delete uiTranslations[key])\n\n // Clear localStorage cache for translations only (preserve languages cache)\n if (typeof window !== 'undefined') {\n clearCache('translations_cache')\n clearCache('ui_translations_cache')\n }\n }\n\n return {\n availableLanguages,\n translations,\n uiTranslations,\n currentLanguage,\n isLoading,\n setLanguage,\n fetchLanguages,\n invalidateLanguages,\n clearTranslations,\n translatorHost\n }\n}\n","export function devDebug(...args: unknown[]) {\n if (import.meta.env && import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.debug(...args)\n }\n}\n","import * as ct from 'countries-and-timezones'\n\n// Get country from multiple sources with fallback\nexport async function getCountryCode(): Promise<string | null> {\n // Try locale first\n const localeCountry = getCountryCodeFromBrowser()\n if (localeCountry) return localeCountry\n\n // Try timezone\n const timezoneCountry = getCountryFromTimezone()\n if (timezoneCountry) return timezoneCountry\n\n // Try IP as last resort\n return await getCountryFromIP()\n}\n\n// Get country from timezone using countries-and-timezones library\nfunction getCountryFromTimezone(): string | null {\n try {\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone\n return getCountryFromTimezoneString(timezone)\n } catch (error) {\n return null\n }\n}\n\n// Helper function to get country code from timezone string\nexport function getCountryFromTimezoneString(timezone: string): string | null {\n try {\n const country = ct.getCountryForTimezone(timezone)\n return country?.id || null\n } catch (error) {\n return null\n }\n}\n\n// Get country from IP (requires external service)\nasync function getCountryFromIP(): Promise<string | null> {\n try {\n const response = await fetch('https://ipapi.co/json/')\n const data = await response.json()\n return data.country_code || null\n } catch (error) {\n return null\n }\n}\n\n// Get user's country code from browser locale\nexport function getCountryCodeFromBrowser(): string | null {\n const langs = navigator.languages || [navigator.language]\n for (const locale of langs) {\n const parts = locale.split('-')\n if (parts.length > 1) {\n return parts[1].toUpperCase()\n }\n }\n return null\n}\n","interface CacheItem<T> {\n data: T\n timestamp: number\n ttl: number\n}\n\ninterface CacheOptions {\n ttl?: number // Time to live in milliseconds\n maxSize?: number // Maximum size in bytes\n maxItems?: number // Maximum number of items\n}\n\nconst DEFAULT_TTL = 7 * 24 * 60 * 60 * 1000 // 7 days\nconst DEFAULT_MAX_SIZE = 2 * 1024 * 1024 // 2MB\nconst DEFAULT_MAX_ITEMS = 1000\n\nexport class CacheManager {\n private options: Required<CacheOptions>\n\n constructor(options: CacheOptions = {}) {\n this.options = {\n ttl: options.ttl || DEFAULT_TTL,\n maxSize: options.maxSize || DEFAULT_MAX_SIZE,\n maxItems: options.maxItems || DEFAULT_MAX_ITEMS\n }\n }\n\n set<T>(key: string, data: T, ttl?: number): boolean {\n if (typeof window === 'undefined') return false\n\n try {\n const item: CacheItem<T> = {\n data,\n timestamp: Date.now(),\n ttl: ttl || this.options.ttl\n }\n\n const serialized = JSON.stringify(item)\n const size = new Blob([serialized]).size\n\n // Check if adding this item would exceed max size\n if (size > this.options.maxSize) {\n console.warn(`[CacheManager] Item size ${size} exceeds max size ${this.options.maxSize}`)\n return false\n }\n\n // Clean up expired items and check total size\n this.cleanup()\n\n // Check if we have space after cleanup\n const currentSize = this.getCurrentSize()\n if (currentSize + size > this.options.maxSize) {\n console.warn(`[CacheManager] Cache would exceed max size after adding item`)\n return false\n }\n\n localStorage.setItem(key, serialized)\n return true\n } catch (error) {\n console.warn(`[CacheManager] Failed to set cache item ${key}:`, error)\n return false\n }\n }\n\n get<T>(key: string): T | null {\n if (typeof window === 'undefined') return null\n\n try {\n const item = localStorage.getItem(key)\n if (!item) return null\n\n const cacheItem: CacheItem<T> = JSON.parse(item)\n const now = Date.now()\n\n // Check if item is expired\n if (now - cacheItem.timestamp > cacheItem.ttl) {\n localStorage.removeItem(key)\n return null\n }\n\n return cacheItem.data\n } catch (error) {\n console.warn(`[CacheManager] Failed to get cache item ${key}:`, error)\n localStorage.removeItem(key) // Remove corrupted item\n return null\n }\n }\n\n remove(key: string): boolean {\n if (typeof window === 'undefined') return false\n\n try {\n localStorage.removeItem(key)\n return true\n } catch (error) {\n console.warn(`[CacheManager] Failed to remove cache item ${key}:`, error)\n return false\n }\n }\n\n clear(pattern?: string): void {\n if (typeof window === 'undefined') return\n\n try {\n if (pattern) {\n // Remove items matching pattern\n Object.keys(localStorage).forEach((key) => {\n if (key.includes(pattern)) {\n localStorage.removeItem(key)\n }\n })\n } else {\n // Remove all langie cache items\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n localStorage.removeItem(key)\n }\n })\n }\n } catch (error) {\n console.warn('[CacheManager] Failed to clear cache:', error)\n }\n }\n\n private cleanup(): void {\n if (typeof window === 'undefined') return\n\n try {\n const now = Date.now()\n const items: Array<{ key: string; size: number; timestamp: number }> = []\n\n // Collect all langie cache items with their sizes and timestamps\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n try {\n const item = localStorage.getItem(key)\n if (item) {\n const cacheItem: CacheItem<any> = JSON.parse(item)\n const size = new Blob([item]).size\n\n // Remove expired items\n if (now - cacheItem.timestamp > cacheItem.ttl) {\n localStorage.removeItem(key)\n return\n }\n\n items.push({\n key,\n size,\n timestamp: cacheItem.timestamp\n })\n }\n } catch (error) {\n // Remove corrupted items\n localStorage.removeItem(key)\n }\n }\n })\n\n // Sort by timestamp (oldest first)\n items.sort((a, b) => a.timestamp - b.timestamp)\n\n // Remove oldest items if we exceed max items\n while (items.length > this.options.maxItems) {\n const oldest = items.shift()\n if (oldest) {\n localStorage.removeItem(oldest.key)\n }\n }\n\n // Remove oldest items if we exceed max size\n let totalSize = items.reduce((sum, item) => sum + item.size, 0)\n while (totalSize > this.options.maxSize && items.length > 0) {\n const oldest = items.shift()\n if (oldest) {\n localStorage.removeItem(oldest.key)\n totalSize -= oldest.size\n }\n }\n } catch (error) {\n console.warn('[CacheManager] Failed to cleanup cache:', error)\n }\n }\n\n private getCurrentSize(): number {\n if (typeof window === 'undefined') return 0\n\n try {\n let totalSize = 0\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n const item = localStorage.getItem(key)\n if (item) {\n totalSize += new Blob([item]).size\n }\n }\n })\n return totalSize\n } catch (error) {\n console.warn('[CacheManager] Failed to calculate cache size:', error)\n return 0\n }\n }\n\n getStats(): { size: number; items: number; maxSize: number; maxItems: number } {\n if (typeof window === 'undefined') {\n return { size: 0, items: 0, maxSize: this.options.maxSize, maxItems: this.options.maxItems }\n }\n\n try {\n let totalSize = 0\n let itemCount = 0\n\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n const item = localStorage.getItem(key)\n if (item) {\n totalSize += new Blob([item]).size\n itemCount++\n }\n }\n })\n\n return {\n size: totalSize,\n items: itemCount,\n maxSize: this.options.maxSize,\n maxItems: this.options.maxItems\n }\n } catch (error) {\n console.warn('[CacheManager] Failed to get cache stats:', error)\n return { size: 0, items: 0, maxSize: this.options.maxSize, maxItems: this.options.maxItems }\n }\n }\n}\n\n// Default cache manager instance\nexport const cacheManager = new CacheManager()\n\n// Convenience functions\nexport const setCache = <T>(key: string, data: T, ttl?: number): boolean => {\n return cacheManager.set(key, data, ttl)\n}\n\nexport const getCache = <T>(key: string): T | null => {\n return cacheManager.get<T>(key)\n}\n\nexport const removeCache = (key: string): boolean => {\n return cacheManager.remove(key)\n}\n\nexport const clearCache = (pattern?: string): void => {\n return cacheManager.clear(pattern)\n}\n\nexport const getCacheStats = () => {\n return cacheManager.getStats()\n}\n","import type { TranslatorLanguage, TranslatorOptions } from '../types'\nimport { translateBatch } from '../core'\nimport { API_FIELD_TEXT, API_FIELD_FROM, API_FIELD_TO, API_FIELD_CTX } from '../constants'\nimport { getCache, setCache } from './cache'\nimport { devDebug } from './debug'\n\nconst CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000\nconst NAME_CTX = 'language name'\n\ntype NameMap = Record<string, string>\n\n// Translate the distinct English language names into `targetLang`, returning a\n// name → translation map. translateBatch preserves input order, so results map\n// back by index.\nasync function translateNames(\n names: string[],\n targetLang: string,\n options: TranslatorOptions\n): Promise<NameMap | null> {\n const requests = names.map((name) => ({\n [API_FIELD_TEXT]: name,\n [API_FIELD_FROM]: 'en',\n [API_FIELD_TO]: targetLang,\n [API_FIELD_CTX]: NAME_CTX\n }))\n try {\n const results = await translateBatch(requests, options)\n const map: NameMap = {}\n names.forEach((name, i) => {\n const translated = results[i]?.[API_FIELD_TEXT]\n if (translated) map[name] = translated\n })\n return map\n } catch (error: unknown) {\n devDebug('[localizeLanguageNames] translate failed:', error)\n return null\n }\n}\n\n/**\n * Attach `search_alias` — each language's name in the current interface language —\n * so the picker's fuzzy search matches names typed in the user's own language and\n * script (e.g. Cyrillic \"браз\" → Brazilian). English is a no-op: `name` already is\n * the primary search field. Cached per interface language (7-day TTL). Returns the\n * same array reference unchanged on no-op / failure so callers can skip reassigning.\n */\nexport async function localizeLanguageNames(\n languages: TranslatorLanguage[],\n targetLang: string,\n options: TranslatorOptions = {}\n): Promise<TranslatorLanguage[]> {\n const to = (targetLang || '').toLowerCase()\n if (!to || to === 'en' || languages.length === 0) return languages\n\n const cacheKey = `langie_langnames_${to}`\n let map = getCache<NameMap>(cacheKey)\n if (!map) {\n const names = [...new Set(languages.map((l) => l.name).filter(Boolean))]\n map = await translateNames(names, to, options)\n if (map && Object.keys(map).length) setCache(cacheKey, map, CACHE_TTL_MS)\n }\n if (!map) return languages\n\n const resolved = map\n return languages.map((l) => ({ ...l, search_alias: resolved[l.name] || l.search_alias }))\n}\n","import type { TranslateServiceResponse } from '../types'\nimport { devDebug } from '../utils/debug'\nimport {\n API_FIELD_TEXT,\n API_FIELD_FROM,\n API_FIELD_TO,\n API_FIELD_CTX,\n API_FIELD_TRANSLATIONS,\n API_FIELD_ERROR,\n API_FIELD_TURNSTILE\n} from '../constants'\n\nexport interface BatchingOptions {\n initialBatchDelay?: number\n followupBatchDelay?: number\n maxBatchSize?: number\n maxWaitTime?: number\n /**\n * Supplies a fresh Cloudflare Turnstile token per batch request. Required by the\n * keyless `/frontend/translate` proxy when Turnstile is enabled server-side.\n * Single-use tokens, so it is invoked once per outgoing request.\n */\n getTurnstileToken?: () => string | Promise<string>\n}\n\nexport interface BatchRequest {\n [API_FIELD_TEXT]: string\n [API_FIELD_CTX]: string\n [API_FIELD_FROM]: string\n [API_FIELD_TO]: string\n cacheKey: string\n __explicitToLang?: boolean\n}\n\nexport class TranslationBatching {\n private pendingRequests = new Set<string>()\n private queueMap = new Map<\n string,\n Map<string, { [API_FIELD_TEXT]: string; [API_FIELD_CTX]: string; __explicitToLang?: boolean }>\n >()\n private flushTimeout: NodeJS.Timeout | null = null\n private queuedThisTick = new Set<string>()\n private clearQueuedThisTickScheduled = false\n private firstItemTime: number | null = null\n\n constructor(\n private options: BatchingOptions = {},\n private translatorHost: string,\n private currentLanguage: () => string,\n private onBatchComplete: (results: TranslateServiceResponse[], requests: BatchRequest[]) => void\n ) {}\n\n private get initialBatchDelay() {\n return this.options.initialBatchDelay ?? 50\n }\n\n private get followupBatchDelay() {\n return this.options.followupBatchDelay ?? 10\n }\n\n private get maxBatchSize() {\n return this.options.maxBatchSize ?? 50\n }\n\n private get maxWaitTime() {\n return this.options.maxWaitTime ?? 1000\n }\n\n private scheduleClearQueuedThisTick() {\n if (this.clearQueuedThisTickScheduled) return\n this.clearQueuedThisTickScheduled = true\n queueMicrotask(() => {\n this.queuedThisTick.clear()\n this.clearQueuedThisTickScheduled = false\n })\n }\n\n private flushQueues = async () => {\n const allRequests: BatchRequest[] = []\n for (const [batchKey, map] of Array.from(this.queueMap.entries())) {\n if (!map || map.size === 0) {\n this.queueMap.delete(batchKey)\n continue\n }\n const [from, to] = batchKey.split('|')\n for (const [cacheKey, item] of map.entries()) {\n allRequests.push({\n [API_FIELD_TEXT]: item[API_FIELD_TEXT],\n [API_FIELD_CTX]: item[API_FIELD_CTX],\n [API_FIELD_FROM]: from,\n [API_FIELD_TO]: to,\n cacheKey,\n __explicitToLang: item.__explicitToLang\n })\n }\n this.queueMap.delete(batchKey)\n }\n\n if (allRequests.length > 0) {\n // Only log if there are more than 1 request to reduce noise\n // devDebug('[TranslationBatching] Sending batch:', allRequests.length, 'translation items')\n devDebug(\n '[TranslationBatching] Sending batch:',\n allRequests.length,\n 'translation items',\n allRequests\n )\n\n // Split large batches into smaller chunks\n const chunks = this.chunkArray(allRequests, this.maxBatchSize)\n\n for (const chunk of chunks) {\n try {\n await this.fetchAndCacheBatchMixed(chunk)\n } catch (error) {\n devDebug('[TranslationBatching] Batch translation error:', error)\n chunk.forEach((req) => this.pendingRequests.delete(req.cacheKey))\n }\n }\n }\n\n // Reset the first item time after flushing\n this.firstItemTime = null\n }\n\n private chunkArray<T>(array: T[], size: number): T[][] {\n const chunks: T[][] = []\n for (let i = 0; i < array.length; i += size) {\n chunks.push(array.slice(i, i + size))\n }\n return chunks\n }\n\n private scheduleFlush = () => {\n if (this.flushTimeout) {\n clearTimeout(this.flushTimeout)\n }\n\n // Calculate total items across all batches\n let totalItems = 0\n for (const map of this.queueMap.values()) {\n totalItems += map.size\n }\n\n // Check if we've exceeded maximum wait time\n if (this.firstItemTime && Date.now() - this.firstItemTime >= this.maxWaitTime) {\n devDebug('[TranslationBatching] Flushing due to maximum wait time:', totalItems, 'items')\n this.flushQueues()\n return\n }\n\n const delay = this.queueMap.size === 1 ? this.initialBatchDelay : this.followupBatchDelay\n devDebug(\n '[TranslationBatching] Scheduling flush in',\n delay,\n 'ms',\n Array.from(this.queueMap.entries())\n )\n this.flushTimeout = setTimeout(() => {\n this.flushQueues()\n this.flushTimeout = null\n }, delay)\n }\n\n public queueTranslation(\n text: string,\n ctx: string,\n from: string,\n to: string,\n cacheKey: string,\n explicitToLang?: boolean\n ) {\n if (this.pendingRequests.has(cacheKey) || this.queuedThisTick.has(cacheKey)) {\n // devDebug('[TranslationBatching] Skipping duplicate:', cacheKey)\n devDebug('[TranslationBatching] Skipping duplicate:', cacheKey)\n return\n }\n\n // Track when the first item was queued\n if (this.firstItemTime === null) {\n this.firstItemTime = Date.now()\n }\n\n this.queuedThisTick.add(cacheKey)\n this.scheduleClearQueuedThisTick()\n this.pendingRequests.add(cacheKey)\n\n const batchKey = `${from}|${to}`\n if (!this.queueMap.has(batchKey)) {\n this.queueMap.set(batchKey, new Map())\n }\n\n this.queueMap.get(batchKey)!.set(cacheKey, {\n [API_FIELD_TEXT]: text,\n [API_FIELD_CTX]: ctx,\n __explicitToLang: explicitToLang\n })\n // devDebug('[TranslationBatching] Queued translation:', { text, ctx, from, to, cacheKey, batchKey })\n devDebug('[TranslationBatching] Queued translation:', {\n text,\n ctx,\n from,\n to,\n cacheKey,\n batchKey,\n explicitToLang\n })\n this.scheduleFlush()\n }\n\n private async fetchAndCacheBatchMixed(requests: BatchRequest[]) {\n const grouped: { [key: string]: BatchRequest[] } = {}\n requests.forEach((req) => {\n const key = `${req.from}|${req.to}`\n if (!grouped[key]) grouped[key] = []\n grouped[key].push(req)\n })\n\n const allResults: TranslateServiceResponse[] = []\n const allRequests: BatchRequest[] = []\n for (const [langPair, batchRequests] of Object.entries(grouped)) {\n const [from, to] = langPair.split('|')\n\n try {\n // Check if all requests have the same context\n const contexts = [...new Set(batchRequests.map((req) => req[API_FIELD_CTX]))]\n const useGlobalContext = contexts.length === 1 && contexts[0] === 'ui'\n\n // devDebug('[TranslationBatching] Sending batch for', langPair, 'with', batchRequests.length, 'items')\n devDebug(\n '[TranslationBatching] Sending batch for',\n langPair,\n 'with',\n batchRequests.length,\n 'items',\n batchRequests\n )\n\n const buildBody = (turnstileToken?: string) =>\n JSON.stringify({\n translations: batchRequests.map((req) => ({\n [API_FIELD_TEXT]: req[API_FIELD_TEXT],\n ...(useGlobalContext ? {} : { [API_FIELD_CTX]: req[API_FIELD_CTX] })\n })),\n [API_FIELD_FROM]: from,\n [API_FIELD_TO]: to,\n ...(useGlobalContext ? { [API_FIELD_CTX]: 'ui' } : {}),\n ...(turnstileToken ? { [API_FIELD_TURNSTILE]: turnstileToken } : {})\n })\n\n const postTranslate = (turnstileToken?: string) =>\n fetch(`${this.translatorHost}/translate`, {\n method: 'POST',\n // Carry the /frontend session cookie the proxy issues after one\n // Turnstile check, so we don't solve a challenge on every request.\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: buildBody(turnstileToken)\n })\n\n // Ride the session cookie first; only solve a fresh single-use Turnstile\n // challenge when the keyless /frontend proxy rejects for a missing token.\n // Session-aware backends answer 401; older ones 400 — accept both so the\n // demo works against either, making the backend/SDK deploy order irrelevant.\n let response = await postTranslate()\n if (\n (response.status === 401 || response.status === 400) &&\n this.options.getTurnstileToken\n ) {\n const turnstileToken = await this.options.getTurnstileToken()\n response = await postTranslate(turnstileToken)\n }\n\n let result\n try {\n result = await response.json()\n } catch (parseError) {\n devDebug('[TranslationBatching] Failed to parse response as JSON:', parseError)\n throw new Error(`Translation request failed: ${response.status}`)\n }\n\n // Handle HTTP errors by checking if the response contains an error message\n if (!response.ok) {\n devDebug(\n '[TranslationBatching] Translation request failed:',\n response.status,\n response.statusText\n )\n\n // If the response contains an error message, use it\n if (result && result[API_FIELD_ERROR]) {\n devDebug(\n '[TranslationBatching] HTTP error with API error message:',\n result[API_FIELD_ERROR]\n )\n\n // Create error responses for all requests in this batch\n const errorResponses = batchRequests.map((req) => ({\n [API_FIELD_TEXT]: req[API_FIELD_TEXT],\n [API_FIELD_ERROR]: result[API_FIELD_ERROR]\n }))\n\n // Add error responses to results\n allResults.push({ [API_FIELD_TRANSLATIONS]: errorResponses })\n allRequests.push(...batchRequests)\n\n // Clear pending requests for this batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n\n // Continue to onBatchComplete to record errors\n this.onBatchComplete(allResults, allRequests)\n return\n }\n\n throw new Error(`Translation request failed: ${response.status}`)\n }\n\n // Handle top-level error responses\n if (result[API_FIELD_ERROR]) {\n devDebug('[TranslationBatching] Top-level API error:', result[API_FIELD_ERROR])\n\n // Create error responses for all requests in this batch\n const errorResponses = batchRequests.map((req) => ({\n [API_FIELD_TEXT]: req[API_FIELD_TEXT],\n [API_FIELD_ERROR]: result[API_FIELD_ERROR]\n }))\n\n // Add error responses to results\n allResults.push({ [API_FIELD_TRANSLATIONS]: errorResponses })\n allRequests.push(...batchRequests)\n\n // Clear pending requests for this batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n\n // Continue to onBatchComplete to record errors\n } else {\n // Handle error responses in the result\n if (result[API_FIELD_TRANSLATIONS]) {\n result[API_FIELD_TRANSLATIONS].forEach((translation: any, index: number) => {\n if (translation[API_FIELD_ERROR]) {\n const originalText = batchRequests[index]?.[API_FIELD_TEXT]\n devDebug(\n '[TranslationBatching] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n }\n })\n }\n\n allResults.push(result)\n allRequests.push(...batchRequests)\n\n // Clear pending requests for this batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n }\n } catch (error) {\n devDebug('[TranslationBatching] Batch request failed for', langPair, ':', error)\n\n // Clear pending requests for failed batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n\n // Re-throw to be handled by the caller\n throw error\n }\n }\n\n this.onBatchComplete(allResults, allRequests)\n }\n\n public clearPending(cacheKey: string) {\n this.pendingRequests.delete(cacheKey)\n }\n\n public clearAllPending() {\n this.pendingRequests.clear()\n }\n\n public cleanup() {\n this.clearAllPending()\n this.queueMap.clear()\n this.queuedThisTick.clear()\n if (this.flushTimeout) {\n clearTimeout(this.flushTimeout)\n this.flushTimeout = null\n }\n this.clearQueuedThisTickScheduled = false\n this.firstItemTime = null\n }\n\n public getStats() {\n return {\n pendingRequests: this.pendingRequests.size,\n queuedBatches: this.queueMap.size,\n queuedThisTick: this.queuedThisTick.size,\n hasFlushTimeout: !!this.flushTimeout\n }\n }\n}\n","import script from \"/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue?type=script\"\nexport * from \"/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue?type=script\"\n\nimport \"/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue?type=style&index=0\"\nexport default script\nscript.__scopeId = \"data-v-258d337a\"","<template>\n <transition name=\"fade\" mode=\"out-in\">\n <span :key=\"translated\">{{ translated }}</span>\n </transition>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, useSlots, watch } from 'vue'\nimport { ref, nextTick } from 'vue'\nimport { useLangie } from '../useLangie'\n\n// Define component name for better debugging\n// Component name for Vue devtools\n// Note: defineOptions requires Vue 3.3+, but we support Vue 3.2+\n// The component will work without explicit name\n\n// Detect if we're running in Nuxt\nconst isNuxt = computed(() => {\n if (typeof window !== 'undefined') {\n return !!(window as any).__NUXT__\n }\n if (typeof process !== 'undefined') {\n return !!(process.env as any).NUXT_SSR_BASE || !!(process.env as any).NUXT_PUBLIC_BASE_URL\n }\n return false\n})\n\nconst props = defineProps({\n // Message key (optional, otherwise slot content is used)\n msg: {\n type: String,\n default: undefined\n },\n // Translation context shorthand\n ctx: {\n type: String,\n required: false,\n default: 'ui'\n },\n // Original language shorthand\n orig: {\n type: String,\n required: false,\n default: undefined\n }\n})\n\nconst slots = useSlots()\nconst { lr, peekTranslation, currentLanguage, uiTranslations, translations, getLtDefaults } =\n useLangie()\n\nconst keyStr = computed(() => {\n if (props.msg) return props.msg\n const slotContent = slots.default\n ? slots\n .default()\n .map((n) => n.children)\n .join('')\n : ''\n return (slotContent || '').trim()\n})\n\n// Force component update when translations change\nconst forceUpdate = ref(0)\nwatch(\n [uiTranslations, translations],\n () => {\n // Small delay to ensure translations are cached before updating\n nextTick(() => {\n forceUpdate.value++\n })\n },\n { deep: true }\n)\n\nconst translated = computed(() => {\n // Get global defaults\n const globalDefaults = getLtDefaults()\n\n // Use props or fall back to global defaults\n const effectiveCtx = props.ctx ?? globalDefaults.ctx\n const effectiveOrig = props.orig ?? globalDefaults.orig\n\n // On the server emit a seeded translation when the host pre-populated one (no\n // English flash, no CLS); on a cold miss render the key (invisible reserver,\n // fade-in after mount). peekTranslation never queues — a doomed SSR request is\n // pointless. The client seeds the same map, so hydration matches on hits.\n if (isNuxt.value && typeof window === 'undefined') {\n return peekTranslation(keyStr.value, effectiveCtx)\n }\n\n // Force reactivity by depending on currentLanguage and translation caches\n void currentLanguage.value\n void forceUpdate.value // Force recomputation when translations change\n // Access properties to create reactive dependencies\n const cacheKey = `${keyStr.value}|${effectiveCtx}`\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n void cache[cacheKey] // This creates a reactive dependency\n\n // For other frameworks, always translate\n const result = lr(keyStr.value, effectiveCtx, effectiveOrig)\n return result\n})\n</script>\n\n<style scoped>\n.fade-enter-active,\n.fade-leave-active {\n transition: opacity 0.25s ease;\n}\n.fade-enter-from,\n.fade-leave-to {\n opacity: 0;\n}\n</style>\n","import script from \"/builds/codelits/langie-sdk/src/components/lt.vue?type=script\"\nexport * from \"/builds/codelits/langie-sdk/src/components/lt.vue?type=script\"\n\nimport \"/builds/codelits/langie-sdk/src/components/lt.vue?type=style&index=0\"\nexport default script\nscript.__scopeId = \"data-v-3341698b\""],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,iCAAAA;AAAA,EAAA,sBAAAC;AAAA,EAAA,UAAAC;AAAA;AAAA;;;;;ACoFA,qBAAO;;;ACnFkB,SAAR,YAA6B,KAAK,EAAE,SAAS,IAAI,CAAC,GAAG;AAC1D,MAAI,CAAC,OAAO,OAAO,aAAa,YAAa;AAE7C,QAAM,OAAO,SAAS,QAAQ,SAAS,qBAAqB,MAAM,EAAE,CAAC;AACrE,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,OAAO;AAEb,MAAI,aAAa,OAAO;AACtB,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa,OAAO,KAAK,UAAU;AAAA,IAC1C,OAAO;AACL,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF,OAAO;AACL,SAAK,YAAY,KAAK;AAAA,EACxB;AAEA,MAAI,MAAM,YAAY;AACpB,UAAM,WAAW,UAAU;AAAA,EAC7B,OAAO;AACL,UAAM,YAAY,SAAS,eAAe,GAAG,CAAC;AAAA,EAChD;AACF;;;ACvB8B,YAAY,2yBAA2yB;;;AFsF/1B,IAAAC,cAA2D;AAE3D,yBAAwB;AACxB,kBAAiB;;;AGvFjB,IAAI,UAAyC;AAQtC,SAAS,oBAA4C;AAC1D,MAAI,CAAC,SAAS;AACZ,cAAU,OAAO,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa;AAAA,EACjE;AACA,SAAO;AACT;;;ACbO,IAAM,qBAAmC;AAAA;AAAA,EAE9C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,SAAS,YAAY,OAAO;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,sBAAO,kCAAS,8CAAW,qGAAqB,mGAAmB;AAAA,IAC3E,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,wDAAW;AAAA,IACnB,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,sCAAQ;AAAA,IAChB,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,kDAAU;AAAA,IAClB,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,WAAW,YAAY,QAAQ;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,WAAW,UAAU,UAAU;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,YAAY,SAAS,eAAe;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS,YAAY,eAAe;AAAA,IACzD,SAAS,CAAC,aAAa,cAAc,UAAU;AAAA,EACjD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,UAAU,aAAa,QAAQ,cAAc,QAAQ;AAAA,IACtF,SAAS,CAAC,YAAY,WAAW;AAAA,EACnC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO,eAAe,WAAW,WAAW,SAAS;AAAA,IAC1E,SAAS,CAAC,WAAW,WAAW;AAAA,EAClC;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,UAAU,SAAS;AAAA,IACxC,SAAS,CAAC,UAAU,SAAS,cAAc,SAAS,SAAS,UAAU;AAAA,EACzE;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,WAAW,YAAY;AAAA,EACnC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,YAAY,WAAW;AAAA,EACnC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO,kBAAkB,SAAS;AAAA,IACvD,SAAS,CAAC,UAAU,UAAU;AAAA,EAChC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,UAAU;AAAA,IAC/B,SAAS,CAAC,SAAS,OAAO;AAAA,EAC5B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,WAAW,WAAW,aAAa;AAAA,EAC/C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,YAAY,WAAW,aAAa;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,UAAU;AAAA,IAC/B,SAAS,CAAC,YAAY;AAAA,EACxB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,UAAU;AAAA,IAC/B,SAAS,CAAC,UAAU;AAAA,EACtB;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,aAAa,UAAU,SAAS;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,WAAW,QAAQ;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,aAAa,SAAS;AAAA,EAClC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,YAAY,SAAS;AAAA,EACjC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,WAAW,WAAW;AAAA,EAClC;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO,UAAU,UAAU;AAAA,IAChD,SAAS,CAAC,cAAc,UAAU;AAAA,EACpC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO,SAAS;AAAA,IACrC,SAAS,CAAC,YAAY,WAAW;AAAA,EACnC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW,QAAQ;AAAA,IACxC,SAAS,CAAC,YAAY,QAAQ;AAAA,EAChC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO,WAAW,QAAQ;AAAA,IAC/C,SAAS,CAAC,SAAS,YAAY;AAAA,EACjC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW;AAAA,IAChC,SAAS,CAAC,WAAW,QAAQ;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,cAAc,UAAU;AAAA,EACpC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,WAAW,SAAS;AAAA,EAChC;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW,QAAQ;AAAA,IACxC,SAAS,CAAC,YAAY,OAAO;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS,OAAO;AAAA,IACrC,SAAS,CAAC,SAAS,SAAS;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,cAAc;AAAA,IAC/C,SAAS,CAAC,SAAS,SAAS;AAAA,EAC9B;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW;AAAA,IAChC,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO;AAAA,IAC5B,SAAS,CAAC,WAAW,WAAW,QAAQ;AAAA,EAC1C;AACF;;;ACrQO,IAAM,kBAAgC;AAAA;AAAA,EAE3C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS,CAAC,aAAa,aAAa,OAAO;AAAA,EAC7C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,MAAM,SAAS,SAAS;AAAA,IAC7C,SAAS,CAAC,UAAU;AAAA,EACtB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,MAAM,SAAS,UAAU,eAAe,aAAa;AAAA,IAC1E,SAAS,CAAC,MAAM;AAAA,EAClB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS,UAAU,YAAY;AAAA,IACpD,SAAS,CAAC,QAAQ,WAAW,YAAY,WAAW,SAAS;AAAA,EAC/D;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ,SAAS,SAAS,YAAY,QAAQ,aAAa,SAAS;AAAA,IACzF,SAAS,CAAC,WAAW,UAAU,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,MAAM;AAAA,IACvC,SAAS,CAAC,OAAO,OAAO;AAAA,EAC1B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,SAAS,KAAK;AAAA,EAC1B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,aAAa,QAAQ;AAAA,IAC1C,SAAS,CAAC,SAAS,YAAY,WAAW;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,QAAQ;AAAA,IACzC,SAAS,CAAC,YAAY;AAAA,EACxB;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,UAAU,UAAU,cAAc,kCAAS,0DAAa,sCAAQ;AAAA,IACrF,SAAS,CAAC,WAAW,UAAU,OAAO;AAAA,EACxC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,WAAW,aAAa;AAAA,EACpC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY;AAAA,IACjC,SAAS,CAAC,SAAS,UAAU,QAAQ;AAAA,EACvC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY;AAAA,IACjC,SAAS,CAAC,UAAU,OAAO;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY;AAAA,IACjC,SAAS,CAAC,WAAW,OAAO;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY;AAAA,IACjC,SAAS,CAAC,WAAW,SAAS;AAAA,EAChC;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO,QAAQ,SAAS,QAAQ,aAAa;AAAA,IAClE,SAAS,CAAC,SAAS,WAAW,QAAQ;AAAA,EACxC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,UAAU,SAAS;AAAA,IACxC,SAAS,CAAC,UAAU,SAAS;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,aAAa,YAAY,QAAQ;AAAA,IACtD,SAAS,CAAC,WAAW,WAAW,QAAQ;AAAA,EAC1C;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,WAAW;AAAA,IAC5C,SAAS,CAAC,SAAS,SAAS;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,cAAc,QAAQ;AAAA,IAC3C,SAAS,CAAC,SAAS,UAAU;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,SAAS,MAAM;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,SAAS;AAAA,IAC9B,SAAS,CAAC,SAAS,SAAS;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,aAAa;AAAA,IAClC,SAAS,CAAC,SAAS,UAAU;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,cAAc,WAAW;AAAA,IAC9C,SAAS,CAAC,aAAa,UAAU,SAAS;AAAA,EAC5C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,gBAAgB;AAAA,IACrC,SAAS,CAAC,SAAS,SAAS;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW;AAAA,IAChC,SAAS,CAAC,SAAS,UAAU,WAAW;AAAA,EAC1C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,QAAQ;AAAA,IAC7B,SAAS,CAAC,SAAS,SAAS;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,OAAO;AAAA,IAC5B,SAAS,CAAC,OAAO;AAAA,EACnB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,aAAa,QAAQ;AAAA,IAC1C,SAAS,CAAC,OAAO;AAAA,EACnB;AAAA;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW,OAAO;AAAA,IACvC,SAAS,CAAC,MAAM;AAAA,EAClB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,WAAW;AAAA,IAC5C,SAAS,CAAC,cAAc,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,MAAM;AAAA,IAC3B,SAAS,CAAC,QAAQ,YAAY;AAAA,EAChC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,eAAe,UAAU;AAAA,IAC9C,SAAS,CAAC,WAAW,SAAS;AAAA,EAChC;AACF;;;AC1LO,IAAM,oBAAkC;AAAA;AAAA,EAE7C;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,aAAa,YAAY,OAAO;AAAA,IACrD,SAAS,CAAC,QAAQ;AAAA,EACpB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,YAAY,WAAW;AAAA,IAC5C,SAAS,CAAC,YAAY,OAAO;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,WAAW,OAAO;AAAA,IACvC,SAAS,CAAC,QAAQ,OAAO;AAAA,EAC3B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO,CAAC,OAAO,MAAM,cAAc;AAAA,IACnC,SAAS,CAAC,SAAS,WAAW;AAAA,EAChC;AACF;;;ACnBO,IAAM,uBAAqC;AAAA,EAChD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;;;ACHO,SAAS,mBAAmB,OAAO,IAGxC;AACA,QAAM,IAAI,KAAK,YAAY,EAAE,KAAK;AAClC,MAAI,CAAC,EAAG,QAAO,EAAE,SAAS,MAAM,aAAa,CAAC,EAAE;AAGhD,QAAM,UAAU,CAAC,OAAe,UAA2B;AACzD,QAAI,UAAU,MAAO,QAAO;AAE5B,QAAI,MAAM,UAAU,KAAK,MAAM,UAAU,MAAM,UAAU,MAAM,WAAW,KAAK,EAAG,QAAO;AAEzF,QAAI,MAAM,UAAU,KAAK,MAAM,WAAW,KAAK,EAAG,QAAO;AACzD,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,cAAc,oBAAI,IAAY;AAEpC,aAAW,EAAE,MAAM,OAAO,QAAQ,KAAK,sBAAsB;AAE3D,eAAW,KAAK,OAAO;AACrB,UAAI,QAAQ,GAAG,CAAC,GAAG;AACjB,aAAK,IAAI,IAAI;AAEb,YAAI,SAAS;AACX,kBAAQ,QAAQ,CAAC,QAAgB,YAAY,IAAI,GAAG,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,KAAK,SAAS,GAAG;AACnB,cAAU;AAAA,EACZ,WAAW,KAAK,SAAS,GAAG;AAC1B,cAAU,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,EAC9B,OAAO;AACL,cAAU,MAAM,KAAK,IAAI;AAAA,EAC3B;AAEA,SAAO,EAAE,SAAS,aAAa,MAAM,KAAK,WAAW,EAAE;AACzD;;;AC9CA,IAAM,iBAAiB;AAWhB,SAAS,cAAc,OAAO,IAAI,SAAS,IAAY;AAC5D,SAAO,SAAS,UAAU,eAAe,KAAK,IAAI,KAAK,eAAe,KAAK,MAAM,IAC7E,OAAO,QAAQ,gBAAgB,EAAE,IACjC;AACN;;;ACbO,IAAM,iBAAiB,CAAC,aAC7B,SAAS,WAAW,GAAG,KAAK,gBAAgB,KAAK,QAAQ;AAOpD,IAAM,eAAe,CAAC,aAC3B,eAAe,QAAQ,IAAI,WAAW,UAAU,QAAQ;;;ACXnD,IAAM,SAAS;AAAA;AAAA,EAEpB,SAAS;AAAA,IACP,MAAM;AAAA,IACN,WAAW;AAAA,IACX,UAAU;AAAA,IACV,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA;AAAA,EAGA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAGO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,IACL,YAAY,OAAO,QAAQ;AAAA,IAC3B,oBAAoB,OAAO,QAAQ;AAAA,IACnC,QAAQ,OAAO,OAAO;AAAA,IACtB,aAAa,OAAO,KAAK;AAAA,IACzB,MAAM,OAAO,QAAQ;AAAA,IACrB,eAAe,OAAO,QAAQ;AAAA,IAC9B,mBAAmB,OAAO,KAAK;AAAA,IAC/B,gBAAgB,OAAO,QAAQ;AAAA,IAC/B,oBAAoB,OAAO,QAAQ;AAAA,IACnC,oBAAoB,OAAO,QAAQ;AAAA,IACnC,gBAAgB,OAAO,OAAO;AAAA,IAC9B,cAAc,OAAO,KAAK;AAAA,IAC1B,eAAe,OAAO,QAAQ;AAAA,EAChC;AAAA,EACA,MAAM;AAAA,IACJ,YAAY,OAAO,QAAQ;AAAA,IAC3B,oBAAoB,OAAO,QAAQ;AAAA,IACnC,QAAQ,OAAO,OAAO;AAAA,IACtB,aAAa,OAAO,KAAK;AAAA,IACzB,MAAM,OAAO,QAAQ;AAAA,IACrB,eAAe,OAAO,QAAQ;AAAA,IAC9B,mBAAmB,OAAO,QAAQ;AAAA,IAClC,gBAAgB,OAAO,QAAQ;AAAA,IAC/B,oBAAoB,OAAO,QAAQ;AAAA,IACnC,oBAAoB,OAAO,QAAQ;AAAA,IACnC,gBAAgB,OAAO,OAAO;AAAA,IAC9B,cAAc,OAAO,QAAQ;AAAA,IAC7B,eAAe,OAAO,QAAQ;AAAA,EAChC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AX4BA,UAAM,gBAAgB,EAAE,wBAAwB,QAAW,oBAAoB,OAAU;AAOzF,UAAM,oBAAgB,mBAAM;AAE5B,UAAM,cAAc,CAAC,SAAqC;AACxD,YAAM,WAAW,KAAK,gBAAgB,KAAK;AAC3C,aAAO;IACT;AAIA,UAAM,kBAAkB,CAAC,SAAqC,aAAa,YAAY,IAAI,CAAC;AAE5F,UAAM,QAAQ;AAuBd,UAAM,OAAO;AAEb,UAAM,qBAAiB,iBAA6C,IAAI;AAExE,UAAM,gBAAY,sBAAS,MAAM;AAC/B,aAAO,MAAM,UAAU,UAAU;IACnC,CAAC;AACD,UAAM,kBAAc,iBAAI,EAAE;AAC1B,UAAM,oBAAgB,wBAAiC,IAAI;AAE3D,UAAM,uBAAmB,sBAAS,OAAO,EAAE,aAAa,MAAM,YAAY,EAAE;AAE5E,UAAM,qBAAiB,sBAAS,MAAM;AACpC,aAAO,MAAM,UAAU,OAAO,CAAC,SAAS,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,WAAW;IAC5F,CAAC;AAED,UAAM,WAAO,sBAAS,MAAM;AAC1B,UAAI,CAAC,eAAe,MAAM,OAAQ,QAAO;AAEzC,aAAO,IAAI,YAAAC,QAAK,eAAe,OAAO;QACpC,MAAM,CAAC,QAAQ,eAAe,gBAAgB,MAAM;QACpD,cAAc;QACd,WAAW;;QACX,gBAAgB;;QAChB,iBAAiB;QACjB,oBAAoB;;MACtB,CAAC;IACH,CAAC;AAED,UAAM,qBAAiB,sBAAS,MAAM;AAEpC,YAAM,aAAa,MAAM,UAAU,SAAS,KAAK,MAAM,UAAU,CAAC,EAAE,iBAAiB;AACrF,aAAO,aAAa,aAAa;IACnC,CAAC;AAED,UAAM,0BAAsB,sBAAS,MAAM;AACzC,UAAI,CAAC,MAAM,cAAc,CAAC,MAAM,WAAW,KAAM,QAAO;AACxD,YAAM,MAAM,GAAG,MAAM,WAAW,IAAI,IAAI,MAAM,WAAW,gBAAgB,UAAU;AACnF,aAAO;IACT,CAAC;AAED,UAAM,uBAAmB,sBAAS;MAChC,KAAK,MAAM,MAAM,cAAc;MAC/B,KAAK,CAAC,UAAU;AACd,YAAI,SAAS,MAAM,MAAM;AACvB,eAAK,qBAAqB,KAAK;QACjC;MACF;IACF,CAAC;AAED,UAAM,wBAAoB,sBAAS,MAAM;AACvC,YAAM,QAAQ,YAAY,MAAM,KAAK;AAErC,UAAI;AACJ,UAAI,CAAC,OAAO;AAEV,kBAAU,eAAe;MAC3B,OAAO;AAEL,YAAI,CAAC,KAAK,MAAO,QAAO,CAAC;AAGzB,cAAM,cAAc,mBAAmB,KAAK;AAC5C,cAAM,aAAa,MAAM,QAAQ,YAAY,OAAO,IAChD,YAAY,QAAQ,CAAC,IACrB,YAAY;AAGhB,cAAM,cAAc,CAAC,SAA2C;AAC9D,eAAK,QAAQ,CAAC,QAAQ;AACpB,gBAAI,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,IAAI,EAAG,SAAQ,KAAK,IAAI,IAAI;UAC3E,CAAC;QACH;AAGA,kBAAU,KAAK,MAAM,OAAO,UAAU,EAAE,IAAI,CAAC,WAAW,OAAO,IAAI;AAGnE,YAAI,eAAe,OAAO;AACxB,sBAAY,KAAK,MAAM,OAAO,KAAK,CAAC;QACtC;AAKA,cAAM,aAAa,cAAc,QAAQ,cAAc,MAAM,KAAK,IAAI;AACtE,YAAI,cAAc,WAAW,YAAY,MAAM,MAAM,YAAY,GAAG;AAClE,sBAAY,KAAK,MAAM,OAAO,UAAU,CAAC;QAC3C;AAGA,YAAI,YAAY,YAAY,SAAS,GAAG;AACtC,sBAAY,YAAY,QAAQ,CAAC,eAAe;AAC9C,kBAAM,gBAAgB,eAAe,MAAM,KAAK,CAAC,SAAS;AACxD,oBAAM,WAAW,KAAK,KAAK,YAAY;AACvC,oBAAM,mBAAmB,WAAW,YAAY;AAGhD,qBACE,aAAa;cACb,SAAS,SAAS,gBAAgB;cAClC,KAAK,KAAK,YAAY,MAAM;cAC5B,SAAS,WAAW,gBAAgB;;cAEnC,qBAAqB,WAAW,SAAS,SAAS,OAAO,KACzD,qBAAqB,iBACnB,SAAS,SAAS,SAAS,KAAK,SAAS,SAAS,YAAY,MAChE,qBAAqB,eACnB,SAAS,SAAS,QAAQ,KAAK,SAAS,SAAS,SAAS;YAEjE,CAAC;AACD,gBAAI,iBAAiB,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,cAAc,IAAI,GAAG;AACxE,sBAAQ,KAAK,aAAa;YAC5B;UACF,CAAC;QACH;AAGA,YAAI,MAAM,WAAW,GAAG;AACtB,gBAAM,aAAa,MAAM,YAAY;AACrC,gBAAM,gBAAgB,eAAe,MAAM;YACzC,CAAC,SACC,KAAK,KAAK,YAAY,EAAE,WAAW,UAAU,KAC7C,KAAK,YAAY,YAAY,EAAE,WAAW,UAAU;UACxD;AACA,wBAAc,QAAQ,CAAC,SAAS;AAC9B,gBAAI,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG;AAC9C,sBAAQ,KAAK,IAAI;YACnB;UACF,CAAC;QACH;MACF;AAGA,YAAM,WAAW,QAAQ;QACvB,CAAC,SAAS,CAAC,MAAM,cAAc,CAAC,MAAM,WAAW,QAAQ,KAAK,SAAS,MAAM,WAAW;MAC1F;AAEA,aAAO;IACT,CAAC;AAED,aAAS,aAAa,OAAe;AACnC,kBAAY,QAAQ;AACpB,UAAI,CAAC,MAAM,KAAK,EAAG;AAInB,UAAI,CAAC,cAAc,OAAO;AACxB,aAAK,kBAAkB,EAAE,KAAK,CAAC,OAAO;AACpC,wBAAc,QAAQ;QACxB,CAAC;MACH;AAQA,gCAAS,MAAM;AACb,uBAAe,OAAO,kBAAkB;AACxC,cAAM,WAAW,SAAS,cAAc,uBAAuB;AAC/D,YAAI,SAAU,UAAS,YAAY;MACrC,CAAC;IACH;AAKA,aAAS,cAAc,OAAc;AACnC,YAAM,gBAAgB;AACtB,UAAI,cAAc,QAAQ,SAAS,cAAc,QAAQ,QAAS;AAClE,UAAI,CAAC,YAAY,MAAM,KAAK,EAAG;AAE/B,YAAM,WAAW,SAAS,cAAc,uBAAuB;AAC/D,YAAM,UACJ,UAAU,cAAc,iDAAiD,KACzE,UAAU,cAAc,sCAAsC;AAChE,YAAM,WAAW,SAAS,aAAa,gBAAgB;AACvD,UAAI,CAAC,SAAU;AAEf,YAAM,WAAW,eAAe,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,QAAQ;AAC3E,UAAI,UAAU;AACZ,yBAAiB,QAAQ;AACzB,oBAAY,QAAQ;AACpB,sBAAc,eAAe;MAC/B;IACF;AAEA,UAAM,cAAc,CAAC,UAAiB;AACpC,YAAM,SAAS,MAAM;AACrB,YAAM,aAAa,OAAO;AAM1B,UAAI,OAAO,QAAQ,YAAY;AAC7B,eAAO,MAAM,UAAU;AACvB;MACF;AAGA,UAAI,cAAc,WAAW,SAAS,SAAS,GAAG;AAChD,cAAM,QAAQ,WAAW,MAAM,0BAA0B;AACzD,YAAI,OAAO;AACT,gBAAM,cAAc,MAAM,CAAC;AAE3B,iBAAO,MAAM,uBAAuB,WAAW;AAE/C,iBAAO,UAAU,MAAM;AACrB,mBAAO,MAAM,UAAU;UACzB;AACA;QACF;MACF;AAGA,aAAO,MAAM,UAAU;IACzB;;+CA3WE,YAAAC;QA+EM;QAAA;UA/ED,WAAK,YAAAC,gBAAA,CAAC,mBAAiB,EAAA,WAAsB,QAAA,OAAM,CAAA,CAAA;;;cACtD,YAAAC,oBAAA,+DAAA;UAEQ,eAAA,MAAe,SAAM,KAAA,CAAS,UAAA,2CADtC,YAAAC,iBA0Ec,YAAAC,OAAA,mBAAAC,OAAA,GAAA;qBAxER;YAAJ,KAAI;YACH,KAAK,eAAA;wBACG,iBAAA;yEAAA,iBAAgB,QAAA;YACxB,SAAS,kBAAA;YACT,YAAY;YACZ,gBAAe;YACf,aAAW;YACX,eAAa;YACb,QAAQ;YACR,aAAa,eAAA,MAAe,WAAM,IAAA,2BAAoC,QAAA;YACtE,UAAU,MAAM,YAAY,eAAA,MAAe,WAAM;YACjD,SAAS,UAAA;YACV,YAAS;YACT,OAAM;YACN,cAAW;YACV,kBAAgB;YAChB,QAAI,YAAAD,OAAA,aAAA;YACJ,MAAM;YACN,OAAO,iBAAA;YACP,WAAS;;YAEC,iBAAW,YAAAE,SACpB,CAgBM,EAjBkB,MAAK,MAAA;cAClB,2CAAX,YAAAN,oBAgBM,OAhBN,YAgBM;gBAdI,MAAM,0CADd,YAAAA,oBAQE,OAAA;kBANC,KAAK,oBAAA;kBACL,KAAK,gBAAgB,KAAK;kBAC3B,OAAM;kBACL,KAAG,GAAK,MAAM,eAAe,MAAM,IAAI;kBACvC,wBAAkB,YAAAI,OAAA,cAAA,EAAe,YAAY,KAAK,CAAA,KAAM;kBACxD,SAAO;;oBAEV,YAAAG,oBAKC,QALD,YAKC;;qDAJK,MAAM,IAAI,IAAG;oBACjB;;kBAAA;kBAAY,MAAM,eAAe,MAAM,gBAAgB,MAAM,0CAA7D,YAAAP;oBAEC;oBAFD;oBACG,UAAC,YAAAQ,qBAAG,YAAAJ,OAAA,aAAA,EAAc,MAAM,MAAM,MAAM,WAAW,CAAA,IAAI;oBAAC;;kBAAA;;;;YAKlD,YAAM,YAAAE,SACf,CAiBM,EAlBa,OAAM,MAAA;kBACzB,YAAAC,oBAiBM,OAAA;gBAjBD,OAAM;gBAAsB,kBAAgB,OAAO;;mDACtD,YAAAP,oBAOE,OAAA;kBANC,KAAG,GAAK,OAAO,IAAI,IAAI,OAAO,gBAAY,UAAA;kBAC1C,KAAK,gBAAgB,MAAM;kBAC5B,OAAM;kBACL,KAAG,GAAK,OAAO,IAAI;kBACnB,wBAAkB,YAAAI,OAAA,cAAA,EAAe,YAAY,MAAM,CAAA,KAAM;kBACzD,SAAO;;oBAEV,YAAAG,oBAOC,QAPD,YAOC;;qDANK,OAAO,IAAI,IAAG;oBAClB;;kBAAA;kBACQ,OAAO,eAAe,OAAO,gBAAgB,OAAO,0CAD5D,YAAAP;oBAIC;oBAJD;oBAGG,UAAC,YAAAQ,qBAAG,YAAAJ,OAAA,aAAA,EAAc,OAAO,MAAM,OAAO,WAAW,CAAA,IAAI;oBAAC;;kBAAA;;;;YAKpD,eAAS,YAAAE,SAClB,MAA6D,OAAA,CAAA,MAAA,OAAA,CAAA,IAAA;kBAA7D,YAAAC;gBAA6D;gBAAA,EAAxD,OAAM,yBAAwB;gBAAC;gBAAmB;;cAAA;;YAE9C,eAAS,YAAAD,SAClB,MAMM;kBANN,YAAAC;gBAMM;gBANN;oBAMM,YAAAC,iBAJF,eAAA,MAAe,WAAM;;;;;;;mGAQb,UAAA,SAAa,eAAA,MAAe,WAAM,uCAAlD,YAAAR;YAAwF,YAAAS;YAAA,EAAA,KAAA,EAAA;YAAA;kBADxF,YAAAP,oBAAA,gFAAA;4CACA,YAAAK;gBAAwF;gBAAA,EAA9B,OAAM,kBAAiB;gBAAA;gBAAA;;cAAA;;;;;;;;;;;;;;AY3ErF,IAAOG,0BAAQ;AACf,uBAAO,YAAY;;;;;ACoBnB,IAAAC,cAAgD;;;ACzBhD,IAAAC,cAAsB;;;ACGf,IAAM,mBAAmB;AAwBzB,IAAM,iBAAiB;AAGvB,IAAM,iBAAiB;AAGvB,IAAM,eAAe;AAGrB,IAAM,gBAAgB;AAKtB,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAM/B,IAAM,yBAAyB;AAG/B,IAAM,kBAAkB;AAGxB,IAAM,sBAAsB;;;ACjCnC,IAAM,0BAA0B;AAChC,IAAM,sBAAsB;AAM5B,SAAS,cAAc,SAAgD;AACrE,MAAI,QAAQ,OAAQ,QAAO,QAAQ;AACnC,QAAM,MAAM,OAAO,YAAY,cAAc,QAAQ,MAAM;AAC3D,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,IAAI,QAAQ,aAAa,mBAAmB;AACrD;AAIA,SAAS,eAAe,GAAiD;AACvE,QAAM,MAAM,EAAE,sBAAsB;AACpC,QAAM,MAAM,EAAE,sBAAsB;AACpC,SAAO,OAAO,MAAM,EAAE,CAAC,sBAAsB,GAAG,KAAK,CAAC,sBAAsB,GAAG,IAAI,IAAI,CAAC;AAC1F;AAGA,IAAM,mBAAmB,oBAAI,IAAiD;AAE9E,SAAS,uBACP,qBACA,SACQ;AAER,SAAO,KAAK,UAAU;AAAA,IACpB,cAAc,oBAAoB,IAAI,CAAC,OAAO;AAAA,MAC5C,CAAC,cAAc,GAAG,EAAE,cAAc;AAAA,MAClC,CAAC,cAAc,GAAG,EAAE,cAAc;AAAA,MAClC,CAAC,YAAY,GAAG,EAAE,YAAY;AAAA,MAC9B,CAAC,aAAa,GAAG,EAAE,aAAa,KAAK,QAAQ,aAAa,KAAK;AAAA,MAC/D,GAAG,eAAe,CAAC;AAAA,IACrB,EAAE;AAAA,IACF,MAAM,QAAQ,kBAAkB;AAAA,IAChC,SAAS,QAAQ,aAAa,KAAK;AAAA,EACrC,CAAC;AACH;AASA,eAAsB,eACpBC,gBAAuC,CAAC,GACxC,UAA6B,CAAC,GACO;AAiBrC,MAAI,CAAC,MAAM,QAAQA,aAAY,KAAKA,cAAa,WAAW,GAAG;AAE7D,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAEA,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,SAAS,cAAc,OAAO;AASpC,QAAM,sBAA8C,CAAC;AACrD,QAAM,WAAqB,CAAC;AAE5B,EAAAA,cAAa,QAAQ,CAAC,IAAI,QAAQ;AAChC,UAAM,QAAQ,GAAG,cAAc,KAAK,IAAI,YAAY;AACpD,UAAM,MAAM,GAAG,YAAY,KAAK,IAAI,YAAY;AAChD,QAAI,SAAS,IAAI;AAEf;AAAA,IACF;AACA,wBAAoB,KAAK,EAAE;AAC3B,aAAS,KAAK,GAAG;AAAA,EACnB,CAAC;AAQD,MAAI,iBAA6C,CAAC;AAClD,MAAI,oBAAoB,SAAS,GAAG;AAElC,UAAM,WAAW,uBAAuB,qBAAqB,OAAO;AACpE,QAAI,iBAAiB,IAAI,QAAQ,GAAG;AAElC,uBAAiB,MAAM,iBAAiB,IAAI,QAAQ;AAAA,IACtD,OAAO;AASL,YAAM,sBAAsB,YAAY;AACtC,YAAI;AAGF,gBAAM,iBAAiB,QAAQ,oBAC3B,MAAM,QAAQ,kBAAkB,IAChC;AAEJ,gBAAM,aAAa,IAAI,gBAAgB;AACvC,gBAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,GAAI;AAE3D,gBAAM,OAAO,MAAM,MAAM,GAAG,cAAc,cAAc;AAAA,YACtD,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,gBAAgB;AAAA,cAChB,GAAI,SAAS,EAAE,eAAe,UAAU,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC;AAAA,YAC7E;AAAA,YACA,MAAM,KAAK,UAAU;AAAA,cACnB,CAAC,sBAAsB,GAAG,oBAAoB,IAAI,CAAC,OAAO;AAAA,gBACxD,CAAC,cAAc,GAAG,EAAE,cAAc;AAAA,gBAClC,CAAC,cAAc,GAAG,EAAE,cAAc;AAAA,gBAClC,CAAC,YAAY,GAAG,EAAE,YAAY;AAAA,gBAC9B,CAAC,aAAa,GAAG,EAAE,aAAa,KAAK,QAAQ,aAAa,KAAK;AAAA,gBAC/D,GAAG,eAAe,CAAC;AAAA,cACrB,EAAE;AAAA,cACF,CAAC,aAAa,GAAG,QAAQ,aAAa,KAAK;AAAA,cAC3C,GAAI,iBAAiB,EAAE,CAAC,mBAAmB,GAAG,eAAe,IAAI,CAAC;AAAA,YACpE,CAAC;AAAA,YACD,QAAQ,WAAW;AAAA,UACrB,CAAC;AAED,uBAAa,SAAS;AAWtB,cAAI,CAAC,KAAK,IAAI;AACZ,oBAAQ;AAAA,cACN;AAAA,cACA,KAAK;AAAA,cACL,KAAK;AAAA,YACP;AACA,kBAAM,IAAI,MAAM,6BAA6B,KAAK,MAAM,IAAI,KAAK,UAAU,EAAE;AAAA,UAC/E;AAEA,cAAI;AAKJ,cAAI;AACF,qBAAS,MAAM,KAAK,MAAM,EAAE,KAAK;AAAA,UAMnC,SAAS,SAAS;AAChB,oBAAQ,MAAM,mDAAmD,OAAO;AACxE,kBAAM,IAAI,MAAM,kCAAkC,OAAO,EAAE;AAAA,UAC7D;AASA,gBAAM,OAAO,UAAU,CAAC;AAGxB,cAAI,KAAK,eAAe,GAAG;AACzB,oBAAQ,KAAK,yCAAyC,KAAK,eAAe,CAAC;AAG3E,mBAAO,oBAAoB,IAAI,CAAC,iBAAiB;AAAA,cAC/C,CAAC,cAAc,GAAG,YAAY,cAAc;AAAA,cAC5C,CAAC,eAAe,GAAG,KAAK,eAAe;AAAA,YACzC,EAAE;AAAA,UACJ;AAEA,gBAAM,UAAU,MAAM,QAAQ,KAAK,sBAAsB,CAAC,IACtD,KAAK,sBAAsB,EAAE,IAAI,CAAC,aAAa,UAAU;AACvD,kBAAM,eAAe,oBAAoB,KAAK,IAAI,cAAc,KAAK;AAGrE,gBAAI,YAAY,eAAe,GAAG;AAChC,sBAAQ;AAAA,gBACN,2CAA2C,YAAY;AAAA,gBACvD,YAAY,eAAe;AAAA,cAC7B;AACA,qBAAO;AAAA,gBACL,CAAC,cAAc,GAAG;AAAA;AAAA,gBAClB,CAAC,eAAe,GAAG,YAAY,eAAe;AAAA,cAChD;AAAA,YACF;AAGA,gBAAI,YAAY,cAAc,KAAK,CAAC,YAAY,cAAc,GAAG;AAC/D,qBAAO;AAAA,gBACL,CAAC,cAAc,GAAG;AAAA;AAAA,gBAClB,CAAC,cAAc,GAAG,YAAY,cAAc;AAAA,cAC9C;AAAA,YACF;AAGA,mBAAO;AAAA,cACL,CAAC,cAAc,GAAG,YAAY,cAAc,KAAK;AAAA,YACnD;AAAA,UACF,CAAC,IACD,KAAK,cAAc,IACjB,CAAC,EAAE,CAAC,cAAc,GAAG,KAAK,cAAc,EAAE,CAAC,IAC3C,CAAC;AAOP,iBAAO;AAAA,QACT,SAAS,OAAgB;AAEvB,2BAAiB,OAAO,QAAQ;AAEhC,cAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,kBAAMC,WAAU,yBAAyB,cAAc;AACvD,oBAAQ,MAAMA,QAAO;AACrB,kBAAM,IAAI,MAAMA,QAAO;AAAA,UACzB;AACA,gBAAM,UAAU,sCAAsC,cAAc;AACpE,kBAAQ,MAAM,OAAO;AACrB,gBAAM,IAAI,MAAM,OAAO;AAAA,QACzB;AAAA,MACF,GAAG;AAGH,uBAAiB,IAAI,UAAU,kBAAkB;AACjD,uBAAiB,MAAM;AAAA,IACzB;AAAA,EACF;AAGA,QAAM,QAAQD,cAAa,IAAI,CAAC,IAAI,QAAQ;AAC1C,UAAM,QAAQ,GAAG,cAAc,KAAK,IAAI,YAAY;AACpD,UAAM,MAAM,GAAG,YAAY,KAAK,IAAI,YAAY;AAChD,QAAI,SAAS,GAAI,QAAO,EAAE,CAAC,cAAc,GAAG,GAAG,cAAc,EAAE;AAE/D,UAAM,SAAS,SAAS,QAAQ,GAAG;AACnC,QAAI,WAAW,GAAI,QAAO,eAAe,MAAM,KAAK,EAAE,CAAC,cAAc,GAAG,GAAG,cAAc,EAAE;AAC3F,WAAO,EAAE,CAAC,cAAc,GAAG,GAAG,cAAc,EAAE;AAAA,EAChD,CAAC;AASD,SAAO;AACT;;;ACrTA,IAAAE,cAA8B;;;ACA9B;AAAO,SAAS,YAAY,MAAiB;AAC3C,MAAI,YAAY,OAAO,YAAY,IAAI,KAAK;AAE1C,YAAQ,MAAM,GAAG,IAAI;AAAA,EACvB;AACF;;;ACLA,SAAoB;AAGpB,eAAsB,iBAAyC;AAE7D,QAAM,gBAAgB,0BAA0B;AAChD,MAAI,cAAe,QAAO;AAG1B,QAAM,kBAAkB,uBAAuB;AAC/C,MAAI,gBAAiB,QAAO;AAG5B,SAAO,MAAM,iBAAiB;AAChC;AAGA,SAAS,yBAAwC;AAC/C,MAAI;AACF,UAAM,WAAW,KAAK,eAAe,EAAE,gBAAgB,EAAE;AACzD,WAAO,6BAA6B,QAAQ;AAAA,EAC9C,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAGO,SAAS,6BAA6B,UAAiC;AAC5E,MAAI;AACF,UAAM,UAAa,yBAAsB,QAAQ;AACjD,WAAO,SAAS,MAAM;AAAA,EACxB,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAGA,eAAe,mBAA2C;AACxD,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,wBAAwB;AACrD,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,KAAK,gBAAgB;AAAA,EAC9B,SAAS,OAAO;AACd,WAAO;AAAA,EACT;AACF;AAGO,SAAS,4BAA2C;AACzD,QAAM,QAAQ,UAAU,aAAa,CAAC,UAAU,QAAQ;AACxD,aAAW,UAAU,OAAO;AAC1B,UAAM,QAAQ,OAAO,MAAM,GAAG;AAC9B,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,MAAM,CAAC,EAAE,YAAY;AAAA,IAC9B;AAAA,EACF;AACA,SAAO;AACT;;;AC7CA,IAAM,cAAc,IAAI,KAAK,KAAK,KAAK;AACvC,IAAM,mBAAmB,IAAI,OAAO;AACpC,IAAM,oBAAoB;AAEnB,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EAER,YAAY,UAAwB,CAAC,GAAG;AACtC,SAAK,UAAU;AAAA,MACb,KAAK,QAAQ,OAAO;AAAA,MACpB,SAAS,QAAQ,WAAW;AAAA,MAC5B,UAAU,QAAQ,YAAY;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,IAAO,KAAa,MAAS,KAAuB;AAClD,QAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAI;AACF,YAAM,OAAqB;AAAA,QACzB;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,QACpB,KAAK,OAAO,KAAK,QAAQ;AAAA,MAC3B;AAEA,YAAM,aAAa,KAAK,UAAU,IAAI;AACtC,YAAM,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE;AAGpC,UAAI,OAAO,KAAK,QAAQ,SAAS;AAC/B,gBAAQ,KAAK,4BAA4B,IAAI,qBAAqB,KAAK,QAAQ,OAAO,EAAE;AACxF,eAAO;AAAA,MACT;AAGA,WAAK,QAAQ;AAGb,YAAM,cAAc,KAAK,eAAe;AACxC,UAAI,cAAc,OAAO,KAAK,QAAQ,SAAS;AAC7C,gBAAQ,KAAK,8DAA8D;AAC3E,eAAO;AAAA,MACT;AAEA,mBAAa,QAAQ,KAAK,UAAU;AACpC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,KAAK,2CAA2C,GAAG,KAAK,KAAK;AACrE,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAO,KAAuB;AAC5B,QAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAI;AACF,YAAM,OAAO,aAAa,QAAQ,GAAG;AACrC,UAAI,CAAC,KAAM,QAAO;AAElB,YAAM,YAA0B,KAAK,MAAM,IAAI;AAC/C,YAAM,MAAM,KAAK,IAAI;AAGrB,UAAI,MAAM,UAAU,YAAY,UAAU,KAAK;AAC7C,qBAAa,WAAW,GAAG;AAC3B,eAAO;AAAA,MACT;AAEA,aAAO,UAAU;AAAA,IACnB,SAAS,OAAO;AACd,cAAQ,KAAK,2CAA2C,GAAG,KAAK,KAAK;AACrE,mBAAa,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,KAAsB;AAC3B,QAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAI;AACF,mBAAa,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,KAAK,8CAA8C,GAAG,KAAK,KAAK;AACxE,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SAAwB;AAC5B,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI;AACF,UAAI,SAAS;AAEX,eAAO,KAAK,YAAY,EAAE,QAAQ,CAAC,QAAQ;AACzC,cAAI,IAAI,SAAS,OAAO,GAAG;AACzB,yBAAa,WAAW,GAAG;AAAA,UAC7B;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AAEL,eAAO,KAAK,YAAY,EAAE,QAAQ,CAAC,QAAQ;AACzC,cAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,yBAAa,WAAW,GAAG;AAAA,UAC7B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,yCAAyC,KAAK;AAAA,IAC7D;AAAA,EACF;AAAA,EAEQ,UAAgB;AACtB,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI;AACF,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,QAAiE,CAAC;AAGxE,aAAO,KAAK,YAAY,EAAE,QAAQ,CAAC,QAAQ;AACzC,YAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,cAAI;AACF,kBAAM,OAAO,aAAa,QAAQ,GAAG;AACrC,gBAAI,MAAM;AACR,oBAAM,YAA4B,KAAK,MAAM,IAAI;AACjD,oBAAM,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;AAG9B,kBAAI,MAAM,UAAU,YAAY,UAAU,KAAK;AAC7C,6BAAa,WAAW,GAAG;AAC3B;AAAA,cACF;AAEA,oBAAM,KAAK;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA,WAAW,UAAU;AAAA,cACvB,CAAC;AAAA,YACH;AAAA,UACF,SAAS,OAAO;AAEd,yBAAa,WAAW,GAAG;AAAA,UAC7B;AAAA,QACF;AAAA,MACF,CAAC;AAGD,YAAM,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAG9C,aAAO,MAAM,SAAS,KAAK,QAAQ,UAAU;AAC3C,cAAM,SAAS,MAAM,MAAM;AAC3B,YAAI,QAAQ;AACV,uBAAa,WAAW,OAAO,GAAG;AAAA,QACpC;AAAA,MACF;AAGA,UAAI,YAAY,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,MAAM,CAAC;AAC9D,aAAO,YAAY,KAAK,QAAQ,WAAW,MAAM,SAAS,GAAG;AAC3D,cAAM,SAAS,MAAM,MAAM;AAC3B,YAAI,QAAQ;AACV,uBAAa,WAAW,OAAO,GAAG;AAClC,uBAAa,OAAO;AAAA,QACtB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,2CAA2C,KAAK;AAAA,IAC/D;AAAA,EACF;AAAA,EAEQ,iBAAyB;AAC/B,QAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAI;AACF,UAAI,YAAY;AAChB,aAAO,KAAK,YAAY,EAAE,QAAQ,CAAC,QAAQ;AACzC,YAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,gBAAM,OAAO,aAAa,QAAQ,GAAG;AACrC,cAAI,MAAM;AACR,yBAAa,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;AAAA,UAChC;AAAA,QACF;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,KAAK,kDAAkD,KAAK;AACpE,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,WAA+E;AAC7E,QAAI,OAAO,WAAW,aAAa;AACjC,aAAO,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,KAAK,QAAQ,SAAS,UAAU,KAAK,QAAQ,SAAS;AAAA,IAC7F;AAEA,QAAI;AACF,UAAI,YAAY;AAChB,UAAI,YAAY;AAEhB,aAAO,KAAK,YAAY,EAAE,QAAQ,CAAC,QAAQ;AACzC,YAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,gBAAM,OAAO,aAAa,QAAQ,GAAG;AACrC,cAAI,MAAM;AACR,yBAAa,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;AAC9B;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAED,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,KAAK,QAAQ;AAAA,QACtB,UAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,6CAA6C,KAAK;AAC/D,aAAO,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,KAAK,QAAQ,SAAS,UAAU,KAAK,QAAQ,SAAS;AAAA,IAC7F;AAAA,EACF;AACF;AAGO,IAAM,eAAe,IAAI,aAAa;AAGtC,IAAM,WAAW,CAAI,KAAa,MAAS,QAA0B;AAC1E,SAAO,aAAa,IAAI,KAAK,MAAM,GAAG;AACxC;AAEO,IAAM,WAAW,CAAI,QAA0B;AACpD,SAAO,aAAa,IAAO,GAAG;AAChC;AAMO,IAAM,aAAa,CAAC,YAA2B;AACpD,SAAO,aAAa,MAAM,OAAO;AACnC;;;ACxPA,IAAM,eAAe,IAAI,KAAK,KAAK,KAAK;AACxC,IAAM,WAAW;AAOjB,eAAe,eACb,OACA,YACA,SACyB;AACzB,QAAM,WAAW,MAAM,IAAI,CAAC,UAAU;AAAA,IACpC,CAAC,cAAc,GAAG;AAAA,IAClB,CAAC,cAAc,GAAG;AAAA,IAClB,CAAC,YAAY,GAAG;AAAA,IAChB,CAAC,aAAa,GAAG;AAAA,EACnB,EAAE;AACF,MAAI;AACF,UAAM,UAAU,MAAM,eAAe,UAAU,OAAO;AACtD,UAAM,MAAe,CAAC;AACtB,UAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,YAAM,aAAa,QAAQ,CAAC,IAAI,cAAc;AAC9C,UAAI,WAAY,KAAI,IAAI,IAAI;AAAA,IAC9B,CAAC;AACD,WAAO;AAAA,EACT,SAAS,OAAgB;AACvB,aAAS,6CAA6C,KAAK;AAC3D,WAAO;AAAA,EACT;AACF;AASA,eAAsB,sBACpB,WACA,YACA,UAA6B,CAAC,GACC;AAC/B,QAAM,MAAM,cAAc,IAAI,YAAY;AAC1C,MAAI,CAAC,MAAM,OAAO,QAAQ,UAAU,WAAW,EAAG,QAAO;AAEzD,QAAM,WAAW,oBAAoB,EAAE;AACvC,MAAI,MAAM,SAAkB,QAAQ;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC;AACvE,UAAM,MAAM,eAAe,OAAO,IAAI,OAAO;AAC7C,QAAI,OAAO,OAAO,KAAK,GAAG,EAAE,OAAQ,UAAS,UAAU,KAAK,YAAY;AAAA,EAC1E;AACA,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,WAAW;AACjB,SAAO,UAAU,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,cAAc,SAAS,EAAE,IAAI,KAAK,EAAE,aAAa,EAAE;AAC1F;;;AJxDA,IAAM,yBAAgD,iBAAI,CAAC,CAAC;AAC5D,IAAM,mBAA0C,sBAAS,CAAC,CAAC;AAC3D,IAAM,qBAA4C,sBAAS,CAAC,CAAC;AAC7D,IAAM,sBAA+B,iBAAI,IAAI;AAG7C,IAAI,kBAA0B;AAG9B,IAAI,gBAAgB;AAGpB,IAAI,kBAA+C;AACnD,IAAI,oBAAoB;AACxB,IAAI,oBAA0D;AAE9D,IAAM,sBAAsB;AAqBrB,SAAS,cAAc,UAA6B,CAAC,GAAG;AAG7D,MAAI,QAAQ,gBAAgB;AAC1B,sBAAkB,QAAQ;AAAA,EAC5B;AAEA,QAAM,iBAAiB;AACvB,QAAM,kBAAkB,QAAQ,mBAAmB;AAEnD,QAAM,gBAAY,iBAAI,KAAK;AAI3B,MAAI,oBAAoB,QAAQ,gBAAgB,UAAU,MAAM;AAC9D,oBAAgB,QAAQ;AAAA,EAC1B;AAGA,MAAI,OAAO,WAAW,eAAe,gBAAgB,UAAU,MAAM;AACnE,UAAM,gBAAgB,aAAa,QAAQ,oBAAoB;AAC/D,QAAI,eAAe;AACjB,sBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF;AASA,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,kBAAkB,SAA+B,mBAAmB;AAC1E,QAAI,mBAAmB,mBAAmB,MAAM,WAAW,GAAG;AAC5D,yBAAmB,QAAQ;AAC3B,eAAS,8DAA8D,gBAAgB,MAAM;AAAA,IAC/F,WAAW,iBAAiB;AAC1B;AAAA,QACE;AAAA,QACA,mBAAmB,MAAM;AAAA,MAC3B;AAAA,IACF,OAAO;AACL,eAAS,uCAAuC;AAAA,IAClD;AAAA,EACF;AAMA,QAAM,sBAAsB,CAAC,SAAiB;AAC5C,UAAM,OAAO,mBAAmB;AAChC,QAAI,CAAC,KAAK,OAAQ;AAClB,0BAAsB,MAAM,MAAM,EAAE,eAAe,CAAC,EACjD,KAAK,CAAC,cAAc;AACnB,UAAI,cAAc,QAAQ,mBAAmB,UAAU,MAAM;AAC3D,2BAAmB,QAAQ;AAAA,MAC7B;AAAA,IACF,CAAC,EACA,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACnB;AAEA,QAAM,cAAc,CAAC,SAAiB;AACpC,QAAI,QAAQ,SAAS,gBAAgB,OAAO;AAAA,IAE5C;AACA,oBAAgB,QAAQ;AAGxB,QAAI,OAAO,WAAW,aAAa;AACjC,mBAAa,QAAQ,sBAAsB,IAAI;AAAA,IACjD;AAEA,wBAAoB,IAAI;AAAA,EAC1B;AAEA,QAAM,iBAAiB,OACrB,OAAiE,CAAC,MAC/D;AACH,UAAM,EAAE,QAAQ,OAAO,SAAS,iBAAiB,SAAS,IAAI;AAK9D,UAAM,aACJ,CAAC,CAAC,oBAAoB,aAAa,UAAa,KAAK,IAAI,IAAI,oBAAoB;AAEnF,aAAS,sCAAsC;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,CAAC,CAAC;AAAA,MACZ,YAAY,CAAC,CAAC;AAAA,MACd,0BAA0B,mBAAmB,MAAM;AAAA,IACrD,CAAC;AAED,QAAI,CAAC,OAAO;AACV,UAAI,YAAY;AACd,iBAAS,2CAA2C,gBAAiB,MAAM;AAC3E,eAAO;AAAA,MACT;AACA,UAAI,mBAAmB;AACrB,iBAAS,wCAAwC;AACjD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI;AAEF,UAAI,cAAc,mBAAmB;AACrC,UACE,CAAC,eACD,CAAC,mBACD,mBAAmB,SACnB,mBAAmB,MAAM,QACzB;AACA,cAAM,cAAc,gBAAgB;AACpC,cAAM,QAAQ,mBAAmB,MAAM;AAAA,UACrC,CAAC,MAA0B,EAAE,SAAS;AAAA,QACxC;AACA,YAAI,OAAO;AACT,gBAAM,IAAI,MAAM,QAAQ,MAAM,YAAY,IACtC,MAAM,aAAa,CAAC,IACpB,OAAO,MAAM,iBAAiB,WAC3B,MAAM,aAAwB,MAAM,GAAG,EAAE,CAAC,IAC3C;AACN,cAAI,EAAG,eAAc,EAAE,YAAY;AAAA,QACrC;AAAA,MACF;AACA,UAAI,CAAC,eAAe,CAAC,mBAAmB,OAAO,WAAW,aAAa;AAErE,cAAM,KAAK,MAAM,eAAe;AAChC,sBAAc;AAAA,MAChB;AAEA,UAAI,MAAM;AAEV,YAAM,WACH,OAAO,cAAc,eAAe,UAAU,aAAa,UAAU,UAAU,CAAC,KAChF,OAAO,cAAc,eAAe,UAAU,YAC/C;AACF,YAAM,WACH,OAAO,SAAS,eAAe,KAAK,eAAe,EAAE,gBAAgB,EAAE,YAAa;AACvF,YAAM,SAAS,IAAI,gBAAgB;AACnC,UAAI,YAAa,QAAO,OAAO,WAAW,WAAW;AACrD,UAAI,SAAU,QAAO,OAAO,YAAY,QAAQ;AAChD,UAAI,SAAU,QAAO,OAAO,YAAY,QAAQ;AAChD,UAAI,MAAM,KAAK,MAAM,EAAE,SAAS,EAAG,QAAO,IAAI,OAAO,SAAS,CAAC;AAG/D,0BAAoB,MAAM,GAAG,cAAc,GAAG,GAAG,EAAE,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC;AAC7E,YAAM,WAAY,MAAM;AAGxB,YAAM,UAAgC,MAAM,QAAQ,QAAQ,IACxD,WACA,SAAS,aAAa,CAAC;AAG3B,YAAM,SAA+B,QAAQ;AAAA,QAC3C,CAAC,SAAoE;AACnE,cAAI,OAAO,KAAK,gBAAgB,KAAK;AACrC,cAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,mBAAO,KAAK,CAAC;AAAA,UACf;AACA,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO,KAAK;AAAA,YACZ,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAiC,OAAO,OAAO,CAAC,MAAM;AAC1D,YAAI,EAAE,KAAK,WAAW,IAAI,GAAG;AAC3B,iBAAO,EAAE,SAAS,aAAa,EAAE,SAAS;AAAA,QAC5C;AACA,eAAO;AAAA,MACT,CAAC;AAED,yBAAmB,QAAQ;AAC3B,eAAS,uCAAuC,SAAS,MAAM;AAG/D,UAAI,OAAO,WAAW,aAAa;AACjC,cAAM,QAAQ,SAAS,qBAAqB,UAAU,IAAI,KAAK,KAAK,KAAK,GAAI;AAC7E;AAAA,UACE;AAAA,UACA,QAAQ,YAAY;AAAA,UACpB,SAAS;AAAA,QACX;AAAA,MACF;AAGA,UAAI,CAAC,iBAAiB,CAAC,aAAa,QAAQ,oBAAoB,GAAG;AACjE,cAAM,SACJ,OAAO,cAAc,cACjB,UAAU,YAAY,CAAC,KAAK,UAAU,YAAY,KAClD;AACN,cAAM,cAAc,OAAO,MAAM,GAAG,EAAE,CAAC;AAEvC,YAAI,aAAa;AACf,cAAI,OAAuC;AAG3C,cAAI,gBAAgB,MAAM;AACxB,kBAAM,UAAU,QAAQ,KAAK,MAAM,KAAK,WAAW;AACnD,kBAAM,SAAS,UAAU,YAAY;AACrC,mBAAO,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,MAAM;AAAA,UAC9C,WAAW,gBAAgB,MAAM;AAC/B,mBACE,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS,KACxC,OAAO,KAAK,CAAC,MAAM,EAAE,KAAK,WAAW,IAAI,CAAC;AAAA,UAC9C,OAAO;AAEL,mBAAO,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW;AAGjD,gBAAI,CAAC,MAAM;AACT,qBAAO,OAAO,KAAK,CAAC,MAAM,EAAE,KAAK,WAAW,WAAW,CAAC;AAAA,YAC1D;AAAA,UACF;AAEA,cAAI,QAAQ,KAAK,OAAO;AACtB,wBAAY,KAAK,KAAK;AAAA,UACxB;AAAA,QACF;AACA,wBAAgB;AAAA,MAClB;AACA,wBAAkB;AAClB,0BAAoB,KAAK,IAAI;AAC7B,0BAAoB;AAEpB,0BAAoB,gBAAgB,KAAK;AAEzC,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,eAAS,qCAAqC,EAAE,MAAM,CAAC;AACvD,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAKA,QAAM,sBAAsB,MAAM;AAChC,sBAAkB;AAClB,wBAAoB;AACpB,wBAAoB;AACpB,QAAI,OAAO,WAAW,aAAa;AACjC,iBAAW,mBAAmB;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,oBAAoB,MAAM;AAC9B,WAAO,KAAK,YAAY,EAAE,QAAQ,CAAC,QAAQ,OAAO,aAAa,GAAG,CAAC;AACnE,WAAO,KAAK,cAAc,EAAE,QAAQ,CAAC,QAAQ,OAAO,eAAe,GAAG,CAAC;AAGvE,QAAI,OAAO,WAAW,aAAa;AACjC,iBAAW,oBAAoB;AAC/B,iBAAW,uBAAuB;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AKrSO,IAAM,sBAAN,MAA0B;AAAA,EAW/B,YACU,UAA2B,CAAC,GAC5B,gBACAC,kBACA,iBACR;AAJQ;AACA;AACA,2BAAAA;AACA;AAAA,EACP;AAAA,EAfK,kBAAkB,oBAAI,IAAY;AAAA,EAClC,WAAW,oBAAI,IAGrB;AAAA,EACM,eAAsC;AAAA,EACtC,iBAAiB,oBAAI,IAAY;AAAA,EACjC,+BAA+B;AAAA,EAC/B,gBAA+B;AAAA,EASvC,IAAY,oBAAoB;AAC9B,WAAO,KAAK,QAAQ,qBAAqB;AAAA,EAC3C;AAAA,EAEA,IAAY,qBAAqB;AAC/B,WAAO,KAAK,QAAQ,sBAAsB;AAAA,EAC5C;AAAA,EAEA,IAAY,eAAe;AACzB,WAAO,KAAK,QAAQ,gBAAgB;AAAA,EACtC;AAAA,EAEA,IAAY,cAAc;AACxB,WAAO,KAAK,QAAQ,eAAe;AAAA,EACrC;AAAA,EAEQ,8BAA8B;AACpC,QAAI,KAAK,6BAA8B;AACvC,SAAK,+BAA+B;AACpC,mBAAe,MAAM;AACnB,WAAK,eAAe,MAAM;AAC1B,WAAK,+BAA+B;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,YAAY;AAChC,UAAM,cAA8B,CAAC;AACrC,eAAW,CAAC,UAAU,GAAG,KAAK,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC,GAAG;AACjE,UAAI,CAAC,OAAO,IAAI,SAAS,GAAG;AAC1B,aAAK,SAAS,OAAO,QAAQ;AAC7B;AAAA,MACF;AACA,YAAM,CAAC,MAAM,EAAE,IAAI,SAAS,MAAM,GAAG;AACrC,iBAAW,CAAC,UAAU,IAAI,KAAK,IAAI,QAAQ,GAAG;AAC5C,oBAAY,KAAK;AAAA,UACf,CAAC,cAAc,GAAG,KAAK,cAAc;AAAA,UACrC,CAAC,aAAa,GAAG,KAAK,aAAa;AAAA,UACnC,CAAC,cAAc,GAAG;AAAA,UAClB,CAAC,YAAY,GAAG;AAAA,UAChB;AAAA,UACA,kBAAkB,KAAK;AAAA,QACzB,CAAC;AAAA,MACH;AACA,WAAK,SAAS,OAAO,QAAQ;AAAA,IAC/B;AAEA,QAAI,YAAY,SAAS,GAAG;AAG1B;AAAA,QACE;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,MACF;AAGA,YAAM,SAAS,KAAK,WAAW,aAAa,KAAK,YAAY;AAE7D,iBAAW,SAAS,QAAQ;AAC1B,YAAI;AACF,gBAAM,KAAK,wBAAwB,KAAK;AAAA,QAC1C,SAAS,OAAO;AACd,mBAAS,kDAAkD,KAAK;AAChE,gBAAM,QAAQ,CAAC,QAAQ,KAAK,gBAAgB,OAAO,IAAI,QAAQ,CAAC;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAGA,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,WAAc,OAAY,MAAqB;AACrD,UAAM,SAAgB,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,MAAM;AAC3C,aAAO,KAAK,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB,MAAM;AAC5B,QAAI,KAAK,cAAc;AACrB,mBAAa,KAAK,YAAY;AAAA,IAChC;AAGA,QAAI,aAAa;AACjB,eAAW,OAAO,KAAK,SAAS,OAAO,GAAG;AACxC,oBAAc,IAAI;AAAA,IACpB;AAGA,QAAI,KAAK,iBAAiB,KAAK,IAAI,IAAI,KAAK,iBAAiB,KAAK,aAAa;AAC7E,eAAS,4DAA4D,YAAY,OAAO;AACxF,WAAK,YAAY;AACjB;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK,SAAS,SAAS,IAAI,KAAK,oBAAoB,KAAK;AACvE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC;AAAA,IACpC;AACA,SAAK,eAAe,WAAW,MAAM;AACnC,WAAK,YAAY;AACjB,WAAK,eAAe;AAAA,IACtB,GAAG,KAAK;AAAA,EACV;AAAA,EAEO,iBACL,MACA,KACA,MACA,IACA,UACA,gBACA;AACA,QAAI,KAAK,gBAAgB,IAAI,QAAQ,KAAK,KAAK,eAAe,IAAI,QAAQ,GAAG;AAE3E,eAAS,6CAA6C,QAAQ;AAC9D;AAAA,IACF;AAGA,QAAI,KAAK,kBAAkB,MAAM;AAC/B,WAAK,gBAAgB,KAAK,IAAI;AAAA,IAChC;AAEA,SAAK,eAAe,IAAI,QAAQ;AAChC,SAAK,4BAA4B;AACjC,SAAK,gBAAgB,IAAI,QAAQ;AAEjC,UAAM,WAAW,GAAG,IAAI,IAAI,EAAE;AAC9B,QAAI,CAAC,KAAK,SAAS,IAAI,QAAQ,GAAG;AAChC,WAAK,SAAS,IAAI,UAAU,oBAAI,IAAI,CAAC;AAAA,IACvC;AAEA,SAAK,SAAS,IAAI,QAAQ,EAAG,IAAI,UAAU;AAAA,MACzC,CAAC,cAAc,GAAG;AAAA,MAClB,CAAC,aAAa,GAAG;AAAA,MACjB,kBAAkB;AAAA,IACpB,CAAC;AAED,aAAS,6CAA6C;AAAA,MACpD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAc,wBAAwB,UAA0B;AAC9D,UAAM,UAA6C,CAAC;AACpD,aAAS,QAAQ,CAAC,QAAQ;AACxB,YAAM,MAAM,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE;AACjC,UAAI,CAAC,QAAQ,GAAG,EAAG,SAAQ,GAAG,IAAI,CAAC;AACnC,cAAQ,GAAG,EAAE,KAAK,GAAG;AAAA,IACvB,CAAC;AAED,UAAM,aAAyC,CAAC;AAChD,UAAM,cAA8B,CAAC;AACrC,eAAW,CAAC,UAAU,aAAa,KAAK,OAAO,QAAQ,OAAO,GAAG;AAC/D,YAAM,CAAC,MAAM,EAAE,IAAI,SAAS,MAAM,GAAG;AAErC,UAAI;AAEF,cAAM,WAAW,CAAC,GAAG,IAAI,IAAI,cAAc,IAAI,CAAC,QAAQ,IAAI,aAAa,CAAC,CAAC,CAAC;AAC5E,cAAM,mBAAmB,SAAS,WAAW,KAAK,SAAS,CAAC,MAAM;AAGlE;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA,cAAc;AAAA,UACd;AAAA,UACA;AAAA,QACF;AAEA,cAAM,YAAY,CAAC,mBACjB,KAAK,UAAU;AAAA,UACb,cAAc,cAAc,IAAI,CAAC,SAAS;AAAA,YACxC,CAAC,cAAc,GAAG,IAAI,cAAc;AAAA,YACpC,GAAI,mBAAmB,CAAC,IAAI,EAAE,CAAC,aAAa,GAAG,IAAI,aAAa,EAAE;AAAA,UACpE,EAAE;AAAA,UACF,CAAC,cAAc,GAAG;AAAA,UAClB,CAAC,YAAY,GAAG;AAAA,UAChB,GAAI,mBAAmB,EAAE,CAAC,aAAa,GAAG,KAAK,IAAI,CAAC;AAAA,UACpD,GAAI,iBAAiB,EAAE,CAAC,mBAAmB,GAAG,eAAe,IAAI,CAAC;AAAA,QACpE,CAAC;AAEH,cAAM,gBAAgB,CAAC,mBACrB,MAAM,GAAG,KAAK,cAAc,cAAc;AAAA,UACxC,QAAQ;AAAA;AAAA;AAAA,UAGR,aAAa;AAAA,UACb,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,UAAU,cAAc;AAAA,QAChC,CAAC;AAMH,YAAI,WAAW,MAAM,cAAc;AACnC,aACG,SAAS,WAAW,OAAO,SAAS,WAAW,QAChD,KAAK,QAAQ,mBACb;AACA,gBAAM,iBAAiB,MAAM,KAAK,QAAQ,kBAAkB;AAC5D,qBAAW,MAAM,cAAc,cAAc;AAAA,QAC/C;AAEA,YAAI;AACJ,YAAI;AACF,mBAAS,MAAM,SAAS,KAAK;AAAA,QAC/B,SAAS,YAAY;AACnB,mBAAS,2DAA2D,UAAU;AAC9E,gBAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,EAAE;AAAA,QAClE;AAGA,YAAI,CAAC,SAAS,IAAI;AAChB;AAAA,YACE;AAAA,YACA,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAGA,cAAI,UAAU,OAAO,eAAe,GAAG;AACrC;AAAA,cACE;AAAA,cACA,OAAO,eAAe;AAAA,YACxB;AAGA,kBAAM,iBAAiB,cAAc,IAAI,CAAC,SAAS;AAAA,cACjD,CAAC,cAAc,GAAG,IAAI,cAAc;AAAA,cACpC,CAAC,eAAe,GAAG,OAAO,eAAe;AAAA,YAC3C,EAAE;AAGF,uBAAW,KAAK,EAAE,CAAC,sBAAsB,GAAG,eAAe,CAAC;AAC5D,wBAAY,KAAK,GAAG,aAAa;AAGjC,0BAAc,QAAQ,CAAC,QAAQ;AAC7B,mBAAK,gBAAgB,OAAO,IAAI,QAAQ;AAAA,YAC1C,CAAC;AAGD,iBAAK,gBAAgB,YAAY,WAAW;AAC5C;AAAA,UACF;AAEA,gBAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,EAAE;AAAA,QAClE;AAGA,YAAI,OAAO,eAAe,GAAG;AAC3B,mBAAS,8CAA8C,OAAO,eAAe,CAAC;AAG9E,gBAAM,iBAAiB,cAAc,IAAI,CAAC,SAAS;AAAA,YACjD,CAAC,cAAc,GAAG,IAAI,cAAc;AAAA,YACpC,CAAC,eAAe,GAAG,OAAO,eAAe;AAAA,UAC3C,EAAE;AAGF,qBAAW,KAAK,EAAE,CAAC,sBAAsB,GAAG,eAAe,CAAC;AAC5D,sBAAY,KAAK,GAAG,aAAa;AAGjC,wBAAc,QAAQ,CAAC,QAAQ;AAC7B,iBAAK,gBAAgB,OAAO,IAAI,QAAQ;AAAA,UAC1C,CAAC;AAAA,QAGH,OAAO;AAEL,cAAI,OAAO,sBAAsB,GAAG;AAClC,mBAAO,sBAAsB,EAAE,QAAQ,CAAC,aAAkB,UAAkB;AAC1E,kBAAI,YAAY,eAAe,GAAG;AAChC,sBAAM,eAAe,cAAc,KAAK,IAAI,cAAc;AAC1D;AAAA,kBACE;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,YAAY,eAAe;AAAA,gBAC7B;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAEA,qBAAW,KAAK,MAAM;AACtB,sBAAY,KAAK,GAAG,aAAa;AAGjC,wBAAc,QAAQ,CAAC,QAAQ;AAC7B,iBAAK,gBAAgB,OAAO,IAAI,QAAQ;AAAA,UAC1C,CAAC;AAAA,QACH;AAAA,MACF,SAAS,OAAO;AACd,iBAAS,kDAAkD,UAAU,KAAK,KAAK;AAG/E,sBAAc,QAAQ,CAAC,QAAQ;AAC7B,eAAK,gBAAgB,OAAO,IAAI,QAAQ;AAAA,QAC1C,CAAC;AAGD,cAAM;AAAA,MACR;AAAA,IACF;AAEA,SAAK,gBAAgB,YAAY,WAAW;AAAA,EAC9C;AAAA,EAEO,aAAa,UAAkB;AACpC,SAAK,gBAAgB,OAAO,QAAQ;AAAA,EACtC;AAAA,EAEO,kBAAkB;AACvB,SAAK,gBAAgB,MAAM;AAAA,EAC7B;AAAA,EAEO,UAAU;AACf,SAAK,gBAAgB;AACrB,SAAK,SAAS,MAAM;AACpB,SAAK,eAAe,MAAM;AAC1B,QAAI,KAAK,cAAc;AACrB,mBAAa,KAAK,YAAY;AAC9B,WAAK,eAAe;AAAA,IACtB;AACA,SAAK,+BAA+B;AACpC,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEO,WAAW;AAChB,WAAO;AAAA,MACL,iBAAiB,KAAK,gBAAgB;AAAA,MACtC,eAAe,KAAK,SAAS;AAAA,MAC7B,gBAAgB,KAAK,eAAe;AAAA,MACpC,iBAAiB,CAAC,CAAC,KAAK;AAAA,IAC1B;AAAA,EACF;AACF;;;ARhYA,IAAI,uBAA8C;AAGlD,IACE,OAAO,WAAW,eACjB,OAA8C,sBAC/C;AACA,yBAAwB,OACrB;AACL;AAGA,SAAS,uBAA0B,WAAmC;AACpE,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,WAAO,UAAU;AAAA,EACnB,SAAS,GAAG;AACV,aAAS,mCAAmC,CAAC;AAC7C,WAAO;AAAA,EACT;AACF;AAGA,IAAI,CAAC,wBAAwB,OAAO,WAAW,aAAa;AAC1D,QAAM,SAAS,uBAAuB,MAAM,aAAa,QAAQ,0BAA0B,CAAC;AAC5F,MAAI,QAAQ;AAEV,UAAM,gBAAgB,EAAE,gBAAgB,OAAO;AAC/C,2BAAuB,qBAAqB,aAAa;AAAA,EAC3D;AACF;AAQA,SAAS,qBAAqB,UAA6B,CAAC,GAAG;AAC7D,QAAM,OAAO,cAAc,OAAO;AAClC,QAAM;AAAA,IACJ,oBAAAC;AAAA,IACA,cAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,QAAM,aAAa;AAAA,IACjB,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAGA,QAAM,gBAAgB,CAAC,aAA8C;AACnE,WAAO,OAAO,YAAY,QAAQ;AAAA,EACpC;AAEA,QAAM,gBAAgB,OAAO,EAAE,GAAG,WAAW;AAK7C,QAAM,OAAwB,CAAC;AAC/B,MAAI,QAAQ,gBAAiB,kBAAiB,QAAQ,eAAe;AAErE,WAAS,iBAAiB,SAA0B;AAClD,eAAW,QAAQ,OAAO,KAAK,OAAO,GAAG;AACvC,WAAK,IAAI,IAAI,EAAE,GAAI,KAAK,IAAI,KAAK,CAAC,GAAI,GAAG,QAAQ,IAAI,EAAE;AAAA,IACzD;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,MAAc,MAAc,QAC3C,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,EAAE;AAG/B,QAAM,YAAY;AAClB,QAAM,eAAe;AACrB,QAAMC,uBAAsB;AAG5B,QAAM,yBAAyB,MAAM;AACnC,QAAI,OAAO,WAAW,YAAa;AAEnC,UAAM,qBAAqB,SAAiD,SAAS;AACrF,UAAM,uBAAuB,SAAiD,YAAY;AAE1F,QAAI,oBAAoB;AAEtB,YAAM,cAAcD,iBAAgB;AACpC,YAAM,mBAAmB,mBAAmB,WAAW,KAAK,CAAC;AAC7D,aAAO,OAAOF,eAAc,gBAAgB;AAAA,IAC9C;AAEA,QAAI,sBAAsB;AAExB,YAAM,cAAcE,iBAAgB;AACpC,YAAM,qBAAqB,qBAAqB,WAAW,KAAK,CAAC;AACjE,aAAO,OAAOD,iBAAgB,kBAAkB;AAAA,IAClD;AAAA,EACF;AAGA,QAAM,yBAAyB,MAAM;AACnC,QAAI,OAAO,WAAW,YAAa;AAGnC,UAAM,uBAAuB,SAAiD,SAAS,KAAK,CAAC;AAC7F,UAAM,yBACJ,SAAiD,YAAY,KAAK,CAAC;AAGrE,UAAM,cAAcC,iBAAgB;AACpC,yBAAqB,WAAW,IAAI,EAAE,GAAGF,cAAa;AACtD,2BAAuB,WAAW,IAAI,EAAE,GAAGC,gBAAe;AAG1D,aAAS,WAAW,sBAAsB,IAAI,KAAK,KAAK,KAAK,GAAI;AACjE,aAAS,cAAc,wBAAwB,IAAI,KAAK,KAAK,KAAK,GAAI;AAAA,EACxE;AAGA,QAAM,sBAAsB,MAAM;AAChC,QAAI,OAAO,WAAW,YAAa;AAEnC,UAAM,kBAAkB,SAA+BE,oBAAmB;AAC1E,QAAI,iBAAiB;AACnB,MAAAJ,oBAAmB,QAAQ;AAAA,IAC7B;AAAA,EACF;AAGA,yBAAuB;AACvB,sBAAoB;AAGpB,yBAAMG,kBAAiB,MAAM;AAE3B,WAAO,KAAKF,aAAY,EAAE,QAAQ,CAAC,QAAQ,OAAOA,cAAa,GAAG,CAAC;AACnE,WAAO,KAAKC,eAAc,EAAE,QAAQ,CAAC,QAAQ,OAAOA,gBAAe,GAAG,CAAC;AACvE,2BAAuB;AAAA,EACzB,CAAC;AAGD,QAAM,WAAW,IAAI;AAAA,IACnB;AAAA,MACE,mBAAmB,QAAQ;AAAA,MAC3B,oBAAoB,QAAQ;AAAA,MAC5B,cAAc,QAAQ;AAAA,MACtB,aAAa,QAAQ;AAAA,MACrB,mBAAmB,QAAQ;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,MAAMC,iBAAgB;AAAA,IACtB,CAAC,SAAS,aAAa;AAKrB,eAAS,QAAQ,CAAC,QAAQ;AACxB,cAAM,WAAW,GAAG,IAAI,cAAc,CAAC,IAAI,IAAI,aAAa,CAAC;AAC7D,cAAM,mBAAmB,GAAG,QAAQ,IAAI,IAAI,cAAc,CAAC,IAAI,IAAI,YAAY,CAAC;AAChF,uBAAe,OAAO,gBAAgB;AAAA,MACxC,CAAC;AAID,UAAI,oBAA8C,CAAC;AACnD,cAAQ,QAAQ,CAAC,WAAW;AAC1B,YAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,8BAAoB,kBAAkB,OAAO,MAAM;AAAA,QACrD,WAAW,OAAO,gBAAgB,MAAM,QAAQ,OAAO,YAAY,GAAG;AACpE,8BAAoB,kBAAkB,OAAO,OAAO,YAAY;AAAA,QAClE;AAAA,MACF,CAAC;AAED,wBAAkB,QAAQ,CAAC,aAAa,QAAQ;AAC9C,cAAM,UAAU,SAAS,GAAG;AAC5B,YAAI,CAAC,SAAS;AACZ,mBAAS,oDAAoD,WAAW;AACxE;AAAA,QACF;AACA,cAAM,eAAe,QAAQ,cAAc;AAC3C,cAAM,cAAc,QAAQ,aAAa,MAAM,WAAW,OAAO;AAGjE,YAAI,YAAY,eAAe,GAAG;AAChC;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,YAAY,eAAe;AAAA,UAC7B;AAGA,gBAAM,WAAW,GAAG,YAAY,IAAI,WAAW,IAAI,QAAQ,cAAc,CAAC,IAAI,QAAQ,YAAY,CAAC;AACnG,4BAAkB,IAAI,UAAU,YAAY,eAAe,CAAC;AAE5D;AAAA,QACF;AAGA,YAAI,YAAY,cAAc,KAAK,CAAC,YAAY,cAAc,GAAG;AAC/D;AAAA,QACF;AAEA,cAAM,iBAAiB,YAAY,cAAc;AACjD,YAAI,gBAAgB;AAElB,gBAAM,oBAAoB,QAAQ,YAAY;AAC9C,gBAAM,iBAAiB,QAAQ;AAC/B,cAAI,CAAC,kBAAkB,sBAAsBA,iBAAgB,OAAO;AAClE,qBAAS,8CAA8C;AAAA,cACrD,UAAU;AAAA,cACV,YAAY;AAAA,cACZ;AAAA,cACA,iBAAiBA,iBAAgB;AAAA,YACnC,CAAC;AACD;AAAA,UACF;AAGA,cAAI,mBAAmB,cAAc;AACnC,qBAAS,yDAAyD;AAAA,cAChE,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,SAAS;AAAA,YACX,CAAC;AACD;AAAA,UACF;AAEA,gBAAM,eAAe;AAGrB,gBAAM,WAAW,QAAQ,YAAY,GAAG,YAAY,IAAI,YAAY;AACpE,gBAAM,QAAQ,iBAAiB,OAAOD,kBAAiBD;AAGvD,gBAAM,QAAQ,IAAI;AAGlB,mBAAS,mCAAmC;AAAA,YAC1C,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,SAAS;AAAA,YACT;AAAA,YACA,UAAU;AAAA,UACZ,CAAC;AAGD,iCAAuB;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,iBAAiB,oBAAI,IAAY;AAEvC,QAAM,kBAAkB,oBAAI,IAAmC;AAG/D,QAAM,oBAAoB,oBAAI,IAAoB;AAGlD,QAAM,oBAAoB,CACxB,MACA,KACA,cACA,QACAI,YAAW,UACR;AACH,QAAIA,WAAU;AACZ,WAAKF,iBAAgB;AAAA,IACvB;AACA,UAAM,OAAO,gBAAgB,WAAW,QAAQ;AAChD,UAAM,KAAK,UAAUA,iBAAgB;AAGrC,QAAI,SAAS,IAAI;AACf,aAAO;AAAA,IACT;AAGA,UAAM,eAAe,QAAQ,SAAY,MAAM,WAAW,OAAO;AACjE,UAAM,UAAU,GAAG,IAAI,IAAI,YAAY;AAKvC,UAAM,WAAW,OAAOA,iBAAgB,QAAQ,GAAG,OAAO,IAAI,IAAI,IAAI,EAAE,KAAK;AAC7E,UAAM,QAAQ,iBAAiB,OAAOD,kBAAiBD;AAGvD,QAAI,MAAM,QAAQ,GAAG;AACnB,aAAO,MAAM,QAAQ;AAAA,IACvB;AAGA,UAAM,SAAS,QAAQ,IAAI,MAAM,YAAY;AAC7C,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,GAAG,IAAI,IAAI,YAAY,IAAI,IAAI,IAAI,EAAE;AACtD,QAAI,kBAAkB,IAAI,QAAQ,GAAG;AACnC,aAAO;AAAA,IACT;AAGA,UAAM,mBAAmB,GAAG,OAAO,IAAI,IAAI,IAAI,EAAE;AACjD,QAAI,eAAe,IAAI,gBAAgB,GAAG;AACxC,aAAO;AAAA,IACT;AAGA,YAAQ,oBAAoB,EAAE,MAAM,KAAK,cAAc,MAAM,GAAG,CAAC;AAGjE,aAAS,iBAAiB,MAAM,cAAc,MAAM,IAAI,UAAU,WAAW,MAAS;AAGtF,mBAAe,IAAI,gBAAgB;AAInC,UAAM,aAAa;AACnB,UAAM,YAAY,WAAW,MAAM;AACjC,qBAAe,OAAO,gBAAgB;AACtC,sBAAgB,OAAO,SAAS;AAAA,IAClC,GAAG,UAAU;AACb,oBAAgB,IAAI,SAAS;AAG7B,WAAO;AAAA,EACT;AAMA,QAAM,IAAI,CAAC,MAAc,KAAc,cAAuB,WAC5D,kBAAkB,MAAM,KAAK,cAAc,QAAQ,KAAK;AAO1D,QAAM,KAAK,CAAC,MAAc,KAAc,cAAuB,WAC7D,kBAAkB,MAAM,KAAK,cAAc,QAAQ,IAAI;AAOzD,QAAM,kBAAkB,CAAC,MAAc,KAAc,WAA4B;AAC/E,UAAM,eAAe,QAAQ,SAAY,MAAM,WAAW,OAAO;AACjE,UAAM,OAAO,WAAW,QAAQ;AAChC,UAAM,KAAK,UAAUE,iBAAgB;AACrC,QAAI,SAAS,GAAI,QAAO;AACxB,UAAM,UAAU,GAAG,IAAI,IAAI,YAAY;AACvC,UAAM,WAAW,OAAOA,iBAAgB,QAAQ,GAAG,OAAO,IAAI,IAAI,IAAI,EAAE,KAAK;AAC7E,UAAM,QAAQ,iBAAiB,OAAOD,kBAAiBD;AACvD,WAAO,MAAM,QAAQ,KAAK,QAAQ,IAAI,MAAM,YAAY,KAAK;AAAA,EAC/D;AAOA,QAAM,mBAAmB,OACvB,MACA,MACA,OAAe,WAAW,QAAQ,OACE;AACpC,UAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,KAAK,EAAE,IAAI;AAC5C,QAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAEhC,UAAM,QAAQ,MAAM,IAAI,CAAC,OAAO;AAAA,MAC9B,CAAC,cAAc,GAAG,EAAE;AAAA,MACpB,CAAC,cAAc,GAAG;AAAA,MAClB,CAAC,YAAY,GAAG;AAAA,MAChB,CAAC,aAAa,GAAG,EAAE,OAAO,WAAW,OAAO;AAAA,IAC9C,EAAE;AAEF,UAAM,UAAU,MAAM,eAAe,OAAO;AAAA,MAC1C;AAAA,MACA,QAAQ,QAAQ;AAAA,MAChB,WAAW,QAAQ;AAAA,IACrB,CAAC;AAED,UAAM,WAAmC,CAAC;AAC1C,YAAQ,QAAQ,CAAC,KAAK,MAAM;AAC1B,YAAM,MAAM,MAAM,CAAC;AACnB,YAAM,aAAa,MAAM,cAAc;AACvC,UAAI,OAAO,cAAc,eAAe,IAAI,MAAM;AAChD,cAAM,MAAM,IAAI,OAAO,WAAW,OAAO;AACzC,iBAAS,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE,IAAI;AAAA,MACnC;AAAA,IACF,CAAC;AAED,QAAI,OAAO,KAAK,QAAQ,EAAE,SAAS,EAAG,kBAAiB,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;AAC3E,WAAO;AAAA,EACT;AAEA,QAAM,qBAAqB,OACzB,OACA,MACA,KAAKE,iBAAgB,OACrB,cACG;AACH,QAAI,MAAM,WAAW,EAAG;AAGxB,UAAM,gBAAgB,QAAQ,WAAW,QAAQ;AAGjD,QAAI,kBAAkB,IAAI;AACxB;AAAA,IACF;AAEA,cAAU,QAAQ;AAElB,QAAI;AAEF,YAAM,eAAe,aAAa,WAAW,OAAO;AAEpD,YAAM,WAAW,MAAM,MAAM,GAAG,cAAc,cAAc;AAAA,QAC1D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,cAAc,MAAM,IAAI,CAAC,UAAU;AAAA,YACjC,CAAC,cAAc,GAAG,KAAK,cAAc;AAAA,YACrC,CAAC,aAAa,GAAG,KAAK,aAAa,KAAK;AAAA,UAC1C,EAAE;AAAA,UACF,CAAC,cAAc,GAAG;AAAA,UAClB,CAAC,YAAY,GAAG;AAAA,QAClB,CAAC;AAAA,MACH,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,EAAE;AAAA,MAClE;AAEA,YAAM,SAAS,MAAM,SAAS,KAAK;AAGnC,UAAI,OAAO,eAAe,GAAG;AAC3B,iBAAS,oCAAoC,OAAO,eAAe,CAAC;AAGpE,cAAM,iBAAiB,MAAM,IAAI,CAAC,UAAU;AAAA,UAC1C,CAAC,cAAc,GAAG,KAAK,cAAc;AAAA,UACrC,CAAC,eAAe,GAAG,OAAO,eAAe;AAAA,QAC3C,EAAE;AAGF,uBAAe,QAAQ,CAAC,aAAqC,UAAkB;AAC7E,gBAAM,OAAO,MAAM,KAAK;AACxB,gBAAM,eAAe,OAAO,cAAc;AAC1C,cAAI,CAAC,cAAc;AACjB;AAAA,UACF;AAGA,cAAI,YAAY,eAAe,GAAG;AAChC;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA,YAAY,eAAe;AAAA,YAC7B;AAGA,kBAAM,WAAW,GAAG,YAAY,IAAI,KAAK,aAAa,KAAK,YAAY,IAAI,aAAa,IAAI,EAAE;AAC9F,8BAAkB,IAAI,UAAU,YAAY,eAAe,CAAC;AAE5D;AAAA,UACF;AAAA,QACF,CAAC;AAED;AAAA,MACF;AAEA,UAAI,OAAO,sBAAsB,GAAG;AAClC,eAAO,sBAAsB,EAAE;AAAA,UAC7B,CAAC,aAAqC,UAAkB;AACtD,kBAAM,OAAO,MAAM,KAAK;AACxB,kBAAM,eAAe,OAAO,cAAc;AAC1C,gBAAI,CAAC,cAAc;AACjB;AAAA,YACF;AAGA,gBAAI,YAAY,eAAe,GAAG;AAChC;AAAA,gBACE;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,YAAY,eAAe;AAAA,cAC7B;AACA;AAAA,YACF;AAGA,gBAAI,YAAY,cAAc,KAAK,CAAC,YAAY,cAAc,GAAG;AAE/D;AAAA,YACF;AAGA,kBAAM,iBAAiB,YAAY,cAAc;AACjD,gBAAI,gBAAgB;AAElB,kBAAI,OAAOA,iBAAgB,OAAO;AAChC,yBAAS,sDAAsD;AAAA,kBAC7D,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,mBAAmB;AAAA,kBACnB,iBAAiBA,iBAAgB;AAAA,gBACnC,CAAC;AACD;AAAA,cACF;AAGA,kBAAI,mBAAmB,cAAc;AACnC,yBAAS,iEAAiE;AAAA,kBACxE,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,SAAS,KAAK,aAAa,KAAK;AAAA,gBAClC,CAAC;AACD;AAAA,cACF;AAGA,oBAAM,cAAc,KAAK,aAAa;AACtC,oBAAM,iBAAiB,gBAAgB,SAAY,cAAc;AACjE,oBAAM,WAAW,GAAG,YAAY,IAAI,cAAc;AAClD,oBAAM,QAAQ,mBAAmB,OAAOD,kBAAiBD;AACzD,oBAAM,QAAQ,IAAI;AAGlB,uBAAS,2CAA2C;AAAA,gBAClD,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT;AAAA,gBACA,UAAU;AAAA,cACZ,CAAC;AAGD,qCAAuB;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AAAA,IACvD,UAAE;AACA,gBAAU,QAAQ;AAAA,IACpB;AAAA,EACF;AAGA,yBAAME,kBAAiB,MAAM;AAE3B,mBAAe,MAAM;AAGrB,2BAAuB;AAGvB,aAAS,QAAQ;AAAA,EACnB,CAAC;AAED,SAAO;AAAA;AAAA,IAEL,oBAAAH;AAAA,IACA,cAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA,IAGA,qBAAqB,CAAC,MAAc,KAAc,MAAe,OAAgB;AAC/E,YAAM,eAAe,QAAQ,SAAY,MAAM,WAAW,OAAO;AACjE,YAAM,gBAAgB,QAAQ,WAAW,QAAQ;AACjD,YAAM,cAAc,MAAMA,iBAAgB;AAC1C,YAAM,WAAW,GAAG,IAAI,IAAI,YAAY,IAAI,aAAa,IAAI,WAAW;AACxE,aAAO,kBAAkB,IAAI,QAAQ,KAAK;AAAA,IAC5C;AAAA;AAAA,IAGA,SAAS,MAAM;AACb,wBAAkB;AAClB,eAAS,QAAQ;AAEjB,sBAAgB,QAAQ,CAAC,OAAO,aAAa,EAAE,CAAC;AAChD,sBAAgB,MAAM;AACtB,wBAAkB,MAAM;AAAA,IAC1B;AAAA,IACA,kBAAkB,MAAM,SAAS,SAAS;AAAA;AAAA,IAG1C;AAAA,IACA;AAAA,EACF;AACF;AAIA,SAAS,0BAAiD;AACxD,MAAI,OAAO,WAAW,aAAa;AACjC,WACG,OAAgE,wBAAwB;AAAA,EAE7F;AACA,SAAO;AACT;AACA,SAAS,wBAAwB,UAA0B,SAA6B;AACtF,MAAI,OAAO,WAAW,aAAa;AACjC;AAAC,IAAC,OAAgE,uBAChE;AACF,QAAI,WAAW,QAAQ,gBAAgB;AACrC;AAAA,QAAuB,MACrB,aAAa,QAAQ,4BAA4B,QAAQ,cAAe;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AACA,yBAAuB;AACzB;AAEO,SAAS,UAAU,UAA6B,CAAC,GAAG;AACzD,QAAM,iBAAwC,wBAAwB;AAGtE,MAAI,gBAAgB;AAClB,UAAM,cAAc,eAAe;AACnC,UAAM,UAAU,QAAQ;AACxB,QAAI,CAAC,QAAQ,kBAAkB,gBAAgB,SAAS;AACtD,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,WAA2B,qBAAqB,OAAO;AAC7D,0BAAwB,UAAU,OAAO;AACzC,SAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADzpBA,UAAM,yBAAqB,iBAAI,KAAK;AAEpC,UAAM,QAAQ;AA2Bd,UAAM,OAAO;AAGb,UAAM,EAAE,oBAAAG,qBAAoB,iBAAAC,kBAAiB,aAAa,gBAAgB,GAAG,IAAI,UAAU;AAG3F,UAAM,yBAAqB,sBAAS,MAAM;AACxC,YAAM,YACJ,MAAM,aAAa,MAAM,UAAU,SAAS,IAAI,MAAM,YAAYD,oBAAmB;AAGvF,YAAM,YAAY,UAAU,IAAI,CAAC,UAAU;QACzC,GAAG;QACH,aAAa,KAAK,eAAe,KAAK;QACtC,cAAc,KAAK,gBAAgB,KAAK;MAC1C,EAAE;AAIF,aAAO;IACT,CAAC;AAED,UAAM,4BAAwB,sBAAS,MAAM;AAC3C,UAAI,CAACC,iBAAgB,MAAO,QAAO;AACnC,aAAO,mBAAmB,MAAM,KAAK,CAAC,SAAS,KAAK,SAASA,iBAAgB,KAAK,KAAK;IACzF,CAAC;AAGD,aAAS,sBAAsB,WAAgD;AAC7E,UAAI,UAAU,WAAW,EAAG,QAAO;AAGnC,YAAM,mBAAmB,UAAU,aAAa,CAAC,UAAU,YAAY,IAAI;AAG3E,iBAAW,eAAe,kBAAkB;AAC1C,cAAM,WAAW,YAAY,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACvD,cAAM,aAAa,UAAU,KAAK,CAAC,SAAS,KAAK,KAAK,YAAY,MAAM,QAAQ;AAChF,YAAI,YAAY;AACd,iBAAO,WAAW;QACpB;MACF;AAGA,iBAAW,eAAe,kBAAkB;AAC1C,cAAM,eAAe,YAAY,YAAY;AAC7C,cAAM,cAAc,UAAU,KAAK,CAAC,SAAS,KAAK,KAAK,YAAY,MAAM,YAAY;AACrF,YAAI,aAAa;AACf,iBAAO,YAAY;QACrB;MACF;AAEA,aAAO;IACT;AAEA,mBAAe,qBAAqB,kBAA6C;AAC/E,UAAI,kBAAkB;AAEpB,2BAAmB,QAAQ;AAE3B,YAAI;AACF,sBAAY,iBAAiB,IAAI;AAEjC,uBAAa,QAAQ,sBAAsB,iBAAiB,IAAI;AAChE,eAAK,qBAAqB,gBAAgB;QAC5C,UAAE;AAEA,6BAAmB,QAAQ;QAC7B;MACF;IACF;AAGA,2BAAMA,kBAAiB,CAAC,gBAAgB;AACtC,UAAI,aAAa;AACf,qBAAa,QAAQ,sBAAsB,WAAW;MACxD;IACF,CAAC;AAGD;MACE,MAAM,mBAAmB;MACzB,CAAC,iBAAiB;AAChB,YAAI,aAAa,SAAS,KAAK,CAACA,iBAAgB,OAAO;AAErD,gBAAM,oBAAoB,aAAa,QAAQ,oBAAoB;AAEnE,cAAI,mBAAmB;AAErB,kBAAM,kBAAkB,aAAa,KAAK,CAAC,SAAS,KAAK,SAAS,iBAAiB;AACnF,gBAAI,iBAAiB;AACnB,0BAAY,iBAAiB;AAC7B;YACF;UACF;AAGA,gBAAM,cAAc,sBAAsB,YAAY;AACtD,cAAI,aAAa;AACf,wBAAY,WAAW;UACzB;QACF;MACF;MACA,EAAE,WAAW,KAAK;IACpB;AAGA,+BAAU,YAAY;AAEpB,UAAI,CAAC,MAAM,aAAa,MAAM,UAAU,WAAW,GAAG;AAEpD,cAAM,cAAc,MAAM,eAAe;AACzC,cAAM,eAAe,EAAE,SAAS,eAAe,OAAU,CAAC;MAC5D;AAEA,YAAM,oBAAoB,aAAa,QAAQ,oBAAoB;AAEnE,UAAI,qBAAqB,sBAAsBA,iBAAgB,OAAO;AAEpE,cAAM,mBAAmB,mBAAmB;AAC5C,cAAM,kBAAkB,iBAAiB,KAAK,CAAC,SAAS,KAAK,SAAS,iBAAiB;AAEvF,YAAI,iBAAiB;AACnB,sBAAY,iBAAiB;QAC/B,WAAW,iBAAiB,SAAS,GAAG;AAEtC,gBAAM,cAAc,sBAAsB,gBAAgB;AAC1D,cAAI,aAAa;AACf,wBAAY,WAAW;UACzB;QACF;MACF,WAAW,CAACA,iBAAgB,SAAS,mBAAmB,MAAM,SAAS,GAAG;AAExE,cAAM,cAAc,sBAAsB,mBAAmB,KAAK;AAClE,YAAI,aAAa;AACf,sBAAY,WAAW;QACzB;MACF;IACF,CAAC;AAGD;MACE;MACA,CAAC,aAAa;AACZ,YAAI,UAAU;AACZ,eAAK,qBAAqB,QAAQ;QACpC;MACF;MACA,EAAE,WAAW,KAAK;IACpB;;+CAjNE,YAAAC,oBAoBM,OApBNC,aAoBM;2CAnBJ,YAAAC,aAQEC,yBAAA;UAPC,KAAG,kBAAoB,mBAAA,MAAmB,MAAM,IAAI,mBAAA,MAAkB,CAAA,GAAK,QAAI,OAAA;UAC/E,eAAa,sBAAA;UACb,WAAW,mBAAA;UACX,aAAa,MAAM;UACnB,UAAU,MAAM,YAAY,mBAAA;UAC5B,WAAS,MAAM;UACf,uBAAoB;;YAGvB,YAAAC,oBAAA,mBAAA;QAEQ,mBAAA,2CADR,YAAAJ;UAOM;UAAA;;YALJ,WAAK,YAAAK,gBAAA,CAAC,0BAAwB,EAAA,WACT,MAAM,OAAM,CAAA,CAAA;;;0CAEjC,YAAAC;cAAkC;cAAA,EAA7B,OAAM,iBAAgB;cAAA;cAAA;;YAAA;gBAC3B,YAAAA;cAAuE;cAAvEC;kBAAuE,YAAAC,qBAA1C,YAAAC,OAAA,EAAA,EAAE,wBAAA,IAAA,CAAA;cAAA;;YAAA;;;;;;;;;;;AUfrC,IAAOC,mCAAQ;AACf,gCAAO,YAAY;;;;;ACEnB,IAAAC,eAA0C;AAC1C,IAAAA,eAA8B;;;;;;;;;;;;;;;;;;;;;;;AAS9B,UAAM,aAAS,uBAAS,MAAM;AAC5B,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO,CAAC,CAAE,OAAe;MAC3B;AACA,UAAI,OAAO,YAAY,aAAa;AAClC,eAAO,CAAC,CAAE,QAAQ,IAAY,iBAAiB,CAAC,CAAE,QAAQ,IAAY;MACxE;AACA,aAAO;IACT,CAAC;AAED,UAAM,QAAQ;AAoBd,UAAM,YAAQ,uBAAS;AACvB,UAAM,EAAE,IAAI,iBAAiB,iBAAAC,kBAAiB,gBAAAC,iBAAgB,cAAAC,eAAc,cAAc,IACxF,UAAU;AAEZ,UAAM,aAAS,uBAAS,MAAM;AAC5B,UAAI,MAAM,IAAK,QAAO,MAAM;AAC5B,YAAM,cAAc,MAAM,UACtB,MACG,QAAQ,EACR,IAAI,CAAC,MAAM,EAAE,QAAQ,EACrB,KAAK,EAAE,IACV;AACJ,cAAQ,eAAe,IAAI,KAAK;IAClC,CAAC;AAGD,UAAM,kBAAc,kBAAI,CAAC;AACzB;MACE,CAACD,iBAAgBC,aAAY;MAC7B,MAAM;AAEJ,mCAAS,MAAM;AACb,sBAAY;QACd,CAAC;MACH;MACA,EAAE,MAAM,KAAK;IACf;AAEA,UAAM,iBAAa,uBAAS,MAAM;AAEhC,YAAM,iBAAiB,cAAc;AAGrC,YAAM,eAAe,MAAM,OAAO,eAAe;AACjD,YAAM,gBAAgB,MAAM,QAAQ,eAAe;AAMnD,UAAI,OAAO,SAAS,OAAO,WAAW,aAAa;AACjD,eAAO,gBAAgB,OAAO,OAAO,YAAY;MACnD;AAGA,WAAKF,iBAAgB;AACrB,WAAK,YAAY;AAEjB,YAAM,WAAW,GAAG,OAAO,KAAK,IAAI,YAAY;AAChD,YAAM,QAAQ,iBAAiB,OAAOC,kBAAiBC;AACvD,WAAK,MAAM,QAAQ;AAGnB,YAAM,SAAS,GAAG,OAAO,OAAO,cAAc,aAAa;AAC3D,aAAO;IACT,CAAC;;gDArGC,aAAAC,aAEa,aAAAC,YAAA;QAFD,MAAK;QAAO,MAAK;;2CAC3B,MAA+C;8CAA/C,aAAAC;YAA+C;YAAA,EAAxC,KAAK,WAAA,MAAU;gBAAA,aAAAC,iBAAK,WAAA,KAAU;YAAA;;UAAA;;;;;;;;;;ACEzC,IAAOC,cAAQ;AACf,WAAO,YAAY;","names":["InterfaceLanguageSelect_default","LanguageSelect_default","lt_default","import_vue","Fuse","_createElementBlock","_normalizeClass","_createCommentVNode","_createBlock","_unref","Multiselect","_withCtx","_createElementVNode","_toDisplayString","_Fragment","LanguageSelect_default","import_vue","import_vue","translations","message","import_vue","currentLanguage","availableLanguages","translations","uiTranslations","currentLanguage","LANGUAGES_CACHE_KEY","reactive","availableLanguages","currentLanguage","_createElementBlock","_hoisted_1","_createBlock","LanguageSelect_default","_createCommentVNode","_normalizeClass","_createElementVNode","_hoisted_2","_toDisplayString","_unref","InterfaceLanguageSelect_default","import_vue","currentLanguage","uiTranslations","translations","_createBlock","_Transition","_createElementBlock","_toDisplayString","lt_default"]}
1
+ {"version":3,"sources":["../../src/components/index.ts","/builds/codelits/langie-sdk/src/components/LanguageSelect.vue","#style-inject:#style-inject","../../src/styles/teleport.css","../../src/utils/lazyTransliterate.ts","../../src/language-aliases/european.ts","../../src/language-aliases/asian.ts","../../src/language-aliases/african.ts","../../src/language-aliases/index.ts","../../src/search-utils.ts","../../src/utils/displayNative.ts","../../src/utils/languageLabel.ts","../../src/utils/flagUrl.ts","../../src/constants/colors.ts","../../src/components/LanguageSelect.vue","/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue","../../src/useLangie.ts","../../src/constants.ts","../../src/core.ts","../../src/composables/useLangie-core.ts","../../src/utils/debug.ts","../../src/utils/getCountryCode.ts","../../src/utils/cache.ts","../../src/utils/localizeLanguageNames.ts","../../src/composables/useLangie-batching.ts","../../src/components/InterfaceLanguageSelect.vue","/builds/codelits/langie-sdk/src/components/lt.vue","../../src/components/lt.vue"],"sourcesContent":["export { default as LanguageSelect } from './LanguageSelect.vue'\nexport { default as InterfaceLanguageSelect } from './InterfaceLanguageSelect.vue'\nexport { default as lt } from './lt.vue'\n\nexport * from './types'\n","<template>\n <div class=\"language-select\" :class=\"{ 'is-dark': isDark }\">\n <!-- Show multiselect when we have languages OR when not loading -->\n <Multiselect\n v-if=\"validLanguages.length > 0 || !isLoading\"\n ref=\"multiselectRef\"\n :key=\"multiselectKey\"\n v-model=\"selectedLanguage\"\n :options=\"filteredLanguages\"\n :searchable=\"true\"\n @search-change=\"handleSearch\"\n :can-clear=\"false\"\n :allow-empty=\"false\"\n :object=\"true\"\n :placeholder=\"validLanguages.length === 0 ? 'No languages available' : placeholder\"\n :disabled=\"props.disabled || validLanguages.length === 0\"\n :loading=\"isLoading\"\n track-by=\"code\"\n label=\"name\"\n value-prop=\"code\"\n :filter-results=\"false\"\n :id=\"multiselectId\"\n :aria=\"COMBOBOX_ARIA\"\n :attrs=\"searchInputAttrs\"\n @keydown=\"handleKeydown\"\n >\n <template #singlelabel=\"{ value }\">\n <div v-if=\"value\" class=\"multiselect-single-label\">\n <img\n v-if=\"value.code\"\n :key=\"selectedLanguageKey\"\n :src=\"getFlagImageUrl(value)\"\n class=\"lang-flag\"\n :alt=\"`${languageLabel(value).primary} flag`\"\n :data-custom-flag=\"isReadyFlagUrl(getFlagCode(value)) || undefined\"\n @error=\"onFlagError\"\n />\n <span class=\"language-text\"\n >{{ languageLabel(value).primary }}\n <span v-if=\"languageLabel(value).native\" class=\"native-name\"\n >({{ languageLabel(value).native }})</span\n ></span\n >\n </div>\n </template>\n <template #option=\"{ option }\">\n <div class=\"multiselect-option\" :data-lang-code=\"option.code\">\n <img\n :key=\"`${option.code}-${option.flag_country || 'fallback'}`\"\n :src=\"getFlagImageUrl(option)\"\n class=\"lang-flag\"\n :alt=\"`${languageLabel(option).primary} flag`\"\n :data-custom-flag=\"isReadyFlagUrl(getFlagCode(option)) || undefined\"\n @error=\"onFlagError\"\n />\n <span class=\"language-text\"\n >{{ languageLabel(option).primary }}\n <span v-if=\"languageLabel(option).native\" class=\"native-name\"\n >({{ languageLabel(option).native }})</span\n ></span\n >\n </div>\n </template>\n <template #noresults>\n <div class=\"multiselect-no-results\">No languages found.</div>\n </template>\n <template #nooptions>\n <div class=\"multiselect-no-options\">\n {{\n validLanguages.length === 0\n ? 'Please provide languages via the :languages prop'\n : 'No languages available.'\n }}\n </div>\n </template>\n </Multiselect>\n <!-- Only show skeleton loader when actually loading AND we have no languages yet -->\n <div v-else-if=\"isLoading && validLanguages.length === 0\" class=\"skeleton-loader\"></div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport '@vueform/multiselect/themes/default.css'\nimport '../styles/teleport.css'\nimport { ref, shallowRef, computed, nextTick, useId } from 'vue'\nimport type { PropType } from 'vue'\nimport Multiselect from '@vueform/multiselect'\nimport Fuse from 'fuse.js'\nimport type { FuseResult } from 'fuse.js'\nimport { loadTransliterate } from '../utils/lazyTransliterate'\nimport type { Transliterate } from '../utils/lazyTransliterate'\nimport { applyLanguageAlias } from '../search-utils'\nimport { languageLabel } from '../utils/languageLabel'\nimport { flagImageUrl, isReadyFlagUrl } from '../utils/flagUrl'\nimport { THEME_COLORS, COLORS } from '../constants/colors'\nimport type { TranslatorLanguage } from '../types'\n\n// role=\"combobox\" supports neither aria-multiselectable nor aria-placeholder (see\n// axe-core's role table), but @vueform/multiselect emits both on the search input.\n// The `aria` prop is merged last, so an undefined value drops the attribute instead\n// of shipping invalid ARIA. The placeholder comes back as a native one below, which\n// screen readers announce and validators accept.\nconst COMBOBOX_ARIA = { 'aria-multiselectable': undefined, 'aria-placeholder': undefined }\n\n// Without an id, vueform hardcodes `multiselect-options` on the listbox and\n// `assist` on its description, so two pickers on one page (source + target) hand\n// assistive tech duplicate ids and the wrong `aria-controls` target. useId is\n// SSR-safe — a module counter would drift between the server process and the\n// client and break hydration.\nconst multiselectId = useId()\n\nconst getFlagCode = (lang: TranslatorLanguage): string => {\n const flagCode = lang.flag_country || lang.code\n return flagCode\n}\n\n// Local flags are downloaded during build for offline support and faster\n// loading; on a miss the onerror handler falls back to the CDN.\nconst getFlagImageUrl = (lang: TranslatorLanguage): string => flagImageUrl(getFlagCode(lang))\n\nconst props = defineProps({\n modelValue: {\n type: Object as PropType<TranslatorLanguage | null | undefined>,\n default: undefined\n },\n languages: {\n type: Array as PropType<TranslatorLanguage[]>,\n default: () => []\n },\n placeholder: {\n type: String,\n default: 'Select language'\n },\n disabled: {\n type: Boolean,\n default: false\n },\n isDark: {\n type: Boolean,\n default: false\n }\n})\n\nconst emit = defineEmits(['update:modelValue'])\n\nconst multiselectRef = ref<{ setPointerFirst?: () => void } | null>(null)\n\nconst isLoading = computed(() => {\n return props.languages.length <= 0\n})\nconst searchQuery = ref('')\nconst transliterate = shallowRef<Transliterate | null>(null)\n\nconst searchInputAttrs = computed(() => ({ placeholder: props.placeholder }))\n\nconst validLanguages = computed(() => {\n return props.languages.filter((lang) => lang && lang.code && lang.name && lang.native_name)\n})\n\nconst fuse = computed(() => {\n if (!validLanguages.value.length) return null\n\n return new Fuse(validLanguages.value, {\n keys: ['name', 'native_name', 'search_alias', 'code'],\n includeScore: true,\n threshold: 0.4, // Trim fuzzy noise; short abbreviations (e.g. \"сша\") no longer rank below it\n ignoreLocation: true, // Match anywhere in the field, not just near position 0\n isCaseSensitive: false,\n minMatchCharLength: 1 // Allow single character matches\n })\n})\n\nconst multiselectKey = computed(() => {\n // Create a key that changes when the language data structure changes\n const hasApiData = props.languages.length > 0 && props.languages[0].flag_country !== null\n return hasApiData ? 'api-data' : 'fallback-data'\n})\n\nconst selectedLanguageKey = computed(() => {\n if (!props.modelValue || !props.modelValue.code) return 'no-selection'\n const key = `${props.modelValue.code}-${props.modelValue.flag_country || 'fallback'}`\n return key\n})\n\nconst selectedLanguage = computed({\n get: () => props.modelValue || null,\n set: (value) => {\n if (value && value.code) {\n emit('update:modelValue', value)\n }\n }\n})\n\nconst filteredLanguages = computed(() => {\n const query = searchQuery.value.trim()\n\n let results: TranslatorLanguage[]\n if (!query) {\n // When no search query, return all valid languages (bypass Fuse.js)\n results = validLanguages.value\n } else {\n // Only use Fuse.js when there's an actual search query\n if (!fuse.value) return []\n\n // Get the most likely alias or the original term\n const aliasResult = applyLanguageAlias(query)\n const searchTerm = Array.isArray(aliasResult.primary)\n ? aliasResult.primary[0]\n : aliasResult.primary\n\n // Merge Fuse hits into `results`, skipping languages already present.\n const mergeByCode = (hits: FuseResult<TranslatorLanguage>[]) => {\n hits.forEach((hit) => {\n if (!results.some((r) => r.code === hit.item.code)) results.push(hit.item)\n })\n }\n\n // Always use Fuse.js for the main search (both original query and alias result)\n results = fuse.value.search(searchTerm).map((result) => result.item)\n\n // If the search term is different from query (alias was applied), also search the original query\n if (searchTerm !== query) {\n mergeByCode(fuse.value.search(query))\n }\n\n // Transliterate the query to Latin so a foreign-script keyboard still matches the\n // Latin `name`/`native_name` when no localized `search_alias` exists (e.g. English\n // interface). Helps cognates: Cyrillic \"браз\" → \"braz\" → Brazilian.\n const latinQuery = transliterate.value ? transliterate.value(query) : ''\n if (latinQuery && latinQuery.toLowerCase() !== query.toLowerCase()) {\n mergeByCode(fuse.value.search(latinQuery))\n }\n\n // Add suggested languages to expand the results\n if (aliasResult.suggestions.length > 0) {\n aliasResult.suggestions.forEach((suggestion) => {\n const suggestedLang = validLanguages.value.find((lang) => {\n const langName = lang.name.toLowerCase()\n const suggestion_lower = suggestion.toLowerCase()\n\n // Try multiple matching strategies\n return (\n langName === suggestion_lower || // Exact match\n langName.includes(suggestion_lower) || // Contains match\n lang.code.toLowerCase() === suggestion_lower || // Code match\n langName.startsWith(suggestion_lower) || // Starts with match\n // Handle common variations\n (suggestion_lower === 'tatar' && langName.includes('tatar')) ||\n (suggestion_lower === 'belarusian' &&\n (langName.includes('belarus') || langName.includes('belarusian'))) ||\n (suggestion_lower === 'moldovan' &&\n (langName.includes('moldov') || langName.includes('moldova')))\n )\n })\n if (suggestedLang && !results.some((r) => r.code === suggestedLang.code)) {\n results.push(suggestedLang)\n }\n })\n }\n\n // Special handling for very short queries (e.g. \"се\")\n if (query.length === 2) {\n const lowerQuery = query.toLowerCase()\n const manualResults = validLanguages.value.filter(\n (lang) =>\n lang.name.toLowerCase().startsWith(lowerQuery) ||\n lang.native_name.toLowerCase().startsWith(lowerQuery)\n )\n manualResults.forEach((lang) => {\n if (!results.some((r) => r.code === lang.code)) {\n results.push(lang)\n }\n })\n }\n }\n\n // Remove the currently selected language from the options\n const filtered = results.filter(\n (lang) => !props.modelValue || !props.modelValue.code || lang.code !== props.modelValue.code\n )\n\n return filtered\n})\n\nfunction handleSearch(query: string) {\n searchQuery.value = query\n if (!query.trim()) return\n\n // Typing is the first moment the charmap can matter; the results recompute on\n // their own once the ref lands, so the first keystrokes stay Latin-only.\n if (!transliterate.value) {\n void loadTransliterate().then((fn) => {\n transliterate.value = fn\n })\n }\n\n // We feed our own fuzzy-filtered list (`filter-results=false`), so vueform's search\n // watcher runs setPointerFirst against the OLD options before our list re-renders —\n // leaving a STALE internal pointer that Enter/arrows then act on (random selection).\n // Re-point to the first option once the fresh list has rendered, and reset the scroll\n // so the best match is at the top. This drives vueform's real pointer (which owns the\n // `is-pointed` highlight and keyboard selection), not just the visual class.\n nextTick(() => {\n multiselectRef.value?.setPointerFirst?.()\n const dropdown = document.querySelector('.multiselect-dropdown')\n if (dropdown) dropdown.scrollTop = 0\n })\n}\n\n// Enter/Tab selects the currently highlighted option. `data-lang-code` lives on our inner\n// slot div, not vueform's outer `.multiselect-option` wrapper — read it from the pointed\n// row (falling back to the first) so selection matches what the user sees highlighted.\nfunction handleKeydown(event: Event) {\n const keyboardEvent = event as KeyboardEvent\n if (keyboardEvent.key !== 'Tab' && keyboardEvent.key !== 'Enter') return\n if (!searchQuery.value.trim()) return\n\n const dropdown = document.querySelector('.multiselect-dropdown')\n const pointed =\n dropdown?.querySelector('.multiselect-option.is-pointed [data-lang-code]') ||\n dropdown?.querySelector('.multiselect-option [data-lang-code]')\n const langCode = pointed?.getAttribute('data-lang-code')\n if (!langCode) return\n\n const language = validLanguages.value.find((lang) => lang.code === langCode)\n if (language) {\n selectedLanguage.value = language\n searchQuery.value = ''\n keyboardEvent.preventDefault()\n }\n}\n\nconst onFlagError = (event: Event) => {\n const target = event.target as HTMLImageElement\n const currentSrc = target.src\n\n // A custom flag is final: its slug is a language code, so the CDN fallback\n // below would silently serve an unrelated country — \"cv\" is Chuvash to us\n // and Cape Verde to flagcdn, \"ba\" Bashkir and Bosnia. Wrong flag beats no\n // flag only if you never look at it. Hide instead.\n if (target.dataset.customFlag) {\n target.style.display = 'none'\n return\n }\n\n // If loading from local cache failed, try CDN\n if (currentSrc && currentSrc.includes('/flags/')) {\n const match = currentSrc.match(/\\/flags\\/([a-z]{2})\\.svg/)\n if (match) {\n const countryCode = match[1]\n // Fallback to CDN\n target.src = `https://flagcdn.com/${countryCode}.svg`\n // If CDN also fails, hide the image\n target.onerror = () => {\n target.style.display = 'none'\n }\n return\n }\n }\n\n // If CDN or any other source fails, hide the image\n target.style.display = 'none'\n}\n</script>\n\n<style scoped>\n.language-select {\n position: relative;\n min-height: 40px; /* To prevent layout shift while loading */\n}\n\n.skeleton-loader {\n width: 100%;\n height: 40px;\n background-color: #e2e8f0;\n border-radius: 4px;\n animation: pulse 1.5s infinite ease-in-out;\n}\n\n.is-dark .skeleton-loader {\n background-color: #374151;\n}\n\n@keyframes pulse {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n\n:deep(.multiselect) {\n --ms-font-size: 1rem;\n --ms-line-height: 1.5;\n --ms-bg: v-bind('THEME_COLORS.light.background');\n --ms-bg-disabled: v-bind('THEME_COLORS.light.backgroundDisabled');\n --ms-border-color: v-bind('THEME_COLORS.light.border');\n --ms-border-width: 1px;\n --ms-radius: 4px;\n --ms-py: 0.3rem;\n --ms-px: 0.875rem;\n --ms-ring-width: 3px;\n --ms-ring-color: v-bind('THEME_COLORS.light.ring');\n --ms-placeholder-color: v-bind('THEME_COLORS.light.placeholder');\n --ms-color: #1f2937; /* Explicit text color for light theme */\n\n /* Options */\n --ms-option-font-size: 1rem;\n --ms-option-line-height: 1;\n --ms-option-py: 0.2rem;\n --ms-option-px: 0.5rem;\n --ms-option-bg-pointed: v-bind('THEME_COLORS.light.optionPointed');\n --ms-option-color-pointed: v-bind('THEME_COLORS.light.optionPointedText');\n --ms-option-bg-selected: v-bind('THEME_COLORS.light.optionSelected');\n --ms-option-color-selected: v-bind('THEME_COLORS.light.optionSelectedText');\n --ms-option-bg-disabled: #fff;\n --ms-option-color-disabled: #d1d5db;\n\n /* Dropdown */\n --ms-dropdown-bg: v-bind('THEME_COLORS.light.dropdownBackground');\n --ms-dropdown-border-color: v-bind('THEME_COLORS.light.dropdownBorder');\n --ms-dropdown-color: v-bind('THEME_COLORS.light.dropdownText');\n\n /* Others */\n --ms-tag-bg: v-bind('THEME_COLORS.light.tagBackground');\n}\n\n.is-dark :deep(.multiselect) {\n --ms-bg: v-bind('THEME_COLORS.dark.background');\n --ms-bg-disabled: v-bind('THEME_COLORS.dark.backgroundDisabled');\n --ms-border-color: v-bind('THEME_COLORS.dark.border');\n --ms-placeholder-color: v-bind('THEME_COLORS.dark.placeholder');\n --ms-ring-color: v-bind('THEME_COLORS.dark.ring');\n --ms-color: v-bind('THEME_COLORS.dark.dropdownText'); /* typed search text; base is dark #1f2937 → invisible on dark bg */\n\n /* Options */\n --ms-option-bg-pointed: v-bind('THEME_COLORS.dark.optionPointed');\n --ms-option-color-pointed: v-bind('THEME_COLORS.dark.optionPointedText');\n --ms-option-bg-selected: v-bind('THEME_COLORS.dark.optionSelected');\n --ms-option-color-selected: v-bind('THEME_COLORS.dark.optionSelectedText');\n\n /* Dropdown */\n --ms-dropdown-bg: v-bind('THEME_COLORS.dark.dropdownBackground');\n --ms-dropdown-border-color: v-bind('THEME_COLORS.dark.dropdownBorder');\n --ms-dropdown-color: v-bind('THEME_COLORS.dark.dropdownText');\n}\n\n:deep(.lang-flag) {\n width: 20px;\n height: 15px;\n border: 1px solid v-bind('COLORS.border.flag');\n border-radius: 2px;\n object-fit: cover;\n flex-shrink: 0;\n display: block;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.is-dark :deep(.lang-flag) {\n border-color: v-bind('COLORS.border.dark');\n}\n\n:deep(.multiselect-single-label),\n:deep(.multiselect-option) {\n display: flex !important;\n align-items: center !important;\n min-width: 0 !important;\n width: 100% !important;\n padding: 4px 8px !important;\n gap: 8px !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n flex-wrap: nowrap !important;\n}\n\n:deep(.multiselect-option) {\n text-align: left !important;\n transition: background-color 0.15s ease !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n flex-wrap: nowrap !important;\n}\n\n:deep(.language-text) {\n display: inline-block !important;\n min-width: 0 !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n flex: 1 !important;\n line-height: 1.4 !important;\n color: v-bind('THEME_COLORS.light.dropdownText') !important;\n word-break: keep-all !important;\n word-wrap: normal !important;\n word-spacing: normal !important;\n max-width: 100% !important;\n}\n\n.is-dark :deep(.language-text) {\n color: v-bind('THEME_COLORS.dark.dropdownText') !important;\n}\n\n:deep(.native-name) {\n color: v-bind('COLORS.text.secondary');\n margin-left: 0.5rem;\n font-size: 0.9em;\n white-space: nowrap !important;\n display: inline !important;\n}\n\n.is-dark :deep(.native-name) {\n color: v-bind('COLORS.neutral.gray400');\n}\n\n:deep(.multiselect) {\n width: 100%;\n min-width: 200px;\n color: v-bind('THEME_COLORS.light.dropdownText');\n position: relative;\n z-index: 1;\n}\n\n.is-dark :deep(.multiselect) {\n color: v-bind('THEME_COLORS.dark.dropdownText');\n}\n\n/* Lift the open select above sibling selects (each is its own z-index:1 stacking context) */\n:deep(.multiselect.is-active) {\n z-index: 2;\n}\n\n:deep(.multiselect-dropdown) {\n padding: 2px 0 !important;\n z-index: 1000 !important;\n}\n\n:deep(.multiselect-dropdown .multiselect-option) {\n padding: 4px 8px !important;\n margin: 0 !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n flex-wrap: nowrap !important;\n}\n\n:deep(.multiselect-dropdown .language-text) {\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n word-break: keep-all !important;\n word-wrap: normal !important;\n word-spacing: normal !important;\n max-width: 100% !important;\n}\n\n:deep(.multiselect-no-results),\n:deep(.multiselect-no-options) {\n padding: 0.5rem 0.875rem;\n color: v-bind('COLORS.text.secondary');\n}\n\n.is-dark :deep(.multiselect-no-results),\n.is-dark :deep(.multiselect-no-options) {\n color: v-bind('COLORS.neutral.gray400');\n}\n</style>\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".multiselect-single-label,\\n.multiselect-option {\\n display: flex;\\n align-items: center;\\n}\\n.lang-flag {\\n width: 20px;\\n height: 15px;\\n margin-right: 10px;\\n border: 1px solid var(--langie-flag-border, #eee);\\n border-radius: 2px;\\n object-fit: cover;\\n}\\n.is-dark .lang-flag {\\n border-color: var(--langie-flag-border-dark, #4b5563);\\n}\\n.native-name {\\n color: var(--langie-text-secondary, #6b7280);\\n margin-left: 0.5rem;\\n font-size: 0.9em;\\n}\\n.is-dark .native-name {\\n color: var(--langie-text-secondary-dark, #9ca3af);\\n}\\n.multiselect-no-results,\\n.multiselect-no-options {\\n padding: 0.5rem 0.875rem;\\n color: var(--langie-text-secondary, #6b7280);\\n}\\n.is-dark .multiselect-no-results,\\n.is-dark .multiselect-no-options {\\n color: var(--langie-text-secondary-dark, #9ca3af);\\n}\\n\")","export type Transliterate = (input: string) => string\n\nlet pending: Promise<Transliterate> | null = null\n\n/**\n * `transliteration` ships a ~200 KB charmap — a third of a consumer's entry\n * chunk — but it is only needed once somebody types a non-Latin query, so it is\n * pulled on demand instead of at import time. The promise is cached, so the\n * charmap is fetched once per session no matter how many pickers ask for it.\n */\nexport function loadTransliterate(): Promise<Transliterate> {\n if (!pending) {\n pending = import('transliteration').then((m) => m.transliterate)\n }\n return pending\n}\n","import type { AliasEntry } from './types'\n\nexport const EUROPEAN_LANGUAGES: AliasEntry[] = [\n // Major European Languages\n {\n lang: 'english',\n match: [\n 'eng',\n 'en',\n 'английский',\n 'англ',\n 'united states',\n 'united states of america',\n 'usa',\n 'us',\n 'great britain',\n 'britain',\n 'british',\n 'england',\n 'united kingdom',\n 'uk'\n ],\n suggest: ['irish', 'scottish', 'welsh']\n },\n // English variants: country name / abbreviation → the specific variant CODE.\n // `lang` here is a variant code (not a language name) so Fuse matches it against\n // the `code` key and ranks that exact variant first (e.g. \"сша\" → en-US #1).\n // Latin \"usa\"/\"us\" stay on the `english` entry above (surface the whole group);\n // these cover the Cyrillic exonyms the translated names never contain.\n {\n lang: 'en-us',\n match: ['сша', 'штаты', 'америка', 'соединённые штаты', 'соединенные штаты'],\n suggest: []\n },\n {\n lang: 'en-au',\n match: ['австралия'],\n suggest: []\n },\n {\n lang: 'en-ca',\n match: ['канада'],\n suggest: []\n },\n {\n lang: 'en-ie',\n match: ['ирландия'],\n suggest: []\n },\n {\n lang: 'spanish',\n match: [\n 'spa',\n 'es',\n 'esp',\n 'spain',\n 'español',\n 'mexico',\n 'mexican',\n 'argentina',\n 'colombia',\n 'venezuela'\n ],\n suggest: ['catalan', 'galician', 'basque']\n },\n {\n lang: 'french',\n match: [\n 'fra',\n 'fr',\n 'fre',\n 'france',\n 'français',\n 'canada',\n 'canadian',\n 'quebec',\n 'belgium',\n 'swiss'\n ],\n suggest: ['occitan', 'breton', 'corsican']\n },\n {\n lang: 'german',\n match: [\n 'ger',\n 'de',\n 'deu',\n 'germany',\n 'deutsch',\n 'austria',\n 'austrian',\n 'switzerland',\n 'swiss'\n ],\n suggest: ['bavarian', 'saxon', 'luxembourgish']\n },\n {\n lang: 'italian',\n match: ['ita', 'it', 'italy', 'italiano', 'swiss italian'],\n suggest: ['sardinian', 'neapolitan', 'venetian']\n },\n {\n lang: 'portuguese',\n match: ['por', 'pt', 'portugal', 'brazil', 'brazilian', 'braz', 'mozambique', 'angola'],\n suggest: ['galician', 'mirandese']\n },\n {\n lang: 'dutch',\n match: ['dut', 'nl', 'nld', 'netherlands', 'holland', 'flemish', 'belgium'],\n suggest: ['frisian', 'afrikaans']\n },\n\n // Slavic Languages\n {\n lang: 'russian',\n match: ['rus', 'ru', 'russia', 'belarus'],\n suggest: ['kazakh', 'tatar', 'belarusian', 'tajik', 'uzbek', 'moldovan']\n },\n {\n lang: 'ukrainian',\n match: ['ukr', 'uk', 'ukraine'],\n suggest: ['russian', 'belarusian']\n },\n {\n lang: 'polish',\n match: ['pol', 'pl', 'poland'],\n suggest: ['silesian', 'kashubian']\n },\n {\n lang: 'czech',\n match: ['ces', 'cs', 'cze', 'czech republic', 'czechia'],\n suggest: ['slovak', 'moravian']\n },\n {\n lang: 'slovak',\n match: ['slk', 'sk', 'slovakia'],\n suggest: ['czech', 'rusyn']\n },\n {\n lang: 'croatian',\n match: ['hrv', 'hr', 'croatia'],\n suggest: ['serbian', 'bosnian', 'montenegrin']\n },\n {\n lang: 'serbian',\n match: [\n 'srp',\n 'sr',\n 'ser',\n 'serbia',\n 'serbian',\n 'srpski',\n 'србија',\n 'српски',\n 'серб',\n 'сербский',\n 'сербс'\n ],\n suggest: ['croatian', 'bosnian', 'montenegrin']\n },\n {\n lang: 'bulgarian',\n match: ['bul', 'bg', 'bulgaria'],\n suggest: ['macedonian']\n },\n {\n lang: 'slovenian',\n match: ['slv', 'sl', 'slovenia'],\n suggest: ['croatian']\n },\n\n // Nordic Languages\n {\n lang: 'swedish',\n match: ['swe', 'sv', 'sweden'],\n suggest: ['norwegian', 'danish', 'finnish']\n },\n {\n lang: 'norwegian',\n match: ['nor', 'no', 'norway'],\n suggest: ['swedish', 'danish']\n },\n {\n lang: 'danish',\n match: ['dan', 'da', 'denmark'],\n suggest: ['norwegian', 'swedish']\n },\n {\n lang: 'finnish',\n match: ['fin', 'fi', 'finland'],\n suggest: ['estonian', 'swedish']\n },\n {\n lang: 'icelandic',\n match: ['isl', 'is', 'iceland'],\n suggest: ['faroese', 'norwegian']\n },\n\n // Other European Languages\n {\n lang: 'greek',\n match: ['ell', 'el', 'gre', 'greece', 'hellenic'],\n suggest: ['macedonian', 'albanian']\n },\n {\n lang: 'romanian',\n match: ['ron', 'ro', 'rum', 'romania'],\n suggest: ['moldovan', 'hungarian']\n },\n {\n lang: 'hungarian',\n match: ['hun', 'hu', 'hungary', 'magyar'],\n suggest: ['romanian', 'slovak']\n },\n {\n lang: 'albanian',\n match: ['sqi', 'sq', 'alb', 'albania', 'kosovo'],\n suggest: ['greek', 'macedonian']\n },\n {\n lang: 'lithuanian',\n match: ['lit', 'lt', 'lithuania'],\n suggest: ['latvian', 'polish']\n },\n {\n lang: 'latvian',\n match: ['lav', 'lv', 'latvia'],\n suggest: ['lithuanian', 'estonian']\n },\n {\n lang: 'estonian',\n match: ['est', 'et', 'estonia'],\n suggest: ['finnish', 'latvian']\n },\n\n // Celtic Languages\n {\n lang: 'irish',\n match: ['gle', 'ga', 'ireland', 'gaelic'],\n suggest: ['scottish', 'welsh']\n },\n {\n lang: 'welsh',\n match: ['cym', 'cy', 'wales', 'cymru'],\n suggest: ['irish', 'cornish']\n },\n {\n lang: 'scottish',\n match: ['gla', 'gd', 'scotland', 'scots gaelic'],\n suggest: ['irish', 'english']\n },\n\n // Additional Languages\n {\n lang: 'esperanto',\n match: ['epo', 'eo', 'esperanto'],\n suggest: []\n },\n {\n lang: 'latin',\n match: ['lat', 'la', 'latin'],\n suggest: ['italian', 'spanish', 'french']\n }\n]\n","import type { AliasEntry } from './types'\n\nexport const ASIAN_LANGUAGES: AliasEntry[] = [\n // Asian Languages\n {\n lang: 'chinese',\n match: [\n 'chi',\n 'zh',\n 'zho',\n 'zh-cn',\n 'cn',\n 'china',\n 'mandarin',\n 'zhongwen',\n 'simplified',\n 'traditional'\n ],\n suggest: ['cantonese', 'taiwanese', 'hakka']\n },\n {\n lang: 'japanese',\n match: ['jpn', 'ja', 'jp', 'japan', 'nihongo'],\n suggest: ['okinawan']\n },\n {\n lang: 'korean',\n match: ['kor', 'ko', 'kr', 'korea', 'hangul', 'south korea', 'north korea'],\n suggest: ['jeju']\n },\n {\n lang: 'hindi',\n match: ['hin', 'hi', 'india', 'indian', 'devanagari'],\n suggest: ['urdu', 'punjabi', 'gujarati', 'marathi', 'bengali']\n },\n {\n lang: 'arabic',\n match: ['ara', 'ar', 'arab', 'saudi', 'egypt', 'egyptian', 'gulf', 'levantine', 'maghreb'],\n suggest: ['persian', 'hebrew', 'urdu']\n },\n {\n lang: 'thai',\n match: ['tha', 'th', 'thailand', 'siam'],\n suggest: ['lao', 'khmer']\n },\n {\n lang: 'vietnamese',\n match: ['vie', 'vi', 'vietnam'],\n suggest: ['khmer', 'lao']\n },\n {\n lang: 'indonesian',\n match: ['ind', 'id', 'indonesia', 'bahasa'],\n suggest: ['malay', 'javanese', 'sundanese']\n },\n {\n lang: 'malay',\n match: ['msa', 'ms', 'malaysia', 'brunei'],\n suggest: ['indonesian']\n },\n\n // Central Asian & Turkic Languages\n {\n lang: 'kazakh',\n match: ['kaz', 'kk', 'kazlat', 'kazakh', 'kazakhstan', 'казах', 'казахский', 'казахс'],\n suggest: ['russian', 'kyrgyz', 'uzbek']\n },\n {\n lang: 'turkish',\n match: ['tur', 'tr', 'turkey'],\n suggest: ['kurdish', 'azerbaijani']\n },\n {\n lang: 'uzbek',\n match: ['uzb', 'uz', 'uzbekistan'],\n suggest: ['tajik', 'kazakh', 'kyrgyz']\n },\n {\n lang: 'kyrgyz',\n match: ['kir', 'ky', 'kyrgyzstan'],\n suggest: ['kazakh', 'uzbek']\n },\n {\n lang: 'tajik',\n match: ['tgk', 'tg', 'tajikistan'],\n suggest: ['persian', 'uzbek']\n },\n {\n lang: 'azerbaijani',\n match: ['aze', 'az', 'azerbaijan'],\n suggest: ['turkish', 'persian']\n },\n\n // Middle Eastern Languages\n {\n lang: 'persian',\n match: ['fas', 'fa', 'per', 'iran', 'farsi', 'dari', 'afghanistan'],\n suggest: ['tajik', 'kurdish', 'pashto']\n },\n {\n lang: 'hebrew',\n match: ['heb', 'he', 'israel', 'israeli'],\n suggest: ['arabic', 'yiddish']\n },\n {\n lang: 'kurdish',\n match: ['kur', 'ku', 'kurdistan', 'kurmanji', 'sorani'],\n suggest: ['turkish', 'persian', 'arabic']\n },\n\n // South Asian Languages\n {\n lang: 'urdu',\n match: ['urd', 'ur', 'pakistan', 'pakistani'],\n suggest: ['hindi', 'punjabi']\n },\n {\n lang: 'bengali',\n match: ['ben', 'bn', 'bangladesh', 'bengal'],\n suggest: ['hindi', 'assamese']\n },\n {\n lang: 'punjabi',\n match: ['pan', 'pa', 'punjab'],\n suggest: ['hindi', 'urdu']\n },\n {\n lang: 'gujarati',\n match: ['guj', 'gu', 'gujarat'],\n suggest: ['hindi', 'marathi']\n },\n {\n lang: 'marathi',\n match: ['mar', 'mr', 'maharashtra'],\n suggest: ['hindi', 'gujarati']\n },\n {\n lang: 'tamil',\n match: ['tam', 'ta', 'tamil nadu', 'sri lanka'],\n suggest: ['malayalam', 'telugu', 'kannada']\n },\n {\n lang: 'telugu',\n match: ['tel', 'te', 'andhra pradesh'],\n suggest: ['tamil', 'kannada']\n },\n {\n lang: 'kannada',\n match: ['kan', 'kn', 'karnataka'],\n suggest: ['tamil', 'telugu', 'malayalam']\n },\n {\n lang: 'malayalam',\n match: ['mal', 'ml', 'kerala'],\n suggest: ['tamil', 'kannada']\n },\n {\n lang: 'nepali',\n match: ['nep', 'ne', 'nepal'],\n suggest: ['hindi']\n },\n {\n lang: 'sinhala',\n match: ['sin', 'si', 'sri lanka', 'ceylon'],\n suggest: ['tamil']\n },\n\n // Southeast Asian Languages\n {\n lang: 'burmese',\n match: ['mya', 'my', 'myanmar', 'burma'],\n suggest: ['thai']\n },\n {\n lang: 'khmer',\n match: ['khm', 'km', 'cambodia', 'cambodian'],\n suggest: ['vietnamese', 'thai']\n },\n {\n lang: 'lao',\n match: ['lao', 'lo', 'laos'],\n suggest: ['thai', 'vietnamese']\n },\n {\n lang: 'tagalog',\n match: ['tgl', 'tl', 'philippines', 'filipino'],\n suggest: ['cebuano', 'ilocano']\n }\n]\n","import type { AliasEntry } from './types'\n\nexport const AFRICAN_LANGUAGES: AliasEntry[] = [\n // African Languages\n {\n lang: 'swahili',\n match: ['swa', 'sw', 'kiswahili', 'tanzania', 'kenya'],\n suggest: ['arabic']\n },\n {\n lang: 'amharic',\n match: ['amh', 'am', 'ethiopia', 'ethiopian'],\n suggest: ['tigrinya', 'oromo']\n },\n {\n lang: 'yoruba',\n match: ['yor', 'yo', 'nigeria', 'benin'],\n suggest: ['igbo', 'hausa']\n },\n {\n lang: 'zulu',\n match: ['zul', 'zu', 'south africa'],\n suggest: ['xhosa', 'afrikaans']\n }\n]\n","import type { AliasEntry } from './types'\nimport { EUROPEAN_LANGUAGES } from './european'\nimport { ASIAN_LANGUAGES } from './asian'\nimport { AFRICAN_LANGUAGES } from './african'\n\nexport const LANGUAGE_ALIAS_TABLE: AliasEntry[] = [\n ...EUROPEAN_LANGUAGES,\n ...ASIAN_LANGUAGES,\n ...AFRICAN_LANGUAGES\n]\n\nexport type { AliasEntry }\n","// Map various common synonyms, country names, and demonyms to a canonical\n// language label. The canonical label must match the `name` field found in the\n// languages list returned by the backend (e.g. \"English\", \"French\", ...).\n\nimport { LANGUAGE_ALIAS_TABLE } from './language-aliases'\n\nexport function applyLanguageAlias(term = ''): {\n primary: string | string[]\n suggestions: string[]\n} {\n const s = term.toLowerCase().trim()\n if (!s) return { primary: term, suggestions: [] }\n\n // Helper decides whether a candidate alias matches the typed search string\n const isMatch = (alias: string, input: string): boolean => {\n if (input === alias) return true // exact match\n // Input fully contains the alias (and alias has 3+ chars) → e.g., \"germ\" vs \"german\"\n if (alias.length >= 3 && input.length >= alias.length && input.startsWith(alias)) return true\n // Alias contains the input (user typed prefix, at least 2 chars) → e.g., \"ge\" → \"german\"\n if (input.length >= 2 && alias.startsWith(input)) return true\n return false\n }\n\n const hits = new Set<string>()\n const suggestions = new Set<string>()\n\n for (const { lang, match, suggest } of LANGUAGE_ALIAS_TABLE) {\n // Check primary matches\n for (const m of match) {\n if (isMatch(m, s)) {\n hits.add(lang)\n // If this language has suggestions, add them\n if (suggest) {\n suggest.forEach((sug: string) => suggestions.add(sug))\n }\n }\n }\n }\n\n let primary: string | string[]\n if (hits.size === 0) {\n primary = term\n } else if (hits.size === 1) {\n primary = Array.from(hits)[0]\n } else {\n primary = Array.from(hits)\n }\n\n return { primary, suggestions: Array.from(suggestions) }\n}\n","// Matches a trailing parenthetical (ASCII or fullwidth) plus surrounding space:\n// \"Português (Brasil)\" -> the \" (Brasil)\" tail. Inner text must not contain\n// parens so nested groups don't over-match.\nconst TRAILING_PAREN = /\\s*[((][^()()]*[))]\\s*$/\n\n/**\n * Native-name label for a language option.\n *\n * When BOTH `name` and `native_name` carry a trailing region parenthetical\n * (regional variants like pt-BR: \"Portuguese (Brazil)\" / \"Português (Brasil)\"),\n * the region would read twice, so the native's tail is dropped. When only the\n * native has one (e.g. \"Chinese (Simplified)\" / \"中文\") it is kept. Exact\n * duplicates return unchanged (the caller already guards on `name !== native`).\n */\nexport function displayNative(name = '', native = ''): string {\n return name !== native && TRAILING_PAREN.test(name) && TRAILING_PAREN.test(native)\n ? native.replace(TRAILING_PAREN, '')\n : native\n}\n","import type { TranslatorLanguage } from '../types'\nimport { displayNative } from './displayNative'\n\n/**\n * Label parts for a language option: the name in the interface language when we\n * have it (`search_alias`, filled by localizeLanguageNames), else the English\n * `name`, plus the native name to show in parentheses.\n *\n * `native` comes back empty when it would only repeat the primary — with a\n * Russian interface, Russian reads \"Русский\", not \"Русский (Русский)\".\n */\nexport function languageLabel(lang: Pick<TranslatorLanguage, 'name' | 'native_name'> &\n Partial<Pick<TranslatorLanguage, 'search_alias'>>): { primary: string; native: string } {\n const primary = lang.search_alias || lang.name || ''\n const native = lang.native_name || ''\n if (!native || native === primary) return { primary, native: '' }\n return { primary, native: displayNative(primary, native) }\n}\n","/**\n * A consumer may supply a ready flag path or absolute URL instead of a country\n * code: languages with no country flag of their own (Tatar, Chuvash, Bashkir…)\n * are mapped to a hand-placed SVG such as \"/flags/cv.svg\". Those are final.\n */\nexport const isReadyFlagUrl = (flagCode: string): boolean =>\n flagCode.startsWith('/') || /^https?:\\/\\//i.test(flagCode)\n\n/**\n * The <img src> for a language's flag. Country codes are wrapped into the local\n * flag path (with a CDN fallback on error); a ready path/URL is passed through,\n * since wrapping it again yields \"/flags//flags/cv.svg.svg\" → 404.\n */\nexport const flagImageUrl = (flagCode: string): string =>\n isReadyFlagUrl(flagCode) ? flagCode : `/flags/${flagCode}.svg`\n","// Color constants for the langie\n// These colors are used across components for consistent theming\n\nexport const COLORS = {\n // Primary colors\n primary: {\n blue: '#3b82f6',\n blueLight: '#60a5fa',\n blueDark: '#2563eb',\n blueAlpha30: '#3b82f630',\n blueAlpha50: '#3b82f650'\n },\n\n // Neutral colors\n neutral: {\n white: '#fff',\n gray50: '#f9fafb',\n gray100: '#f3f4f6',\n gray200: '#e5e7eb',\n gray300: '#d1d5db',\n gray400: '#9ca3af',\n gray500: '#6b7280',\n gray600: '#4b5563',\n gray700: '#374151',\n gray800: '#1f2937',\n gray900: '#111827'\n },\n\n // Border colors\n border: {\n light: '#d1d5db',\n dark: '#4b5563',\n flag: '#eee'\n },\n\n // Text colors\n text: {\n primary: '#1f2937',\n secondary: '#6b7280',\n placeholder: '#9ca3af',\n inverse: '#f9fafb'\n }\n} as const\n\n// Theme-specific color mappings\nexport const THEME_COLORS = {\n light: {\n background: COLORS.neutral.white,\n backgroundDisabled: COLORS.neutral.gray100,\n border: COLORS.border.light,\n placeholder: COLORS.text.placeholder,\n ring: COLORS.primary.blueAlpha30,\n optionPointed: COLORS.neutral.gray100,\n optionPointedText: COLORS.text.primary,\n optionSelected: COLORS.primary.blue,\n optionSelectedText: COLORS.neutral.white,\n dropdownBackground: COLORS.neutral.white,\n dropdownBorder: COLORS.border.light,\n dropdownText: COLORS.text.primary,\n tagBackground: COLORS.primary.blue\n },\n dark: {\n background: COLORS.neutral.gray800,\n backgroundDisabled: COLORS.neutral.gray700,\n border: COLORS.border.dark,\n placeholder: COLORS.text.placeholder,\n ring: COLORS.primary.blueAlpha50,\n optionPointed: COLORS.neutral.gray700,\n optionPointedText: COLORS.neutral.gray50,\n optionSelected: COLORS.primary.blue,\n optionSelectedText: COLORS.neutral.white,\n dropdownBackground: COLORS.neutral.gray800,\n dropdownBorder: COLORS.border.dark,\n dropdownText: COLORS.neutral.gray50,\n tagBackground: COLORS.primary.blue\n }\n} as const\n\n// CSS variable names for easy reference\nexport const CSS_VARS = {\n // Multiselect variables\n multiselect: {\n bg: '--ms-bg',\n bgDisabled: '--ms-bg-disabled',\n borderColor: '--ms-border-color',\n placeholderColor: '--ms-placeholder-color',\n ringColor: '--ms-ring-color',\n optionBgPointed: '--ms-option-bg-pointed',\n optionColorPointed: '--ms-option-color-pointed',\n optionBgSelected: '--ms-option-bg-selected',\n optionColorSelected: '--ms-option-color-selected',\n dropdownBg: '--ms-dropdown-bg',\n dropdownBorderColor: '--ms-dropdown-border-color',\n dropdownColor: '--ms-dropdown-color',\n tagBg: '--ms-tag-bg'\n }\n} as const\n","import script from \"/builds/codelits/langie-sdk/src/components/LanguageSelect.vue?type=script\"\nexport * from \"/builds/codelits/langie-sdk/src/components/LanguageSelect.vue?type=script\"\n\nimport \"/builds/codelits/langie-sdk/src/components/LanguageSelect.vue?type=style&index=0\"\nexport default script\nscript.__scopeId = \"data-v-5b09cc17\"","<template>\n <div class=\"interface-language-select-wrapper\">\n <LanguageSelect\n :key=\"`interface-lang-${effectiveLanguages.length}-${effectiveLanguages[0]?.code || 'empty'}`\"\n :model-value=\"currentLanguageObject\"\n :languages=\"effectiveLanguages\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled || isChangingLanguage\"\n :is-dark=\"props.isDark\"\n @update:model-value=\"handleLanguageChange\"\n />\n\n <!-- Loading overlay -->\n <div\n v-if=\"isChangingLanguage\"\n class=\"language-change-loader\"\n :class=\"{ 'is-dark': props.isDark }\"\n >\n <div class=\"loader-spinner\"></div>\n <span class=\"loader-text\">{{ lr('Changing language...', 'ui') }}</span>\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, watch, onMounted, ref } from 'vue'\nimport LanguageSelect from './LanguageSelect.vue'\nimport { useLangie } from '../useLangie'\nimport type { TranslatorLanguage } from '../types'\nimport { getCountryCode } from '../utils/getCountryCode'\n\n// Loading state for language change\nconst isChangingLanguage = ref(false)\n\nconst props = defineProps({\n placeholder: {\n type: String,\n default: 'Select interface language'\n },\n disabled: {\n type: Boolean,\n default: false\n },\n isDark: {\n type: Boolean,\n default: false\n },\n translatorHost: {\n type: String,\n default: ''\n },\n apiKey: {\n type: String,\n default: ''\n },\n languages: {\n type: Array as () => TranslatorLanguage[],\n default: () => []\n }\n})\n\nconst emit = defineEmits(['update:modelValue'])\n\n// Use the same SDK instance as the main app\nconst { availableLanguages, currentLanguage, setLanguage, fetchLanguages, lr } = useLangie()\n\n// Use provided languages if available, otherwise use SDK's languages\nconst effectiveLanguages = computed(() => {\n const languages =\n props.languages && props.languages.length > 0 ? props.languages : availableLanguages.value\n\n // Ensure all languages have required fields to prevent jumping\n const processed = languages.map((lang) => ({\n ...lang,\n native_name: lang.native_name || lang.name,\n flag_country: lang.flag_country || lang.code\n }))\n\n // Important: Keep API order (by popularity from language_popularity table)\n // Do NOT sort alphabetically - multiselect may reorder, but we preserve source order\n return processed\n})\n\nconst currentLanguageObject = computed(() => {\n if (!currentLanguage.value) return null\n return effectiveLanguages.value.find((lang) => lang.code === currentLanguage.value) || null\n})\n\n// Function to detect browser language from available languages\nfunction detectBrowserLanguage(languages: TranslatorLanguage[]): string | null {\n if (languages.length === 0) return null\n\n // Get browser languages in order of preference\n const browserLanguages = navigator.languages || [navigator.language || 'en']\n\n // Try to find exact match first\n for (const browserLang of browserLanguages) {\n const langCode = browserLang.toLowerCase().split('-')[0] // Extract language code (e.g., 'en' from 'en-US')\n const exactMatch = languages.find((lang) => lang.code.toLowerCase() === langCode)\n if (exactMatch) {\n return exactMatch.code\n }\n }\n\n // If no exact match, try with full locale (e.g., 'en-US')\n for (const browserLang of browserLanguages) {\n const fullLangCode = browserLang.toLowerCase()\n const localeMatch = languages.find((lang) => lang.code.toLowerCase() === fullLangCode)\n if (localeMatch) {\n return localeMatch.code\n }\n }\n\n return null\n}\n\nasync function handleLanguageChange(selectedLanguage: TranslatorLanguage | null) {\n if (selectedLanguage) {\n // Start loading\n isChangingLanguage.value = true\n\n try {\n setLanguage(selectedLanguage.code)\n // Save to localStorage when user manually changes language\n localStorage.setItem('interface_language', selectedLanguage.code)\n emit('update:modelValue', selectedLanguage)\n } finally {\n // End loading\n isChangingLanguage.value = false\n }\n }\n}\n\n// Watch for current language changes to save to localStorage\nwatch(currentLanguage, (newLangCode) => {\n if (newLangCode) {\n localStorage.setItem('interface_language', newLangCode)\n }\n})\n\n// Watch for changes in effective languages to set browser language\nwatch(\n () => effectiveLanguages.value,\n (newLanguages) => {\n if (newLanguages.length > 0 && !currentLanguage.value) {\n // Only set browser language if no language is currently selected\n const savedLanguageCode = localStorage.getItem('interface_language')\n\n if (savedLanguageCode) {\n // Check if saved language exists in the provided languages\n const savedLangExists = newLanguages.find((lang) => lang.code === savedLanguageCode)\n if (savedLangExists) {\n setLanguage(savedLanguageCode)\n return\n }\n }\n\n // If no saved language or saved language doesn't exist, detect browser language\n const browserLang = detectBrowserLanguage(newLanguages)\n if (browserLang) {\n setLanguage(browserLang)\n }\n }\n },\n { immediate: true }\n)\n\n// Load saved language from localStorage on initialization\nonMounted(async () => {\n // Only fetch languages if not provided via props\n if (!props.languages || props.languages.length === 0) {\n // Get country code from browser for better language ordering\n const countryCode = await getCountryCode()\n await fetchLanguages({ country: countryCode || undefined })\n }\n\n const savedLanguageCode = localStorage.getItem('interface_language')\n\n if (savedLanguageCode && savedLanguageCode !== currentLanguage.value) {\n // Check if saved language exists in current languages\n const currentLanguages = effectiveLanguages.value\n const savedLangExists = currentLanguages.find((lang) => lang.code === savedLanguageCode)\n\n if (savedLangExists) {\n setLanguage(savedLanguageCode)\n } else if (currentLanguages.length > 0) {\n // If saved language doesn't exist, try to detect browser language\n const browserLang = detectBrowserLanguage(currentLanguages)\n if (browserLang) {\n setLanguage(browserLang)\n }\n }\n } else if (!currentLanguage.value && effectiveLanguages.value.length > 0) {\n // If no saved language and no current language, detect browser language\n const browserLang = detectBrowserLanguage(effectiveLanguages.value)\n if (browserLang) {\n setLanguage(browserLang)\n }\n }\n})\n\n// Emit the current language when it changes\nwatch(\n currentLanguageObject,\n (newValue) => {\n if (newValue) {\n emit('update:modelValue', newValue)\n }\n },\n { immediate: true }\n)\n</script>\n\n<style scoped>\n.interface-language-select-wrapper {\n position: relative;\n display: inline-block;\n width: 100%;\n min-width: 200px;\n}\n\n/* Override styles for the language select component */\n.interface-language-select-wrapper :deep(.multiselect-option) {\n padding: 5px 10px !important;\n margin: 0;\n border-radius: 0;\n}\n\n.interface-language-select-wrapper :deep(.multiselect-option > div) {\n padding: 0 !important;\n margin: 0;\n}\n\n.interface-language-select-wrapper :deep(.multiselect-dropdown) {\n padding: 2px 0 !important;\n}\n\n.language-change-loader {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(255, 255, 255, 0.95);\n border-radius: 6px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n z-index: 10;\n backdrop-filter: blur(2px);\n border: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.language-change-loader.is-dark {\n background: rgba(30, 30, 30, 0.95);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.loader-spinner {\n width: 24px;\n height: 24px;\n border: 3px solid #e5e7eb;\n border-top: 3px solid #3b82f6;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n margin-bottom: 8px;\n}\n\n.language-change-loader.is-dark .loader-spinner {\n border-color: #374151;\n border-top-color: #3b82f6;\n}\n\n.loader-text {\n font-size: 12px;\n color: #6b7280;\n font-weight: 500;\n text-align: center;\n}\n\n.language-change-loader.is-dark .loader-text {\n color: #9ca3af;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n</style>\n","import { watch } from 'vue'\nimport type {\n TranslatorOptions,\n TranslateServiceResponse,\n TranslatorLanguage,\n TranslationSeed\n} from './types'\nimport { translateBatch } from './core'\nimport { useLangieCore, __resetLangieCoreForTests } from './composables/useLangie-core'\nimport { TranslationBatching } from './composables/useLangie-batching'\nimport {\n API_FIELD_TEXT,\n API_FIELD_FROM,\n API_FIELD_TO,\n API_FIELD_CTX,\n API_FIELD_TRANSLATIONS,\n API_FIELD_ERROR\n} from './constants'\nimport { setCache, getCache } from './utils/cache'\nimport { devDebug } from './utils/debug'\n\n// Global singleton instance\ntype LangieInstance = ReturnType<typeof createLangieInstance> & { translatorHost?: string }\nlet globalLangieInstance: LangieInstance | null = null\n\n// Preserve singleton across hot module reloads\nif (\n typeof window !== 'undefined' &&\n (window as unknown as Record<string, unknown>).__LANGIE_SINGLETON__\n) {\n globalLangieInstance = (window as unknown as Record<string, unknown>)\n .__LANGIE_SINGLETON__ as ReturnType<typeof createLangieInstance>\n}\n\n// Helper for safe localStorage access\nfunction safeLocalStorageAccess<T>(operation: () => T): T | undefined {\n if (typeof window === 'undefined') return undefined\n try {\n return operation()\n } catch (e) {\n devDebug('[useLangie] localStorage error:', e)\n return undefined\n }\n}\n\n// Also check if we have a stored singleton in localStorage as backup\nif (!globalLangieInstance && typeof window !== 'undefined') {\n const stored = safeLocalStorageAccess(() => localStorage.getItem('__LANGIE_SINGLETON_URL__'))\n if (stored) {\n // Use stored URL to prevent recreation with wrong options\n const storedOptions = { translatorHost: stored }\n globalLangieInstance = createLangieInstance(storedOptions)\n }\n}\n\n// Extended type for translation objects that includes ctx\ninterface TranslationWithContext extends TranslateServiceResponse {\n [API_FIELD_CTX]?: string\n translated_text?: string\n}\n\nfunction createLangieInstance(options: TranslatorOptions = {}) {\n const core = useLangieCore(options)\n const {\n availableLanguages,\n translations,\n uiTranslations,\n currentLanguage,\n isLoading,\n setLanguage,\n fetchLanguages,\n invalidateLanguages,\n translatorHost,\n clearTranslations\n } = core\n\n // Global defaults for lt component\n const ltDefaults = {\n ctx: 'ui',\n orig: ''\n }\n\n // Functions to manage lt component defaults\n const setLtDefaults = (defaults: { ctx?: string; orig?: string }) => {\n Object.assign(ltDefaults, defaults)\n }\n\n const getLtDefaults = () => ({ ...ltDefaults })\n\n // Synchronous SSR seed: language → \"text|ctx\" → translation. Unlike the reactive\n // caches it is NOT cleared on language switch, so a server-rendered value stays\n // resolvable through hydration (client seeds the same map → no mismatch).\n const seed: TranslationSeed = {}\n if (options.ssrTranslations) seedTranslations(options.ssrTranslations)\n\n function seedTranslations(entries: TranslationSeed) {\n for (const lang of Object.keys(entries)) {\n seed[lang] = { ...(seed[lang] || {}), ...entries[lang] }\n }\n }\n\n const getSeed = (lang: string, text: string, ctx: string): string | undefined =>\n seed[lang]?.[`${text}|${ctx}`]\n\n // localStorage cache management\n const CACHE_KEY = 'langie_translations_cache'\n const UI_CACHE_KEY = 'langie_ui_translations_cache'\n const LANGUAGES_CACHE_KEY = 'langie_languages_cache'\n\n // Load cached translations from localStorage for current language\n const loadCachedTranslations = () => {\n if (typeof window === 'undefined') return\n\n const cachedTranslations = getCache<Record<string, Record<string, string>>>(CACHE_KEY)\n const cachedUiTranslations = getCache<Record<string, Record<string, string>>>(UI_CACHE_KEY)\n\n if (cachedTranslations) {\n // Load translations for current language only\n const currentLang = currentLanguage.value\n const langTranslations = cachedTranslations[currentLang] || {}\n Object.assign(translations, langTranslations)\n }\n\n if (cachedUiTranslations) {\n // Load UI translations for current language only\n const currentLang = currentLanguage.value\n const langUiTranslations = cachedUiTranslations[currentLang] || {}\n Object.assign(uiTranslations, langUiTranslations)\n }\n }\n\n // Save translations to localStorage for current language\n const saveCachedTranslations = () => {\n if (typeof window === 'undefined') return\n\n // Load existing cache\n const existingTranslations = getCache<Record<string, Record<string, string>>>(CACHE_KEY) || {}\n const existingUiTranslations =\n getCache<Record<string, Record<string, string>>>(UI_CACHE_KEY) || {}\n\n // Save current language translations\n const currentLang = currentLanguage.value\n existingTranslations[currentLang] = { ...translations }\n existingUiTranslations[currentLang] = { ...uiTranslations }\n\n // Save with TTL (7 days for translations)\n setCache(CACHE_KEY, existingTranslations, 7 * 24 * 60 * 60 * 1000)\n setCache(UI_CACHE_KEY, existingUiTranslations, 7 * 24 * 60 * 60 * 1000)\n }\n\n // Load cached languages from localStorage\n const loadCachedLanguages = () => {\n if (typeof window === 'undefined') return\n\n const cachedLanguages = getCache<TranslatorLanguage[]>(LANGUAGES_CACHE_KEY)\n if (cachedLanguages) {\n availableLanguages.value = cachedLanguages\n }\n }\n\n // Load cached translations and languages on initialization\n loadCachedTranslations()\n loadCachedLanguages()\n\n // Watch for language changes to load cached translations\n watch(currentLanguage, () => {\n // Clear current translations before loading new ones\n Object.keys(translations).forEach((key) => delete translations[key])\n Object.keys(uiTranslations).forEach((key) => delete uiTranslations[key])\n loadCachedTranslations()\n })\n\n // Create batching instance\n const batching = new TranslationBatching(\n {\n initialBatchDelay: options.initialBatchDelay,\n followupBatchDelay: options.followupBatchDelay,\n maxBatchSize: options.maxBatchSize,\n maxWaitTime: options.maxWaitTime,\n getTurnstileToken: options.getTurnstileToken\n },\n translatorHost,\n () => currentLanguage.value,\n (results, requests) => {\n // Process batch results and update translations\n // Batch complete\n\n // Clear recently queued cache to make translations immediately available\n requests.forEach((req) => {\n const cacheKey = `${req[API_FIELD_TEXT]}|${req[API_FIELD_CTX]}`\n const languageCacheKey = `${cacheKey}|${req[API_FIELD_FROM]}|${req[API_FIELD_TO]}`\n recentlyQueued.delete(languageCacheKey)\n })\n\n // --- PATCH: Map translations to requests by index (since ctx is not present in response) ---\n // Flatten all translation arrays from results\n let translationsArray: TranslationWithContext[] = []\n results.forEach((result) => {\n if (Array.isArray(result)) {\n translationsArray = translationsArray.concat(result)\n } else if (result.translations && Array.isArray(result.translations)) {\n translationsArray = translationsArray.concat(result.translations)\n }\n })\n\n translationsArray.forEach((translation, idx) => {\n const request = requests[idx]\n if (!request) {\n devDebug('[useLangie] No matching request for translation:', translation)\n return\n }\n const originalText = request[API_FIELD_TEXT]\n const originalCtx = request[API_FIELD_CTX] ?? (ltDefaults.ctx || 'ui')\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n devDebug(\n '[useLangie] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n\n // Record the error for future reference\n const errorKey = `${originalText}|${originalCtx}|${request[API_FIELD_FROM]}|${request[API_FIELD_TO]}`\n translationErrors.set(errorKey, translation[API_FIELD_ERROR])\n\n return // Don't cache translations with errors\n }\n\n // Handle language detection response\n if (translation[API_FIELD_FROM] && !translation[API_FIELD_TEXT]) {\n return\n }\n\n const translatedText = translation[API_FIELD_TEXT]\n if (translatedText) {\n // PATCH: Only skip as outdated if toLang was not explicitly set\n const requestedLanguage = request[API_FIELD_TO]\n const explicitToLang = request.__explicitToLang\n if (!explicitToLang && requestedLanguage !== currentLanguage.value) {\n devDebug('[useLangie] Skipping outdated translation:', {\n original: originalText,\n translated: translatedText,\n requestedLanguage,\n currentLanguage: currentLanguage.value\n })\n return\n }\n\n // Skip caching if translation equals original text\n if (translatedText === originalText) {\n devDebug('[useLangie] Skipping cache for identical translation:', {\n original: originalText,\n translated: translatedText,\n context: originalCtx\n })\n return\n }\n\n const effectiveCtx = originalCtx\n // Store under the exact key the read side queued with: explicit-target\n // requests carry a language-qualified key (see translateInternal).\n const cacheKey = request.cacheKey || `${originalText}|${effectiveCtx}`\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n\n // Cache the translation\n cache[cacheKey] = translatedText\n\n // Debug logging\n devDebug('[useLangie] Cached translation:', {\n original: originalText,\n translated: translatedText,\n context: effectiveCtx,\n cacheKey,\n language: requestedLanguage\n })\n\n // Save to localStorage\n saveCachedTranslations()\n }\n })\n }\n )\n\n // Simple cache to track recently queued translations\n const recentlyQueued = new Set<string>()\n // Set to track timeout ids for cleanup\n const pendingTimeouts = new Set<ReturnType<typeof setTimeout>>()\n\n // Track translation errors\n const translationErrors = new Map<string, string>()\n\n // Internal translation logic shared by l and lr\n const translateInternal = (\n text: string,\n ctx?: string,\n originalLang?: string,\n toLang?: string,\n reactive = false\n ) => {\n if (reactive) {\n void currentLanguage.value // For Vue reactivity\n }\n const from = originalLang || ltDefaults.orig || ''\n const to = toLang || currentLanguage.value\n\n // Skip translation if source and target languages are the same\n if (from === to) {\n return text\n }\n\n // Use provided context or global defaults, but don't fallback to 'ui' if ctx is explicitly provided\n const effectiveCtx = ctx !== undefined ? ctx : ltDefaults.ctx || 'ui'\n const baseKey = `${text}|${effectiveCtx}`\n // The caches are scoped to currentLanguage (cleared on language switch), so an\n // unqualified key is only valid when translating INTO the interface language.\n // Explicit targets (lr(text, ctx, from, to)) must carry the language pair in the\n // key, otherwise translations to different targets collide on the same entry.\n const cacheKey = to !== currentLanguage.value ? `${baseKey}|${from}|${to}` : baseKey\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n\n // Return cached translation if available\n if (cache[cacheKey]) {\n return cache[cacheKey]\n }\n\n // Fall back to a synchronous SSR seed (live translations above take precedence).\n const seeded = getSeed(to, text, effectiveCtx)\n if (seeded) {\n return seeded\n }\n\n // Check if we have a recorded error for this translation\n const errorKey = `${text}|${effectiveCtx}|${from}|${to}`\n if (translationErrors.has(errorKey)) {\n return text // Return original text for failed translations\n }\n\n // Check if we've recently queued this translation\n const languageCacheKey = `${baseKey}|${from}|${to}`\n if (recentlyQueued.has(languageCacheKey)) {\n return text\n }\n\n // Cold miss: let the host record it so it can warm the string after render.\n options.onTranslationMiss?.({ text, ctx: effectiveCtx, from, to })\n\n // Queue for translation, pass __explicitToLang if toLang is set\n batching.queueTranslation(text, effectiveCtx, from, to, cacheKey, toLang !== undefined)\n\n // Mark as recently queued\n recentlyQueued.add(languageCacheKey)\n\n // Clear the recently queued cache after a short delay\n // Use a shorter delay for tests to allow retries\n const clearDelay = 100 // Always use short delay for faster updates\n const timeoutId = setTimeout(() => {\n recentlyQueued.delete(languageCacheKey)\n pendingTimeouts.delete(timeoutId)\n }, clearDelay)\n pendingTimeouts.add(timeoutId)\n\n // Return original text for now (will be updated when translation arrives)\n return text\n }\n\n /**\n * l(): Non-reactive translation for plain JavaScript usage.\n * Returns translation or original text. Does NOT auto-update on language change.\n */\n const l = (text: string, ctx?: string, originalLang?: string, toLang?: string) =>\n translateInternal(text, ctx, originalLang, toLang, false)\n\n /**\n * lr(): Reactive translation for Vue usage.\n * Returns translation or original text. Auto-updates on language change (reactive).\n * Use in templates or computed properties.\n */\n const lr = (text: string, ctx?: string, originalLang?: string, toLang?: string) =>\n translateInternal(text, ctx, originalLang, toLang, true)\n\n /**\n * peekTranslation(): read-only lookup with NO queueing side effect. Returns a\n * live-cached or seeded translation, else the original text. Used on the server\n * so `<lt>` emits a seeded translation without queuing a doomed SSR request.\n */\n const peekTranslation = (text: string, ctx?: string, toLang?: string): string => {\n const effectiveCtx = ctx !== undefined ? ctx : ltDefaults.ctx || 'ui'\n const from = ltDefaults.orig || ''\n const to = toLang || currentLanguage.value\n if (from === to) return text\n const baseKey = `${text}|${effectiveCtx}`\n const cacheKey = to !== currentLanguage.value ? `${baseKey}|${from}|${to}` : baseKey\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n return cache[cacheKey] || getSeed(to, text, effectiveCtx) || text\n }\n\n /**\n * warmTranslations(): fetch translations for the given keys and merge them into\n * the SSR seed. Returns the resolved `\"text|ctx\" → translation` map for `lang`\n * so the host can persist it (e.g. Redis) and serialize it into the SSR payload.\n */\n const warmTranslations = async (\n keys: Array<{ text: string; ctx?: string }>,\n lang: string,\n from: string = ltDefaults.orig || ''\n ): Promise<Record<string, string>> => {\n const valid = keys.filter((k) => k && k.text)\n if (valid.length === 0) return {}\n\n const items = valid.map((k) => ({\n [API_FIELD_TEXT]: k.text,\n [API_FIELD_FROM]: from,\n [API_FIELD_TO]: lang,\n [API_FIELD_CTX]: k.ctx ?? ltDefaults.ctx ?? 'ui'\n }))\n\n const results = await translateBatch(items, {\n translatorHost,\n apiKey: options.apiKey,\n apiKeyEnv: options.apiKeyEnv\n })\n\n const resolved: Record<string, string> = {}\n results.forEach((res, i) => {\n const src = valid[i]\n const translated = res?.[API_FIELD_TEXT]\n if (src && translated && translated !== src.text) {\n const ctx = src.ctx ?? ltDefaults.ctx ?? 'ui'\n resolved[`${src.text}|${ctx}`] = translated\n }\n })\n\n if (Object.keys(resolved).length > 0) seedTranslations({ [lang]: resolved })\n return resolved\n }\n\n const fetchAndCacheBatch = async (\n items: { [API_FIELD_TEXT]: string; [API_FIELD_CTX]?: string }[],\n from?: string,\n to = currentLanguage.value,\n globalCtx?: string\n ) => {\n if (items.length === 0) return\n\n // Use global defaults for from language if not provided\n const effectiveFrom = from || ltDefaults.orig || ''\n\n // Skip translation if source and target languages are the same\n if (effectiveFrom === to) {\n return\n }\n\n isLoading.value = true\n\n try {\n // Use global context if provided, otherwise fall back to global defaults or 'ui'\n const effectiveCtx = globalCtx || ltDefaults.ctx || 'ui'\n\n const response = await fetch(`${translatorHost}/translate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n translations: items.map((item) => ({\n [API_FIELD_TEXT]: item[API_FIELD_TEXT],\n [API_FIELD_CTX]: item[API_FIELD_CTX] || effectiveCtx\n })),\n [API_FIELD_FROM]: effectiveFrom,\n [API_FIELD_TO]: to\n })\n })\n\n if (!response.ok) {\n throw new Error(`Translation request failed: ${response.status}`)\n }\n\n const result = await response.json()\n\n // Handle top-level error responses\n if (result[API_FIELD_ERROR]) {\n devDebug('[useLangie] Top-level API error:', result[API_FIELD_ERROR])\n\n // Create error responses for all items\n const errorResponses = items.map((item) => ({\n [API_FIELD_TEXT]: item[API_FIELD_TEXT],\n [API_FIELD_ERROR]: result[API_FIELD_ERROR]\n }))\n\n // Process error responses\n errorResponses.forEach((translation: TranslationWithContext, index: number) => {\n const item = items[index]\n const originalText = item?.[API_FIELD_TEXT]\n if (!originalText) {\n return\n }\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n devDebug(\n '[useLangie] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n\n // Record the error for future reference\n const errorKey = `${originalText}|${item[API_FIELD_CTX] || effectiveCtx}|${effectiveFrom}|${to}`\n translationErrors.set(errorKey, translation[API_FIELD_ERROR])\n\n return // Don't cache translations with errors\n }\n })\n\n return // Skip normal processing\n }\n\n if (result[API_FIELD_TRANSLATIONS]) {\n result[API_FIELD_TRANSLATIONS].forEach(\n (translation: TranslationWithContext, index: number) => {\n const item = items[index]\n const originalText = item?.[API_FIELD_TEXT]\n if (!originalText) {\n return\n }\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n devDebug(\n '[useLangie] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n return // Don't cache translations with errors\n }\n\n // Handle language detection response\n if (translation[API_FIELD_FROM] && !translation[API_FIELD_TEXT]) {\n // Не кешируем детекцию\n return\n }\n\n // Handle translation response\n const translatedText = translation[API_FIELD_TEXT]\n if (translatedText) {\n // Check if the target language is still current\n if (to !== currentLanguage.value) {\n devDebug('[useLangie] Skipping outdated translation (batch):', {\n original: originalText,\n translated: translatedText,\n requestedLanguage: to,\n currentLanguage: currentLanguage.value\n })\n return\n }\n\n // Skip caching if translation equals original text\n if (translatedText === originalText) {\n devDebug('[useLangie] Skipping cache for identical translation (batch):', {\n original: originalText,\n translated: translatedText,\n context: item[API_FIELD_CTX] || effectiveCtx\n })\n return\n }\n\n // Use the context from the original item, not from the response\n const originalCtx = item[API_FIELD_CTX]\n const translationCtx = originalCtx !== undefined ? originalCtx : effectiveCtx\n const cacheKey = `${originalText}|${translationCtx}`\n const cache = translationCtx === 'ui' ? uiTranslations : translations\n cache[cacheKey] = translatedText\n\n // Debug logging\n devDebug('[useLangie] Cached translation (batch):', {\n original: originalText,\n translated: translatedText,\n context: translationCtx,\n cacheKey,\n language: to\n })\n\n // Save to localStorage\n saveCachedTranslations()\n }\n }\n )\n }\n } catch (error) {\n console.error('[useLangie] Translation error:', error)\n } finally {\n isLoading.value = false\n }\n }\n\n // Watch for language changes - load translations for new language\n watch(currentLanguage, () => {\n // Clear recently queued cache to prevent race conditions\n recentlyQueued.clear()\n\n // Load cached translations for new language\n loadCachedTranslations()\n\n // Cleanup batching to cancel pending requests\n batching.cleanup()\n })\n\n return {\n // Core functionality\n availableLanguages,\n translations,\n uiTranslations,\n currentLanguage,\n isLoading,\n setLanguage,\n fetchLanguages,\n invalidateLanguages,\n translatorHost,\n\n // Translation functions\n l,\n lr,\n peekTranslation,\n fetchAndCacheBatch,\n\n // SSR translation seam\n seedTranslations,\n warmTranslations,\n\n // Error handling\n getTranslationError: (text: string, ctx?: string, from?: string, to?: string) => {\n const effectiveCtx = ctx !== undefined ? ctx : ltDefaults.ctx || 'ui'\n const effectiveFrom = from || ltDefaults.orig || ''\n const effectiveTo = to || currentLanguage.value\n const errorKey = `${text}|${effectiveCtx}|${effectiveFrom}|${effectiveTo}`\n return translationErrors.get(errorKey) || null\n },\n\n // Utility functions\n cleanup: () => {\n clearTranslations()\n batching.cleanup()\n // Очистка всех таймеров\n pendingTimeouts.forEach((id) => clearTimeout(id))\n pendingTimeouts.clear()\n translationErrors.clear()\n },\n getBatchingStats: () => batching.getStats(),\n\n // lt component defaults management\n setLtDefaults,\n getLtDefaults\n }\n}\n\n// --- GLOBAL SINGLETON LOGIC ---\n// Always use window.__LANGIE_SINGLETON__ as the source of truth\nfunction getGlobalLangieInstance(): LangieInstance | null {\n if (typeof window !== 'undefined') {\n return (\n (window as unknown as { __LANGIE_SINGLETON__?: LangieInstance }).__LANGIE_SINGLETON__ || null\n )\n }\n return globalLangieInstance\n}\nfunction setGlobalLangieInstance(instance: LangieInstance, options?: TranslatorOptions) {\n if (typeof window !== 'undefined') {\n ;(window as unknown as { __LANGIE_SINGLETON__?: LangieInstance }).__LANGIE_SINGLETON__ =\n instance\n if (options && options.translatorHost) {\n safeLocalStorageAccess(() =>\n localStorage.setItem('__LANGIE_SINGLETON_URL__', options.translatorHost!)\n )\n }\n }\n globalLangieInstance = instance\n}\n\nexport function useLangie(options: TranslatorOptions = {}) {\n const globalInstance: LangieInstance | null = getGlobalLangieInstance()\n\n // If no options or options match, always return the global instance if it exists\n if (globalInstance) {\n const currentHost = globalInstance.translatorHost\n const newHost = options.translatorHost\n if (!options.translatorHost || currentHost === newHost) {\n return globalInstance\n }\n }\n\n // Otherwise, create a new instance\n const instance: LangieInstance = createLangieInstance(options)\n setGlobalLangieInstance(instance, options)\n return instance\n}\n\nexport function __resetLangieSingletonForTests() {\n if (globalLangieInstance) {\n globalLangieInstance.cleanup()\n }\n globalLangieInstance = null\n\n // Clear localStorage backup\n if (typeof window !== 'undefined') {\n safeLocalStorageAccess(() => localStorage.removeItem('__LANGIE_SINGLETON_URL__'))\n try {\n delete (window as unknown as Record<string, unknown>).__LANGIE_SINGLETON__\n } catch (e) {\n devDebug('[useLangie] window singleton delete error:', e)\n }\n }\n\n __resetLangieCoreForTests()\n}\n\n// Global lt component defaults management\nexport function setLtDefaults(defaults: { ctx?: string; orig?: string }) {\n const instance = getGlobalLangieInstance()\n if (instance && instance.setLtDefaults) {\n instance.setLtDefaults(defaults)\n }\n}\n\nexport function getLtDefaults() {\n const instance = getGlobalLangieInstance()\n if (instance && instance.getLtDefaults) {\n return instance.getLtDefaults()\n }\n return { ctx: 'ui', orig: '' }\n}\n","/**\n * Default API configuration constants\n */\nexport const DEFAULT_API_HOST = 'https://api.langie.uk/v1'\n\n/**\n * Development/Demo API host for local testing.\n * Uses the keyless first-party `/frontend` proxy (the backend injects\n * PAGES_API_KEY); the raw `/v1` endpoints require a client API key.\n */\nexport const DEV_API_HOST = 'http://localhost:8081/frontend'\n\n/**\n * Default translator options\n */\nexport const DEFAULT_TRANSLATOR_OPTIONS = {\n translatorHost: DEFAULT_API_HOST,\n defaultLanguage: 'en',\n fallbackLanguage: 'en'\n} as const\n\n/**\n * API field constants\n * Used throughout the SDK to ensure consistency\n */\n\n// Translation text field\nexport const API_FIELD_TEXT = 't'\n\n// Source language field\nexport const API_FIELD_FROM = 'from'\n\n// Target language field\nexport const API_FIELD_TO = 'to'\n\n// Context field\nexport const API_FIELD_CTX = 'ctx'\n\n// Glossary term-forcing fields (optional): render API_FIELD_GLOSSARY_SRC as exactly\n// API_FIELD_GLOSSARY_TGT so a headword and its example stay consistent. Only\n// providers with an inline glossary honour them; the API ignores the pair otherwise.\nexport const API_FIELD_GLOSSARY_SRC = 'gs'\nexport const API_FIELD_GLOSSARY_TGT = 'gt'\n\n// Translated text field (same as text field for response)\nexport const API_FIELD_TRANSLATED = 't'\n\n// Translations array field\nexport const API_FIELD_TRANSLATIONS = 'translations'\n\n// Error field for API responses\nexport const API_FIELD_ERROR = 'error'\n\n// Cloudflare Turnstile token field — anti-abuse on the keyless /frontend/translate proxy\nexport const API_FIELD_TURNSTILE = 'turnstileToken'\n","/**\n * Core translation functions\n */\nimport type {\n TranslateRequestBody,\n TranslateServiceResponse,\n TranslatorLanguage,\n TranslatorOptions\n} from './types'\nimport {\n API_FIELD_TEXT,\n API_FIELD_FROM,\n API_FIELD_TO,\n API_FIELD_CTX,\n API_FIELD_GLOSSARY_SRC,\n API_FIELD_GLOSSARY_TGT,\n API_FIELD_TRANSLATIONS,\n API_FIELD_ERROR,\n API_FIELD_TURNSTILE\n} from './constants'\n\nconst DEFAULT_TRANSLATOR_HOST = 'http://localhost:8081'\nconst DEFAULT_API_KEY_ENV = 'TRANSLATOR_API_KEY'\n\n/**\n * Resolve the API key: explicit `apiKey` wins, then a host-configured env var\n * name (`apiKeyEnv`), then the default `TRANSLATOR_API_KEY`.\n */\nfunction resolveApiKey(options: TranslatorOptions): string | undefined {\n if (options.apiKey) return options.apiKey\n const env = typeof process !== 'undefined' ? process.env : undefined\n if (!env) return undefined\n return env[options.apiKeyEnv || DEFAULT_API_KEY_ENV]\n}\n\n// Optional glossary pair, included only when both terms are set. Shared by the\n// cache key and the request body so a forced request never collides with a plain one.\nfunction glossaryFields(t: TranslateRequestBody): Record<string, string> {\n const src = t[API_FIELD_GLOSSARY_SRC]\n const tgt = t[API_FIELD_GLOSSARY_TGT]\n return src && tgt ? { [API_FIELD_GLOSSARY_SRC]: src, [API_FIELD_GLOSSARY_TGT]: tgt } : {}\n}\n\n// --- Translation cache ---\nconst translationCache = new Map<string, Promise<TranslateServiceResponse[]>>()\n\nfunction getTranslationCacheKey(\n serviceTranslations: TranslateRequestBody[],\n options: TranslatorOptions\n): string {\n // Create a stable cache key based on translations and options\n return JSON.stringify({\n translations: serviceTranslations.map((t) => ({\n [API_FIELD_TEXT]: t[API_FIELD_TEXT],\n [API_FIELD_FROM]: t[API_FIELD_FROM],\n [API_FIELD_TO]: t[API_FIELD_TO],\n [API_FIELD_CTX]: t[API_FIELD_CTX] || options[API_FIELD_CTX] || 'ui',\n ...glossaryFields(t)\n })),\n host: options.translatorHost || DEFAULT_TRANSLATOR_HOST,\n context: options[API_FIELD_CTX] || 'ui'\n })\n}\n\n/**\n * Translates a batch of texts\n *\n * @param translations Array of translation requests\n * @param options Configuration options\n * @returns Array of translated texts\n */\nexport async function translateBatch(\n translations: TranslateRequestBody[] = [],\n options: TranslatorOptions = {}\n): Promise<TranslateServiceResponse[]> {\n // const startTime = Date.now()\n\n // try {\n // console.debug('[translator-sdk] translateBatch called', {\n // count: translations.length,\n // sample: translations.slice(0, 3).map((t) => ({\n // text: t.text?.slice?.(0, 30) ?? '',\n // from: t.from_lang,\n // to: t.to_lang\n // })),\n // opts: { ...options }\n // })\n // } catch (_) {\n // // Ignore logging errors – never block translation\n // }\n\n if (!Array.isArray(translations) || translations.length === 0) {\n // console.error('[translator-sdk] Invalid translations input:', { translations })\n throw new Error('translations must be a non-empty array')\n }\n\n const translatorHost = options.translatorHost || DEFAULT_TRANSLATOR_HOST\n const apiKey = resolveApiKey(options)\n\n // console.debug('[translator-sdk] Configuration', {\n // translatorHost,\n // hasApiKey: !!apiKey,\n // apiKeyLength: apiKey?.length || 0\n // })\n\n // Partition translations: identical language pairs can be returned as-is\n const serviceTranslations: TranslateRequestBody[] = []\n const indexMap: number[] = []\n\n translations.forEach((tr, idx) => {\n const from = (tr[API_FIELD_FROM] || '').toLowerCase()\n const to = (tr[API_FIELD_TO] || '').toLowerCase()\n if (from === to) {\n // console.debug('[translator-sdk] Skipping translation (same language)', { from, to, text: tr.t?.slice(0, 20) })\n return // no need to translate\n }\n serviceTranslations.push(tr)\n indexMap.push(idx)\n })\n\n // console.debug('[translator-sdk] Translation partitioning', {\n // total: translations.length,\n // needsTranslation: serviceTranslations.length,\n // skipped: translations.length - serviceTranslations.length\n // })\n\n let serviceResults: TranslateServiceResponse[] = []\n if (serviceTranslations.length > 0) {\n // Check cache first\n const cacheKey = getTranslationCacheKey(serviceTranslations, options)\n if (translationCache.has(cacheKey)) {\n // console.debug('[translator-sdk] Cache hit for translation batch')\n serviceResults = await translationCache.get(cacheKey)!\n } else {\n // const requestStartTime = Date.now()\n // console.debug('[translator-sdk] Sending request to translator', {\n // host: translatorHost,\n // apiKeySnippet: apiKey ? `${apiKey.slice(0, 4)}…${apiKey.slice(-4)}` : 'none',\n // batchCount: serviceTranslations.length,\n // requestSize: JSON.stringify({ translations: serviceTranslations }).length\n // })\n\n const translationPromise = (async () => {\n try {\n // Fresh Turnstile token per flush (single-use); only the keyless\n // /frontend/translate proxy requires it, other hosts ignore the field.\n const turnstileToken = options.getTurnstileToken\n ? await options.getTurnstileToken()\n : undefined\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), 5000) // 5s timeout\n\n const resp = await fetch(`${translatorHost}/translate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { Authorization: `Bearer ${apiKey}`, 'X-Api-Key': apiKey } : {})\n },\n body: JSON.stringify({\n [API_FIELD_TRANSLATIONS]: serviceTranslations.map((t) => ({\n [API_FIELD_TEXT]: t[API_FIELD_TEXT],\n [API_FIELD_FROM]: t[API_FIELD_FROM],\n [API_FIELD_TO]: t[API_FIELD_TO],\n [API_FIELD_CTX]: t[API_FIELD_CTX] || options[API_FIELD_CTX] || 'ui',\n ...glossaryFields(t)\n })),\n [API_FIELD_CTX]: options[API_FIELD_CTX] || 'ui',\n ...(turnstileToken ? { [API_FIELD_TURNSTILE]: turnstileToken } : {})\n }),\n signal: controller.signal\n })\n\n clearTimeout(timeoutId)\n // const requestDuration = Date.now() - requestStartTime\n\n // console.debug('[translator-sdk] Translator response received', {\n // status: resp.status,\n // statusText: resp.statusText,\n // duration: `${requestDuration}ms`,\n // contentType: resp.headers.get('content-type'),\n // contentLength: resp.headers.get('content-length')\n // })\n\n if (!resp.ok) {\n console.error(\n '[translator-sdk] Translator error response:',\n resp.status,\n resp.statusText\n )\n throw new Error(`Translator service error: ${resp.status} ${resp.statusText}`)\n }\n\n let parsed: {\n translations?: TranslateServiceResponse[]\n t?: string\n error?: string\n } | null\n try {\n parsed = await resp.clone().json()\n // console.debug('[translator-sdk] Response parsed successfully', {\n // hasTranslations: !!parsed?.translations,\n // translationCount: parsed?.translations?.length || 0,\n // hasLegacyT: !!parsed?.t\n // })\n } catch (jsonErr) {\n console.error('[translator-sdk] Failed to parse JSON response:', jsonErr)\n throw new Error(`Failed to parse JSON response: ${jsonErr}`)\n }\n\n // if (parsed) {\n // console.debug(\n // '[translator-sdk] Translator response sample',\n // JSON.stringify(parsed).slice(0, 500)\n // )\n // }\n\n const data = parsed || {}\n\n // Handle top-level error responses\n if (data[API_FIELD_ERROR]) {\n console.warn(`[translator-sdk] Top-level API error:`, data[API_FIELD_ERROR])\n\n // Create error responses for all translations\n return serviceTranslations.map((translation) => ({\n [API_FIELD_TEXT]: translation[API_FIELD_TEXT],\n [API_FIELD_ERROR]: data[API_FIELD_ERROR]\n }))\n }\n\n const results = Array.isArray(data[API_FIELD_TRANSLATIONS])\n ? data[API_FIELD_TRANSLATIONS].map((translation, index) => {\n const originalText = serviceTranslations[index]?.[API_FIELD_TEXT] || ''\n\n // Handle error responses\n if (translation[API_FIELD_ERROR]) {\n console.warn(\n `[translator-sdk] Translation error for \"${originalText}\":`,\n translation[API_FIELD_ERROR]\n )\n return {\n [API_FIELD_TEXT]: originalText, // Return original text on error\n [API_FIELD_ERROR]: translation[API_FIELD_ERROR]\n }\n }\n\n // Handle language detection response\n if (translation[API_FIELD_FROM] && !translation[API_FIELD_TEXT]) {\n return {\n [API_FIELD_TEXT]: originalText, // For detection, return original text\n [API_FIELD_FROM]: translation[API_FIELD_FROM]\n }\n }\n\n // Handle translation response\n return {\n [API_FIELD_TEXT]: translation[API_FIELD_TEXT] || originalText\n }\n })\n : data[API_FIELD_TEXT]\n ? [{ [API_FIELD_TEXT]: data[API_FIELD_TEXT] }]\n : []\n\n // console.debug('[translator-sdk] Service results processed', {\n // resultCount: results.length,\n // expectedCount: serviceTranslations.length\n // })\n\n return results\n } catch (error: unknown) {\n // Remove from cache on error\n translationCache.delete(cacheKey)\n\n if (error instanceof Error && error.name === 'AbortError') {\n const message = `Translator request to ${translatorHost} timed out after 5 seconds.`\n console.error(message)\n throw new Error(message)\n }\n const message = `Failed to connect to translator at ${translatorHost}. Is the service running?`\n console.error(message)\n throw new Error(message)\n }\n })()\n\n // Cache the promise\n translationCache.set(cacheKey, translationPromise)\n serviceResults = await translationPromise\n }\n }\n\n // Assemble final results in original order\n const final = translations.map((tr, idx) => {\n const from = (tr[API_FIELD_FROM] || '').toLowerCase()\n const to = (tr[API_FIELD_TO] || '').toLowerCase()\n if (from === to) return { [API_FIELD_TEXT]: tr[API_FIELD_TEXT] }\n\n const svcIdx = indexMap.indexOf(idx)\n if (svcIdx !== -1) return serviceResults[svcIdx] || { [API_FIELD_TEXT]: tr[API_FIELD_TEXT] }\n return { [API_FIELD_TEXT]: tr[API_FIELD_TEXT] }\n })\n\n // const totalDuration = Date.now() - startTime\n // console.debug('[translator-sdk] translateBatch completed', {\n // totalDuration: `${totalDuration}ms`,\n // resultCount: final.length,\n // successCount: final.filter(r => r.translated && r.translated !== r.text).length\n // })\n\n return final as TranslateServiceResponse[]\n}\n\n// --- Cache management functions ---\nexport function clearTranslationCache(): void {\n translationCache.clear()\n}\n\nexport function getTranslationCacheSize(): number {\n return translationCache.size\n}\n\n/**\n * Vendor/legacy codes whose primary subtag isn't their BCP-47 base language.\n * Folding `kazlat` → `kk` treats Latin and Cyrillic Kazakh as siblings, so a\n * popularity-passing variant keeps its below-floor sibling visible (both scripts\n * stay selectable). It does NOT dedup them — both rows survive.\n */\nconst BASE_CODE_ALIASES: Record<string, string> = {\n kazlat: 'kk' // Kazakh (Latin) — vendor code, not \"kk-latn\"\n}\n\n/**\n * Reduce a language code to its BCP-47 primary subtag, so script/region variants\n * share a base: `sr-cyrl`/`sr-latn` → `sr`, `kk`/`kazlat` → `kk`.\n */\nexport function baseLanguageCode(code: string): string {\n const c = (code || '').trim().toLowerCase().replace(/_/g, '-')\n return BASE_CODE_ALIASES[c] ?? (c.split('-')[0] || c)\n}\n\n/**\n * Fetches available languages from the translation service\n *\n * @param options Configuration options\n * @returns Array of available languages\n */\nexport async function fetchAvailableLanguages(\n options: TranslatorOptions = {}\n): Promise<TranslatorLanguage[]> {\n // const startTime = Date.now()\n\n // console.debug('[translator-sdk] fetchAvailableLanguages called', { options })\n\n const translatorHost = options.translatorHost || DEFAULT_TRANSLATOR_HOST\n const apiKey = resolveApiKey(options)\n // Popularity filtering is opt-in. Default 0 returns the full catalog so the\n // caller (e.g. a searchable picker) gets every language and every script\n // variant; a host env var must not silently prune the list.\n const minPop = options.minPopularity !== undefined ? Number(options.minPopularity) : 0\n\n // console.debug('[translator-sdk] Languages request config', {\n // translatorHost,\n // hasApiKey: !!apiKey,\n // minPopularity: minPop,\n // country: options.country,\n // region: options.region\n // })\n\n const queryParams = []\n if (options.country) queryParams.push(`country=${encodeURIComponent(options.country)}`)\n if (options.region) queryParams.push(`region=${encodeURIComponent(options.region)}`)\n const queryStr = queryParams.length ? `?${queryParams.join('&')}` : ''\n\n const requestUrl = `${translatorHost}/languages${queryStr}`\n\n try {\n const resp = await fetch(requestUrl, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { Authorization: `Bearer ${apiKey}`, 'X-Api-Key': apiKey } : {})\n }\n })\n\n if (!resp.ok) {\n throw new Error(`Translator languages error: ${resp.status}`)\n }\n\n const data = await resp.json()\n const languages: TranslatorLanguage[] = Array.isArray(data) ? data : data.languages || []\n\n if (minPop <= 0) return languages\n\n const passes = (lang: TranslatorLanguage): boolean =>\n lang.popularity === undefined || lang.popularity === null || Number(lang.popularity) >= minPop\n\n // Keep every script/region variant of a base language that has at least one\n // passing entry, so a low-popularity variant (e.g. Kazakh Cyrillic with\n // popularity 0) survives next to its popular sibling and the UI can still\n // offer the \"which variant?\" choice. Otherwise a flat floor splits the pair.\n const keptBases = new Set(languages.filter(passes).map((l) => baseLanguageCode(l.code)))\n return languages.filter((lang) => passes(lang) || keptBases.has(baseLanguageCode(lang.code)))\n } catch (error) {\n console.error('[translator-sdk] Languages fetch error:', error)\n throw error\n }\n}\n","import { ref, reactive, watch } from 'vue'\nimport type { Ref } from 'vue'\nimport type { TranslatorOptions, TranslatorLanguage } from '../types'\nimport { DEFAULT_API_HOST } from '../constants'\nimport { devDebug } from '../utils/debug'\nimport { getCountryCode } from '../utils/getCountryCode'\nimport { setCache, getCache, clearCache } from '../utils/cache'\nimport { localizeLanguageNames } from '../utils/localizeLanguageNames'\n\nconst availableLanguages: Ref<TranslatorLanguage[]> = ref([])\nconst translations: { [key: string]: string } = reactive({})\nconst uiTranslations: { [key: string]: string } = reactive({})\nconst currentLanguage: Ref<string> = ref('en')\n\n// Global state for the translator host\nlet _translatorHost: string = DEFAULT_API_HOST\n\n// Prevent repeated auto-selection of interface language\nlet _autoSelected = false\n\n// Module-scope cache for languages so multiple composable instances / hot-reload don't refetch\nlet _languagesCache: TranslatorLanguage[] | null = null\nlet _languagesCacheAt = 0\nlet _languagesPromise: Promise<TranslatorLanguage[]> | null = null\n\nconst LANGUAGES_CACHE_KEY = 'langie_languages_cache'\n\n// Test reset function\nexport function __resetLangieCoreForTests() {\n availableLanguages.value = []\n Object.keys(translations).forEach((key) => delete translations[key])\n Object.keys(uiTranslations).forEach((key) => delete uiTranslations[key])\n currentLanguage.value = 'en'\n _translatorHost = DEFAULT_API_HOST\n _autoSelected = false\n _languagesCache = null\n _languagesCacheAt = 0\n _languagesPromise = null\n\n // Clear localStorage for tests\n if (typeof window !== 'undefined') {\n localStorage.removeItem('interface_language')\n clearCache() // Clear all langie cache items\n }\n}\n\nexport function useLangieCore(options: TranslatorOptions = {}) {\n // If a host is provided in options, it overrides the global host for all instances.\n // This ensures that the first initialization (e.g., from App.vue) sets the host correctly.\n if (options.translatorHost) {\n _translatorHost = options.translatorHost\n }\n\n const translatorHost = _translatorHost // Use the shared host\n const defaultLanguage = options.defaultLanguage || 'en'\n\n const isLoading = ref(false)\n\n // Initialize shared currentLanguage with default if not already set\n // Always respect the defaultLanguage option if it's different from 'en'\n if (defaultLanguage !== 'en' && currentLanguage.value === 'en') {\n currentLanguage.value = defaultLanguage\n }\n\n // Restore saved language from localStorage if available\n if (typeof window !== 'undefined' && currentLanguage.value === 'en') {\n const savedLanguage = localStorage.getItem('interface_language')\n if (savedLanguage) {\n currentLanguage.value = savedLanguage\n }\n }\n\n // Seed the language list from localStorage for an instant first paint, but\n // deliberately DON'T prime _languagesCache: leaving it null makes the first\n // fetchLanguages() of the session revalidate against the network instead of\n // short-circuiting on the cache. Stale-while-revalidate — the cache paints\n // immediately, the fetched catalog is the source of truth. Without this a list\n // cached during a backend outage (e.g. a truncated fallback) would stick for\n // the full 7-day TTL and the picker would never recover.\n if (typeof window !== 'undefined') {\n const cachedLanguages = getCache<TranslatorLanguage[]>(LANGUAGES_CACHE_KEY)\n if (cachedLanguages && availableLanguages.value.length === 0) {\n availableLanguages.value = cachedLanguages\n devDebug('[useLangie] Seeded languages from cache (will revalidate):', cachedLanguages.length)\n } else if (cachedLanguages) {\n devDebug(\n '[useLangie] Cache exists but languages already loaded:',\n availableLanguages.value.length\n )\n } else {\n devDebug('[useLangie] No cached languages found')\n }\n }\n\n // Fill each language's `search_alias` with its name in `lang` so the picker's\n // fuzzy search matches names typed in the user's own language/script. Fire and\n // forget: cached per language, swaps the list in once resolved (unless a\n // concurrent refetch already replaced it).\n const applyLocalizedNames = (lang: string) => {\n const base = availableLanguages.value\n if (!base.length) return\n localizeLanguageNames(base, lang, { translatorHost })\n .then((localized) => {\n if (localized !== base && availableLanguages.value === base) {\n availableLanguages.value = localized\n }\n })\n .catch(() => {})\n }\n\n // A returning visitor arrives with the interface language already set (cookie /\n // localStorage / defaultLanguage) and the list seeded from cache, so neither\n // setLanguage() nor fetchLanguages() runs — without this the picker keeps\n // showing English names for the whole session. Watching the length (not the\n // array) is what keeps the swap below from re-triggering this.\n watch(\n [() => availableLanguages.value.length, currentLanguage],\n ([count, lang]) => {\n if (count) applyLocalizedNames(lang)\n },\n { immediate: true }\n )\n\n const setLanguage = (lang: string) => {\n if (lang && lang !== currentLanguage.value) {\n // debugOnlyDev(`[useLangie] setLanguage: ${currentLanguage.value} → ${lang}`)\n }\n currentLanguage.value = lang\n\n // Save to localStorage for persistence\n if (typeof window !== 'undefined') {\n localStorage.setItem('interface_language', lang)\n }\n\n applyLocalizedNames(lang)\n }\n\n const fetchLanguages = async (\n opts: { force?: boolean; country?: string; maxAgeMs?: number } = {}\n ) => {\n const { force = false, country: explicitCountry, maxAgeMs } = opts\n // const startTime = Date.now()\n\n // A cached catalogue is fresh unless maxAgeMs is set and it has aged past it,\n // giving hosts a short cross-session TTL without throwing away the cache via force.\n const cacheFresh =\n !!_languagesCache && (maxAgeMs === undefined || Date.now() - _languagesCacheAt < maxAgeMs)\n\n devDebug('[useLangie] fetchLanguages called:', {\n force,\n maxAgeMs,\n cacheFresh,\n hasCache: !!_languagesCache,\n hasPromise: !!_languagesPromise,\n availableLanguagesLength: availableLanguages.value.length\n })\n\n if (!force) {\n if (cacheFresh) {\n devDebug('[useLangie] Returning cached languages:', _languagesCache!.length)\n return _languagesCache!\n }\n if (_languagesPromise) {\n devDebug('[useLangie] Returning existing promise')\n return _languagesPromise\n }\n }\n\n try {\n // Determine country hint - but only if we don't have cached languages\n let countryHint = explicitCountry || null\n if (\n !countryHint &&\n !_languagesCache &&\n availableLanguages.value &&\n availableLanguages.value.length\n ) {\n const currentLang = currentLanguage.value\n const entry = availableLanguages.value.find(\n (l: TranslatorLanguage) => l.code === currentLang\n )\n if (entry) {\n const c = Array.isArray(entry.flag_country)\n ? entry.flag_country[0]\n : typeof entry.flag_country === 'string'\n ? (entry.flag_country as string).split(',')[0]\n : null\n if (c) countryHint = c.toUpperCase()\n }\n }\n if (!countryHint && !_languagesCache && typeof window !== 'undefined') {\n // Use only browser locale for country hint (synchronous)\n const cc = await getCountryCode()\n countryHint = cc\n }\n\n let url = '/languages'\n // Добавляем language и timezone\n const language =\n (typeof navigator !== 'undefined' && navigator.languages && navigator.languages[0]) ||\n (typeof navigator !== 'undefined' && navigator.language) ||\n ''\n const timezone =\n (typeof Intl !== 'undefined' && Intl.DateTimeFormat().resolvedOptions().timeZone) || ''\n const params = new URLSearchParams()\n if (countryHint) params.append('country', countryHint)\n if (language) params.append('language', language)\n if (timezone) params.append('timezone', timezone)\n if (Array.from(params).length > 0) url += `?${params.toString()}`\n\n // Note: /languages endpoint should NOT increase usage count\n _languagesPromise = fetch(`${translatorHost}${url}`).then((res) => res.json())\n const response = (await _languagesPromise) as\n | TranslatorLanguage[]\n | { languages: TranslatorLanguage[] }\n const rawList: TranslatorLanguage[] = Array.isArray(response)\n ? response\n : response.languages || []\n\n // normalise to expected structure\n const mapped: TranslatorLanguage[] = rawList.map(\n (lang: TranslatorLanguage & { flag_country?: string | string[] }) => {\n let flag = lang.flag_country || lang.code\n if (Array.isArray(flag)) {\n flag = flag[0]\n }\n return {\n ...lang,\n value: lang.code,\n flag_country: flag\n }\n }\n )\n\n // Keep only desired Serbian variants\n const filtered: TranslatorLanguage[] = mapped.filter((l) => {\n if (l.code.startsWith('sr')) {\n return l.code === 'sr-latn' || l.code === 'sr-cyrl'\n }\n return true\n })\n\n availableLanguages.value = filtered\n devDebug('[useLangie] Set availableLanguages:', filtered.length)\n\n // Save languages to localStorage with TTL (7 days for languages)\n if (typeof window !== 'undefined') {\n const saved = setCache(LANGUAGES_CACHE_KEY, filtered, 7 * 24 * 60 * 60 * 1000)\n devDebug(\n '[useLangie] Saved languages to cache:',\n saved ? 'success' : 'failed',\n filtered.length\n )\n }\n\n // Auto-select browser language only once if not previously saved\n if (!_autoSelected && !localStorage.getItem('interface_language')) {\n const locale =\n typeof navigator !== 'undefined'\n ? navigator.languages?.[0] || navigator.language || ''\n : ''\n const browserCode = locale.split('-')[0]\n\n if (browserCode) {\n let pick: TranslatorLanguage | undefined = undefined\n\n // Handle Serbian variants\n if (browserCode === 'sr') {\n const isLatin = /latn/i.test(locale) || locale === 'sr'\n const target = isLatin ? 'sr-latn' : 'sr-cyrl'\n pick = mapped.find((l) => l.value === target)\n } else if (browserCode === 'sh') {\n pick =\n mapped.find((l) => l.value === 'sr-latn') ||\n mapped.find((l) => l.code.startsWith('sr'))\n } else {\n // Try exact match first\n pick = mapped.find((l) => l.value === browserCode)\n\n // If no exact match, try prefix match\n if (!pick) {\n pick = mapped.find((l) => l.code.startsWith(browserCode))\n }\n }\n\n if (pick && pick.value) {\n setLanguage(pick.value)\n }\n }\n _autoSelected = true\n }\n _languagesCache = filtered\n _languagesCacheAt = Date.now()\n _languagesPromise = null\n\n applyLocalizedNames(currentLanguage.value)\n\n return filtered\n } catch (error) {\n // const totalDuration = Date.now() - startTime\n devDebug('[useLangie] Language fetch error:', { error })\n return []\n }\n }\n\n // Drop the cached catalogue so the next fetchLanguages() revalidates against the\n // network. Hosts call this on deploy (or a version-change signal) to bust a stale\n // list without waiting out the 7-day TTL.\n const invalidateLanguages = () => {\n _languagesCache = null\n _languagesCacheAt = 0\n _languagesPromise = null\n if (typeof window !== 'undefined') {\n clearCache(LANGUAGES_CACHE_KEY)\n }\n }\n\n const clearTranslations = () => {\n Object.keys(translations).forEach((key) => delete translations[key])\n Object.keys(uiTranslations).forEach((key) => delete uiTranslations[key])\n\n // Clear localStorage cache for translations only (preserve languages cache)\n if (typeof window !== 'undefined') {\n clearCache('translations_cache')\n clearCache('ui_translations_cache')\n }\n }\n\n return {\n availableLanguages,\n translations,\n uiTranslations,\n currentLanguage,\n isLoading,\n setLanguage,\n fetchLanguages,\n invalidateLanguages,\n clearTranslations,\n translatorHost\n }\n}\n","export function devDebug(...args: unknown[]) {\n if (import.meta.env && import.meta.env.DEV) {\n // eslint-disable-next-line no-console\n console.debug(...args)\n }\n}\n","import * as ct from 'countries-and-timezones'\n\n// Get country from multiple sources with fallback\nexport async function getCountryCode(): Promise<string | null> {\n // Try locale first\n const localeCountry = getCountryCodeFromBrowser()\n if (localeCountry) return localeCountry\n\n // Try timezone\n const timezoneCountry = getCountryFromTimezone()\n if (timezoneCountry) return timezoneCountry\n\n // Try IP as last resort\n return await getCountryFromIP()\n}\n\n// Get country from timezone using countries-and-timezones library\nfunction getCountryFromTimezone(): string | null {\n try {\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone\n return getCountryFromTimezoneString(timezone)\n } catch (error) {\n return null\n }\n}\n\n// Helper function to get country code from timezone string\nexport function getCountryFromTimezoneString(timezone: string): string | null {\n try {\n const country = ct.getCountryForTimezone(timezone)\n return country?.id || null\n } catch (error) {\n return null\n }\n}\n\n// Get country from IP (requires external service)\nasync function getCountryFromIP(): Promise<string | null> {\n try {\n const response = await fetch('https://ipapi.co/json/')\n const data = await response.json()\n return data.country_code || null\n } catch (error) {\n return null\n }\n}\n\n// Get user's country code from browser locale\nexport function getCountryCodeFromBrowser(): string | null {\n const langs = navigator.languages || [navigator.language]\n for (const locale of langs) {\n const parts = locale.split('-')\n if (parts.length > 1) {\n return parts[1].toUpperCase()\n }\n }\n return null\n}\n","interface CacheItem<T> {\n data: T\n timestamp: number\n ttl: number\n}\n\ninterface CacheOptions {\n ttl?: number // Time to live in milliseconds\n maxSize?: number // Maximum size in bytes\n maxItems?: number // Maximum number of items\n}\n\nconst DEFAULT_TTL = 7 * 24 * 60 * 60 * 1000 // 7 days\nconst DEFAULT_MAX_SIZE = 2 * 1024 * 1024 // 2MB\nconst DEFAULT_MAX_ITEMS = 1000\n\nexport class CacheManager {\n private options: Required<CacheOptions>\n\n constructor(options: CacheOptions = {}) {\n this.options = {\n ttl: options.ttl || DEFAULT_TTL,\n maxSize: options.maxSize || DEFAULT_MAX_SIZE,\n maxItems: options.maxItems || DEFAULT_MAX_ITEMS\n }\n }\n\n set<T>(key: string, data: T, ttl?: number): boolean {\n if (typeof window === 'undefined') return false\n\n try {\n const item: CacheItem<T> = {\n data,\n timestamp: Date.now(),\n ttl: ttl || this.options.ttl\n }\n\n const serialized = JSON.stringify(item)\n const size = new Blob([serialized]).size\n\n // Check if adding this item would exceed max size\n if (size > this.options.maxSize) {\n console.warn(`[CacheManager] Item size ${size} exceeds max size ${this.options.maxSize}`)\n return false\n }\n\n // Clean up expired items and check total size\n this.cleanup()\n\n // Check if we have space after cleanup\n const currentSize = this.getCurrentSize()\n if (currentSize + size > this.options.maxSize) {\n console.warn(`[CacheManager] Cache would exceed max size after adding item`)\n return false\n }\n\n localStorage.setItem(key, serialized)\n return true\n } catch (error) {\n console.warn(`[CacheManager] Failed to set cache item ${key}:`, error)\n return false\n }\n }\n\n get<T>(key: string): T | null {\n if (typeof window === 'undefined') return null\n\n try {\n const item = localStorage.getItem(key)\n if (!item) return null\n\n const cacheItem: CacheItem<T> = JSON.parse(item)\n const now = Date.now()\n\n // Check if item is expired\n if (now - cacheItem.timestamp > cacheItem.ttl) {\n localStorage.removeItem(key)\n return null\n }\n\n return cacheItem.data\n } catch (error) {\n console.warn(`[CacheManager] Failed to get cache item ${key}:`, error)\n localStorage.removeItem(key) // Remove corrupted item\n return null\n }\n }\n\n remove(key: string): boolean {\n if (typeof window === 'undefined') return false\n\n try {\n localStorage.removeItem(key)\n return true\n } catch (error) {\n console.warn(`[CacheManager] Failed to remove cache item ${key}:`, error)\n return false\n }\n }\n\n clear(pattern?: string): void {\n if (typeof window === 'undefined') return\n\n try {\n if (pattern) {\n // Remove items matching pattern\n Object.keys(localStorage).forEach((key) => {\n if (key.includes(pattern)) {\n localStorage.removeItem(key)\n }\n })\n } else {\n // Remove all langie cache items\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n localStorage.removeItem(key)\n }\n })\n }\n } catch (error) {\n console.warn('[CacheManager] Failed to clear cache:', error)\n }\n }\n\n private cleanup(): void {\n if (typeof window === 'undefined') return\n\n try {\n const now = Date.now()\n const items: Array<{ key: string; size: number; timestamp: number }> = []\n\n // Collect all langie cache items with their sizes and timestamps\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n try {\n const item = localStorage.getItem(key)\n if (item) {\n const cacheItem: CacheItem<any> = JSON.parse(item)\n const size = new Blob([item]).size\n\n // Remove expired items\n if (now - cacheItem.timestamp > cacheItem.ttl) {\n localStorage.removeItem(key)\n return\n }\n\n items.push({\n key,\n size,\n timestamp: cacheItem.timestamp\n })\n }\n } catch (error) {\n // Remove corrupted items\n localStorage.removeItem(key)\n }\n }\n })\n\n // Sort by timestamp (oldest first)\n items.sort((a, b) => a.timestamp - b.timestamp)\n\n // Remove oldest items if we exceed max items\n while (items.length > this.options.maxItems) {\n const oldest = items.shift()\n if (oldest) {\n localStorage.removeItem(oldest.key)\n }\n }\n\n // Remove oldest items if we exceed max size\n let totalSize = items.reduce((sum, item) => sum + item.size, 0)\n while (totalSize > this.options.maxSize && items.length > 0) {\n const oldest = items.shift()\n if (oldest) {\n localStorage.removeItem(oldest.key)\n totalSize -= oldest.size\n }\n }\n } catch (error) {\n console.warn('[CacheManager] Failed to cleanup cache:', error)\n }\n }\n\n private getCurrentSize(): number {\n if (typeof window === 'undefined') return 0\n\n try {\n let totalSize = 0\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n const item = localStorage.getItem(key)\n if (item) {\n totalSize += new Blob([item]).size\n }\n }\n })\n return totalSize\n } catch (error) {\n console.warn('[CacheManager] Failed to calculate cache size:', error)\n return 0\n }\n }\n\n getStats(): { size: number; items: number; maxSize: number; maxItems: number } {\n if (typeof window === 'undefined') {\n return { size: 0, items: 0, maxSize: this.options.maxSize, maxItems: this.options.maxItems }\n }\n\n try {\n let totalSize = 0\n let itemCount = 0\n\n Object.keys(localStorage).forEach((key) => {\n if (key.startsWith('langie_')) {\n const item = localStorage.getItem(key)\n if (item) {\n totalSize += new Blob([item]).size\n itemCount++\n }\n }\n })\n\n return {\n size: totalSize,\n items: itemCount,\n maxSize: this.options.maxSize,\n maxItems: this.options.maxItems\n }\n } catch (error) {\n console.warn('[CacheManager] Failed to get cache stats:', error)\n return { size: 0, items: 0, maxSize: this.options.maxSize, maxItems: this.options.maxItems }\n }\n }\n}\n\n// Default cache manager instance\nexport const cacheManager = new CacheManager()\n\n// Convenience functions\nexport const setCache = <T>(key: string, data: T, ttl?: number): boolean => {\n return cacheManager.set(key, data, ttl)\n}\n\nexport const getCache = <T>(key: string): T | null => {\n return cacheManager.get<T>(key)\n}\n\nexport const removeCache = (key: string): boolean => {\n return cacheManager.remove(key)\n}\n\nexport const clearCache = (pattern?: string): void => {\n return cacheManager.clear(pattern)\n}\n\nexport const getCacheStats = () => {\n return cacheManager.getStats()\n}\n","import type { TranslatorLanguage, TranslatorOptions } from '../types'\nimport { translateBatch } from '../core'\nimport { API_FIELD_TEXT, API_FIELD_FROM, API_FIELD_TO, API_FIELD_CTX } from '../constants'\nimport { getCache, setCache } from './cache'\nimport { devDebug } from './debug'\n\nconst CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000\nconst NAME_CTX = 'language name'\n\ntype NameMap = Record<string, string>\n\n// Translate the distinct English language names into `targetLang`, returning a\n// name → translation map. translateBatch preserves input order, so results map\n// back by index.\nasync function translateNames(\n names: string[],\n targetLang: string,\n options: TranslatorOptions\n): Promise<NameMap | null> {\n const requests = names.map((name) => ({\n [API_FIELD_TEXT]: name,\n [API_FIELD_FROM]: 'en',\n [API_FIELD_TO]: targetLang,\n [API_FIELD_CTX]: NAME_CTX\n }))\n try {\n const results = await translateBatch(requests, options)\n const map: NameMap = {}\n names.forEach((name, i) => {\n const translated = results[i]?.[API_FIELD_TEXT]\n if (translated) map[name] = translated\n })\n return map\n } catch (error: unknown) {\n devDebug('[localizeLanguageNames] translate failed:', error)\n return null\n }\n}\n\n/**\n * Attach `search_alias` — each language's name in the current interface language —\n * so the picker's fuzzy search matches names typed in the user's own language and\n * script (e.g. Cyrillic \"браз\" → Brazilian). English is a no-op: `name` already is\n * the primary search field. Cached per interface language (7-day TTL). Returns the\n * same array reference unchanged on no-op / failure so callers can skip reassigning.\n */\nexport async function localizeLanguageNames(\n languages: TranslatorLanguage[],\n targetLang: string,\n options: TranslatorOptions = {}\n): Promise<TranslatorLanguage[]> {\n const to = (targetLang || '').toLowerCase()\n if (!to || to === 'en' || languages.length === 0) return languages\n\n const cacheKey = `langie_langnames_${to}`\n let map = getCache<NameMap>(cacheKey)\n if (!map) {\n const names = [...new Set(languages.map((l) => l.name).filter(Boolean))]\n map = await translateNames(names, to, options)\n if (map && Object.keys(map).length) setCache(cacheKey, map, CACHE_TTL_MS)\n }\n if (!map) return languages\n\n const resolved = map\n return languages.map((l) => ({ ...l, search_alias: resolved[l.name] || l.search_alias }))\n}\n","import type { TranslateServiceResponse } from '../types'\nimport { devDebug } from '../utils/debug'\nimport {\n API_FIELD_TEXT,\n API_FIELD_FROM,\n API_FIELD_TO,\n API_FIELD_CTX,\n API_FIELD_TRANSLATIONS,\n API_FIELD_ERROR,\n API_FIELD_TURNSTILE\n} from '../constants'\n\nexport interface BatchingOptions {\n initialBatchDelay?: number\n followupBatchDelay?: number\n maxBatchSize?: number\n maxWaitTime?: number\n /**\n * Supplies a fresh Cloudflare Turnstile token per batch request. Required by the\n * keyless `/frontend/translate` proxy when Turnstile is enabled server-side.\n * Single-use tokens, so it is invoked once per outgoing request.\n */\n getTurnstileToken?: () => string | Promise<string>\n}\n\nexport interface BatchRequest {\n [API_FIELD_TEXT]: string\n [API_FIELD_CTX]: string\n [API_FIELD_FROM]: string\n [API_FIELD_TO]: string\n cacheKey: string\n __explicitToLang?: boolean\n}\n\nexport class TranslationBatching {\n private pendingRequests = new Set<string>()\n private queueMap = new Map<\n string,\n Map<string, { [API_FIELD_TEXT]: string; [API_FIELD_CTX]: string; __explicitToLang?: boolean }>\n >()\n private flushTimeout: NodeJS.Timeout | null = null\n private queuedThisTick = new Set<string>()\n private clearQueuedThisTickScheduled = false\n private firstItemTime: number | null = null\n\n constructor(\n private options: BatchingOptions = {},\n private translatorHost: string,\n private currentLanguage: () => string,\n private onBatchComplete: (results: TranslateServiceResponse[], requests: BatchRequest[]) => void\n ) {}\n\n private get initialBatchDelay() {\n return this.options.initialBatchDelay ?? 50\n }\n\n private get followupBatchDelay() {\n return this.options.followupBatchDelay ?? 10\n }\n\n private get maxBatchSize() {\n return this.options.maxBatchSize ?? 50\n }\n\n private get maxWaitTime() {\n return this.options.maxWaitTime ?? 1000\n }\n\n private scheduleClearQueuedThisTick() {\n if (this.clearQueuedThisTickScheduled) return\n this.clearQueuedThisTickScheduled = true\n queueMicrotask(() => {\n this.queuedThisTick.clear()\n this.clearQueuedThisTickScheduled = false\n })\n }\n\n private flushQueues = async () => {\n const allRequests: BatchRequest[] = []\n for (const [batchKey, map] of Array.from(this.queueMap.entries())) {\n if (!map || map.size === 0) {\n this.queueMap.delete(batchKey)\n continue\n }\n const [from, to] = batchKey.split('|')\n for (const [cacheKey, item] of map.entries()) {\n allRequests.push({\n [API_FIELD_TEXT]: item[API_FIELD_TEXT],\n [API_FIELD_CTX]: item[API_FIELD_CTX],\n [API_FIELD_FROM]: from,\n [API_FIELD_TO]: to,\n cacheKey,\n __explicitToLang: item.__explicitToLang\n })\n }\n this.queueMap.delete(batchKey)\n }\n\n if (allRequests.length > 0) {\n // Only log if there are more than 1 request to reduce noise\n // devDebug('[TranslationBatching] Sending batch:', allRequests.length, 'translation items')\n devDebug(\n '[TranslationBatching] Sending batch:',\n allRequests.length,\n 'translation items',\n allRequests\n )\n\n // Split large batches into smaller chunks\n const chunks = this.chunkArray(allRequests, this.maxBatchSize)\n\n for (const chunk of chunks) {\n try {\n await this.fetchAndCacheBatchMixed(chunk)\n } catch (error) {\n devDebug('[TranslationBatching] Batch translation error:', error)\n chunk.forEach((req) => this.pendingRequests.delete(req.cacheKey))\n }\n }\n }\n\n // Reset the first item time after flushing\n this.firstItemTime = null\n }\n\n private chunkArray<T>(array: T[], size: number): T[][] {\n const chunks: T[][] = []\n for (let i = 0; i < array.length; i += size) {\n chunks.push(array.slice(i, i + size))\n }\n return chunks\n }\n\n private scheduleFlush = () => {\n if (this.flushTimeout) {\n clearTimeout(this.flushTimeout)\n }\n\n // Calculate total items across all batches\n let totalItems = 0\n for (const map of this.queueMap.values()) {\n totalItems += map.size\n }\n\n // Check if we've exceeded maximum wait time\n if (this.firstItemTime && Date.now() - this.firstItemTime >= this.maxWaitTime) {\n devDebug('[TranslationBatching] Flushing due to maximum wait time:', totalItems, 'items')\n this.flushQueues()\n return\n }\n\n const delay = this.queueMap.size === 1 ? this.initialBatchDelay : this.followupBatchDelay\n devDebug(\n '[TranslationBatching] Scheduling flush in',\n delay,\n 'ms',\n Array.from(this.queueMap.entries())\n )\n this.flushTimeout = setTimeout(() => {\n this.flushQueues()\n this.flushTimeout = null\n }, delay)\n }\n\n public queueTranslation(\n text: string,\n ctx: string,\n from: string,\n to: string,\n cacheKey: string,\n explicitToLang?: boolean\n ) {\n if (this.pendingRequests.has(cacheKey) || this.queuedThisTick.has(cacheKey)) {\n // devDebug('[TranslationBatching] Skipping duplicate:', cacheKey)\n devDebug('[TranslationBatching] Skipping duplicate:', cacheKey)\n return\n }\n\n // Track when the first item was queued\n if (this.firstItemTime === null) {\n this.firstItemTime = Date.now()\n }\n\n this.queuedThisTick.add(cacheKey)\n this.scheduleClearQueuedThisTick()\n this.pendingRequests.add(cacheKey)\n\n const batchKey = `${from}|${to}`\n if (!this.queueMap.has(batchKey)) {\n this.queueMap.set(batchKey, new Map())\n }\n\n this.queueMap.get(batchKey)!.set(cacheKey, {\n [API_FIELD_TEXT]: text,\n [API_FIELD_CTX]: ctx,\n __explicitToLang: explicitToLang\n })\n // devDebug('[TranslationBatching] Queued translation:', { text, ctx, from, to, cacheKey, batchKey })\n devDebug('[TranslationBatching] Queued translation:', {\n text,\n ctx,\n from,\n to,\n cacheKey,\n batchKey,\n explicitToLang\n })\n this.scheduleFlush()\n }\n\n private async fetchAndCacheBatchMixed(requests: BatchRequest[]) {\n const grouped: { [key: string]: BatchRequest[] } = {}\n requests.forEach((req) => {\n const key = `${req.from}|${req.to}`\n if (!grouped[key]) grouped[key] = []\n grouped[key].push(req)\n })\n\n const allResults: TranslateServiceResponse[] = []\n const allRequests: BatchRequest[] = []\n for (const [langPair, batchRequests] of Object.entries(grouped)) {\n const [from, to] = langPair.split('|')\n\n try {\n // Check if all requests have the same context\n const contexts = [...new Set(batchRequests.map((req) => req[API_FIELD_CTX]))]\n const useGlobalContext = contexts.length === 1 && contexts[0] === 'ui'\n\n // devDebug('[TranslationBatching] Sending batch for', langPair, 'with', batchRequests.length, 'items')\n devDebug(\n '[TranslationBatching] Sending batch for',\n langPair,\n 'with',\n batchRequests.length,\n 'items',\n batchRequests\n )\n\n const buildBody = (turnstileToken?: string) =>\n JSON.stringify({\n translations: batchRequests.map((req) => ({\n [API_FIELD_TEXT]: req[API_FIELD_TEXT],\n ...(useGlobalContext ? {} : { [API_FIELD_CTX]: req[API_FIELD_CTX] })\n })),\n [API_FIELD_FROM]: from,\n [API_FIELD_TO]: to,\n ...(useGlobalContext ? { [API_FIELD_CTX]: 'ui' } : {}),\n ...(turnstileToken ? { [API_FIELD_TURNSTILE]: turnstileToken } : {})\n })\n\n const postTranslate = (turnstileToken?: string) =>\n fetch(`${this.translatorHost}/translate`, {\n method: 'POST',\n // Carry the /frontend session cookie the proxy issues after one\n // Turnstile check, so we don't solve a challenge on every request.\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: buildBody(turnstileToken)\n })\n\n // Ride the session cookie first; only solve a fresh single-use Turnstile\n // challenge when the keyless /frontend proxy rejects for a missing token.\n // Session-aware backends answer 401; older ones 400 — accept both so the\n // demo works against either, making the backend/SDK deploy order irrelevant.\n let response = await postTranslate()\n if (\n (response.status === 401 || response.status === 400) &&\n this.options.getTurnstileToken\n ) {\n const turnstileToken = await this.options.getTurnstileToken()\n response = await postTranslate(turnstileToken)\n }\n\n let result\n try {\n result = await response.json()\n } catch (parseError) {\n devDebug('[TranslationBatching] Failed to parse response as JSON:', parseError)\n throw new Error(`Translation request failed: ${response.status}`)\n }\n\n // Handle HTTP errors by checking if the response contains an error message\n if (!response.ok) {\n devDebug(\n '[TranslationBatching] Translation request failed:',\n response.status,\n response.statusText\n )\n\n // If the response contains an error message, use it\n if (result && result[API_FIELD_ERROR]) {\n devDebug(\n '[TranslationBatching] HTTP error with API error message:',\n result[API_FIELD_ERROR]\n )\n\n // Create error responses for all requests in this batch\n const errorResponses = batchRequests.map((req) => ({\n [API_FIELD_TEXT]: req[API_FIELD_TEXT],\n [API_FIELD_ERROR]: result[API_FIELD_ERROR]\n }))\n\n // Add error responses to results\n allResults.push({ [API_FIELD_TRANSLATIONS]: errorResponses })\n allRequests.push(...batchRequests)\n\n // Clear pending requests for this batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n\n // Continue to onBatchComplete to record errors\n this.onBatchComplete(allResults, allRequests)\n return\n }\n\n throw new Error(`Translation request failed: ${response.status}`)\n }\n\n // Handle top-level error responses\n if (result[API_FIELD_ERROR]) {\n devDebug('[TranslationBatching] Top-level API error:', result[API_FIELD_ERROR])\n\n // Create error responses for all requests in this batch\n const errorResponses = batchRequests.map((req) => ({\n [API_FIELD_TEXT]: req[API_FIELD_TEXT],\n [API_FIELD_ERROR]: result[API_FIELD_ERROR]\n }))\n\n // Add error responses to results\n allResults.push({ [API_FIELD_TRANSLATIONS]: errorResponses })\n allRequests.push(...batchRequests)\n\n // Clear pending requests for this batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n\n // Continue to onBatchComplete to record errors\n } else {\n // Handle error responses in the result\n if (result[API_FIELD_TRANSLATIONS]) {\n result[API_FIELD_TRANSLATIONS].forEach((translation: any, index: number) => {\n if (translation[API_FIELD_ERROR]) {\n const originalText = batchRequests[index]?.[API_FIELD_TEXT]\n devDebug(\n '[TranslationBatching] Translation error for',\n originalText,\n ':',\n translation[API_FIELD_ERROR]\n )\n }\n })\n }\n\n allResults.push(result)\n allRequests.push(...batchRequests)\n\n // Clear pending requests for this batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n }\n } catch (error) {\n devDebug('[TranslationBatching] Batch request failed for', langPair, ':', error)\n\n // Clear pending requests for failed batch\n batchRequests.forEach((req) => {\n this.pendingRequests.delete(req.cacheKey)\n })\n\n // Re-throw to be handled by the caller\n throw error\n }\n }\n\n this.onBatchComplete(allResults, allRequests)\n }\n\n public clearPending(cacheKey: string) {\n this.pendingRequests.delete(cacheKey)\n }\n\n public clearAllPending() {\n this.pendingRequests.clear()\n }\n\n public cleanup() {\n this.clearAllPending()\n this.queueMap.clear()\n this.queuedThisTick.clear()\n if (this.flushTimeout) {\n clearTimeout(this.flushTimeout)\n this.flushTimeout = null\n }\n this.clearQueuedThisTickScheduled = false\n this.firstItemTime = null\n }\n\n public getStats() {\n return {\n pendingRequests: this.pendingRequests.size,\n queuedBatches: this.queueMap.size,\n queuedThisTick: this.queuedThisTick.size,\n hasFlushTimeout: !!this.flushTimeout\n }\n }\n}\n","import script from \"/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue?type=script\"\nexport * from \"/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue?type=script\"\n\nimport \"/builds/codelits/langie-sdk/src/components/InterfaceLanguageSelect.vue?type=style&index=0\"\nexport default script\nscript.__scopeId = \"data-v-258d337a\"","<template>\n <transition name=\"fade\" mode=\"out-in\">\n <span :key=\"translated\">{{ translated }}</span>\n </transition>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, useSlots, watch } from 'vue'\nimport { ref, nextTick } from 'vue'\nimport { useLangie } from '../useLangie'\n\n// Define component name for better debugging\n// Component name for Vue devtools\n// Note: defineOptions requires Vue 3.3+, but we support Vue 3.2+\n// The component will work without explicit name\n\n// Detect if we're running in Nuxt\nconst isNuxt = computed(() => {\n if (typeof window !== 'undefined') {\n return !!(window as any).__NUXT__\n }\n if (typeof process !== 'undefined') {\n return !!(process.env as any).NUXT_SSR_BASE || !!(process.env as any).NUXT_PUBLIC_BASE_URL\n }\n return false\n})\n\nconst props = defineProps({\n // Message key (optional, otherwise slot content is used)\n msg: {\n type: String,\n default: undefined\n },\n // Translation context shorthand\n ctx: {\n type: String,\n required: false,\n default: 'ui'\n },\n // Original language shorthand\n orig: {\n type: String,\n required: false,\n default: undefined\n }\n})\n\nconst slots = useSlots()\nconst { lr, peekTranslation, currentLanguage, uiTranslations, translations, getLtDefaults } =\n useLangie()\n\nconst keyStr = computed(() => {\n if (props.msg) return props.msg\n const slotContent = slots.default\n ? slots\n .default()\n .map((n) => n.children)\n .join('')\n : ''\n return (slotContent || '').trim()\n})\n\n// Force component update when translations change\nconst forceUpdate = ref(0)\nwatch(\n [uiTranslations, translations],\n () => {\n // Small delay to ensure translations are cached before updating\n nextTick(() => {\n forceUpdate.value++\n })\n },\n { deep: true }\n)\n\nconst translated = computed(() => {\n // Get global defaults\n const globalDefaults = getLtDefaults()\n\n // Use props or fall back to global defaults\n const effectiveCtx = props.ctx ?? globalDefaults.ctx\n const effectiveOrig = props.orig ?? globalDefaults.orig\n\n // On the server emit a seeded translation when the host pre-populated one (no\n // English flash, no CLS); on a cold miss render the key (invisible reserver,\n // fade-in after mount). peekTranslation never queues — a doomed SSR request is\n // pointless. The client seeds the same map, so hydration matches on hits.\n if (isNuxt.value && typeof window === 'undefined') {\n return peekTranslation(keyStr.value, effectiveCtx)\n }\n\n // Force reactivity by depending on currentLanguage and translation caches\n void currentLanguage.value\n void forceUpdate.value // Force recomputation when translations change\n // Access properties to create reactive dependencies\n const cacheKey = `${keyStr.value}|${effectiveCtx}`\n const cache = effectiveCtx === 'ui' ? uiTranslations : translations\n void cache[cacheKey] // This creates a reactive dependency\n\n // For other frameworks, always translate\n const result = lr(keyStr.value, effectiveCtx, effectiveOrig)\n return result\n})\n</script>\n\n<style scoped>\n.fade-enter-active,\n.fade-leave-active {\n transition: opacity 0.25s ease;\n}\n.fade-enter-from,\n.fade-leave-to {\n opacity: 0;\n}\n</style>\n","import script from \"/builds/codelits/langie-sdk/src/components/lt.vue?type=script\"\nexport * from \"/builds/codelits/langie-sdk/src/components/lt.vue?type=script\"\n\nimport \"/builds/codelits/langie-sdk/src/components/lt.vue?type=style&index=0\"\nexport default script\nscript.__scopeId = \"data-v-3341698b\""],"mappings":"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","names":["InterfaceLanguageSelect_default","LanguageSelect_default","lt_default","import_vue","Fuse","_createElementBlock","_normalizeClass","_createCommentVNode","_createBlock","_unref","Multiselect","_withCtx","_createElementVNode","_toDisplayString","_Fragment","LanguageSelect_default","import_vue","import_vue","translations","message","import_vue","currentLanguage","availableLanguages","translations","uiTranslations","currentLanguage","LANGUAGES_CACHE_KEY","reactive","availableLanguages","currentLanguage","_createElementBlock","_hoisted_1","_createBlock","LanguageSelect_default","_createCommentVNode","_normalizeClass","_createElementVNode","_hoisted_2","_toDisplayString","_unref","InterfaceLanguageSelect_default","import_vue","currentLanguage","uiTranslations","translations","_createBlock","_Transition","_createElementBlock","_toDisplayString","lt_default"]}