From 7399c0d460ea6201f00401541d78a913503ea879 Mon Sep 17 00:00:00 2001 From: ArTimnak Date: Sat, 4 Jul 2026 17:36:08 +0330 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20add=20Persian=20(=D9=81=D8=A7?= =?UTF-8?q?=D8=B1=D8=B3=DB=8C)=20language=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/i18n/I18nProvider.tsx | 5 +- client/src/i18n/locales/fa.json | 471 +++++++++++++++++++++++++++++++ 2 files changed, 475 insertions(+), 1 deletion(-) create mode 100644 client/src/i18n/locales/fa.json diff --git a/client/src/i18n/I18nProvider.tsx b/client/src/i18n/I18nProvider.tsx index f231403f2..6ebf9e8b8 100644 --- a/client/src/i18n/I18nProvider.tsx +++ b/client/src/i18n/I18nProvider.tsx @@ -30,8 +30,9 @@ import fr from './locales/fr.json' import es from './locales/es.json' import ptBR from './locales/pt-BR.json' import it from './locales/it.json' +import fa from './locales/fa.json' -export const SUPPORTED_LOCALES = ['en', 'zh-CN', 'fr', 'es', 'pt-BR', 'it'] as const +export const SUPPORTED_LOCALES = ['en', 'zh-CN', 'fr', 'es', 'pt-BR', 'it', 'fa'] as const export type Locale = (typeof SUPPORTED_LOCALES)[number] export const DEFAULT_LOCALE: Locale = 'en' @@ -55,6 +56,7 @@ function detectLocale(): Locale { if (lower.startsWith('fr')) return 'fr' if (lower.startsWith('es')) return 'es' if (lower.startsWith('it')) return 'it' + if (lower.startsWith('fa')) return 'fa' if (lower.startsWith('en')) return 'en' return DEFAULT_LOCALE } @@ -68,6 +70,7 @@ const dictionaries: Record = { es: es as Dictionary, 'pt-BR': ptBR as Dictionary, it: it as Dictionary, + fa: fa as Dictionary, } function lookup(dict: Dictionary, key: string): unknown { diff --git a/client/src/i18n/locales/fa.json b/client/src/i18n/locales/fa.json new file mode 100644 index 000000000..ea5f2a1c6 --- /dev/null +++ b/client/src/i18n/locales/fa.json @@ -0,0 +1,471 @@ +{ +"nav": { +"models": "مدل‌ها", +"playground": "محیط آزمایش", +"keys": "کلیدها", +"analytics": "تحلیل‌ها", +"premium": "پریمیوم", +"signOut": "خروج", +"openMenu": "باز کردن منوی ناوبری", +"theme": "پوسته", +"switchLight": "تغییر به پوسته روشن", +"switchDark": "تغییر به پوسته تیره", +"language": "تغییر زبان", +"switchToChinese": "تغییر به چینی", +"switchToEnglish": "تغییر به انگلیسی" +}, +"auth": { +"createYourAccount": "حساب خود را ایجاد کنید", +"signIn": "ورود", +"email": "ایمیل", +"password": "گذرواژه", +"emailPlaceholder": "[you@example.com](mailto:you@example.com)", +"passwordPlaceholderSetup": "حداقل ۸ نویسه", +"passwordPlaceholderLogin": "گذرواژهٔ شما", +"setupDescription": "ایمیل و گذرواژه‌ای را تنظیم کنید که از این داشبورد محافظت خواهد کرد.", +"loginDescription": "برای مدیریت کلیدها، مسیریابی و تحلیل‌ها وارد شوید.", +"createAccount": "ایجاد حساب", +"creating": "در حال ایجاد…", +"signingIn": "در حال ورود…", +"loading": "در حال بارگذاری…", +"newPasswordAutoComplete": "new-password", +"currentPasswordAutoComplete": "current-password", +"serverUnreachableBefore": "نمی‌توان به سرور دسترسی داشت. مطمئن شوید بخش پشتی در حال اجراست (", +"serverUnreachableAfter": ")." +}, +"common": { +"save": "ذخیره", +"saving": "در حال ذخیره…", +"cancel": "لغو", +"discard": "رد کردن", +"delete": "حذف", +"confirm": "تأیید", +"copy": "کپی", +"copied": "کپی شد", +"show": "نمایش", +"hide": "پنهان کردن", +"apply": "اعمال", +"applied": "اعمال شد", +"applying": "در حال اعمال…", +"active": "فعال", +"inactive": "غیرفعال", +"never": "هرگز", +"loading": "در حال بارگذاری…", +"error": "خطا", +"noData": "هنوز داده‌ای نیست", +"unsavedChanges": "تغییرات ذخیره‌نشده", +"saveChanges": "ذخیرهٔ تغییرات", +"check": "بررسی", +"remove": "حذف", +"unknownError": "خطای نامشخص", +"model": "مدل", +"provider": "ارائه‌دهنده", +"success": "موفق", +"failures": "شکست‌ها" +}, +"models": { +"title": "مدل‌ها", +"chatModelsTab": "مدل‌های چت", +"fusionTab": "فیوژن", +"embeddingsTab": "امبدینگ‌ها", +"imageTab": "تصویر", +"audioTab": "صوت", +"imageTitle": "مدل‌های تصویر", +"audioTitle": "مدل‌های صوت", +"imageDesc": "مدل‌های تولید متن به تصویر.", +"audioDesc": "مدل‌های تولید متن به گفتار.", +"mediaHint": "تولید از طریق", +"mediaEmpty": "هنوز مدلی نیست — از کاتالوگ همگام می‌شوند.", +"newBadge": "جدید", +"monthlyTokenBudget": "سقف ماهانهٔ توکن", +"remaining": "باقی‌مانده", +"used": "مصرف‌شده", +"of": "از", +"showAllModels": "نمایش همهٔ {count} مدل", +"showLess": "نمایش کمتر", +"vision": "بینایی", +"visionTitle": "ورودی تصویر را می‌پذیرد", +"tools": "ابزارها", +"toolsTitle": "فراخوانی‌های ساختاریافتهٔ ابزار را تولید می‌کند، بنابراین برای درخواست‌های دارای ابزار مناسب است", +"penalty": "جریمهٔ −{value}", +"obs": "{count} مشاهده", +"tokPerMonth": "{count} توکن/ماه", +"rpmLimit": "{count} درخواست/دقیقه", +"rpdLimit": "{count} درخواست/روز", +"noKey": "بدون کلید", +"dragToReorder": "برای تغییر ترتیب بکشید", +"dragToReorderGroup": "برای تغییر ترتیب مدل بکشید", +"providerCount": "{count} ارائه‌دهنده", +"servedBy": "ارائه‌شده توسط {providers}", +"viewProviders": "مشاهدهٔ ارائه‌دهندگان", +"backToModels": "بازگشت به مدل‌ها", +"providersHeading": "ارائه‌دهندگانی که این مدل را سرویس می‌کنند", +"codeSnippetHeading": "استفاده از این مدل", +"modelNotFound": "این مدل در دسترس نیست، یا هیچ ارائه‌دهندهٔ پیکربندی‌شده‌ای ندارد.", +"providerIdsHeading": "شناسه‌های مدل ارائه‌دهنده", +"providerIdsHint": "شناسهٔ یکپارچهٔ مدل را بفرستید تا بین همهٔ ارائه‌دهندگان سوییچ شود، یا یک شناسهٔ مخصوصِ ارائه‌دهنده را بفرستید تا روی همان ارائه‌دهنده ثابت بماند.", +"copyModelName": "کپی نام مدل", +"settingsHeading": "تنظیمات ارائه‌دهنده", +"settingsHint": "ویرایش‌های محلیِ مدل‌های کاتالوگ در همگام‌سازی‌های کاتالوگ حفظ می‌شوند. مدل‌های حذف‌شدهٔ کاتالوگ تا زمانی که دوباره از طریق پیکربندی اضافه‌شان کنید حذف‌شده باقی می‌مانند.", + "catalogModel": "کاتالوگ", +"customModel": "سفارشی", +"localOverride": "بازنویسی محلی", +"displayName": "نام نمایشی", +"contextWindow": "زمینه", +"inFallback": "در زنجیره", +"saveModelSettings": "ذخیرهٔ تنظیمات مدل", +"aggregateBudget": "{count}/ماه", +"aggregateBudgetTitle": "مجموع توکن‌های رایگان ماهانه در میان ارائه‌دهندگان این مدل", +"rateRpm": "{count} RPM", +"rateRpd": "{count} RPD", +"rateTitle": "دارای محدودیت نرخ — بدون سقف ثابت توکن ماهانه", +"unifyToggle": "یکپارچه‌سازی مدل‌های تکراری", +"unifyToggleHint": "مدلی را که توسط چند ارائه‌دهنده سرویس می‌شود به‌صورت یک مورد نشان دهید و هنگام انتخاب، بین ارائه‌دهندگانش سوییچ کنید.", +"columnModel": "مدل", +"columnOn": "روشن", +"noModelsBefore": "مدلی در دسترس نیست. ابتدا کلیدهای API را در ", +"keysPageLink": "صفحهٔ کلیدها", +"noModelsAfter": " اضافه کنید.", +"hiddenNoKeys": "پنهان (بدون کلید): {platforms}", +"searchPlaceholder": "جست‌وجوی مدل‌ها یا ارائه‌دهندگان…", +"clearSearch": "پاک کردن جست‌وجو", +"ctxAny": "هر اندازهٔ زمینه", +"ctxBadge": "{size} زمینه", +"ctxTitle": "پنجرهٔ زمینه", +"copyModelId": "کپی شناسهٔ مدل", +"showingCount": "نمایش {shown} از {total} مدل", +"clearFilters": "پاک کردن فیلترها", +"noMatches": "هیچ مدلی با فیلترهای شما مطابقت ندارد." +}, +"strategies": { +"title": "راهبرد مسیریابی", +"description": "یک راهبرد مسیریابی انتخاب کنید. در حالت دستی، ترتیب را با کشیدن تعیین می‌کنید؛ سایر راهبردها بر اساس امتیاز زنده در میان قابلیت اطمینان، سرعت و هوشمندی مسیریابی می‌کنند.", +"weightsSummary": "قابلیت اطمینان {reliability}% · سرعت {speed}% · هوشمندی {intelligence}%", +"guardrails": "گاردریل‌ها", +"guardrailsTooltip": "گاردریل‌های همواره فعال: فضای آزاد سهمیه × جریمهٔ زندهٔ محدودیت نرخ. کمتر از 1.0 یعنی مدل در حال عقب نگه‌داشته شدن است.", +"scoreTooltip": "امتیاز نهایی مسیریابی = میانگین وزنی سه محور، ضرب در گاردریل‌ها. امتیاز بالاتر زودتر مسیریابی می‌شود.", + "modeManualHint": "حالت دستی: درخواست‌ها از بالا به پایین، طبق ترتیب زیر پیش می‌روند. برای تغییر ترتیب بکشید.", +"modeScoreHint": "امتیازها بر اساس ترافیک زنده به‌روزرسانی می‌شوند. ترتیب زیر همان مسیریابی فعلی درخواست‌هاست.", +"manual": "دستی", +"manualBlurb": "دقیقاً به ترتیبی که در پایین تنظیم می‌کنید مسیریابی کنید. برای تغییر ترتیب، دستگیره‌ها را بکشید. بدون امتیازدهی؛ زنجیره از بالا به پایین دنبال می‌شود.", +"balanced": "متوازن", +"balancedBlurb": "قابلیت اطمینان در اولویت است (۵۰٪)، و سرعت و هوشمندی به‌طور برابر وزن می‌گیرند (هر کدام ۲۵٪). یک پیش‌فرض متعادل و همه‌کاره.", +"smartest": "باهوش‌ترین", +"smartestBlurb": "مدلی را ترجیح دهید که بیشترین توانایی را دارد و همچنان کار می‌کند. هوشمندی ۵۵٪، قابلیت اطمینان ۳۵٪، سرعت ۱۰٪.", +"fastest": "سریع‌ترین", +"fastestBlurb": "مدلی را ترجیح دهید که سریع‌تر است و همچنان کار می‌کند. سرعت ۵۵٪، قابلیت اطمینان ۳۵٪، هوشمندی ۱۰٪.", +"reliable": "قابل‌اعتمادترین", +"reliableBlurb": "موفقیت را بیش از هر چیز دیگری بهینه کنید. قابلیت اطمینان ۷۰٪، سرعت و هوشمندی هر کدام ۱۵٪.", +"custom": "سفارشی", +"customBlurb": "تعادل دلخواه خودتان را میان قابلیت اطمینان، سرعت و هوشمندی با اسلایدرها تنظیم کنید. همان موتورِ پیش‌فرض‌هاست، فقط با وزن‌های شما.", +"adjust": "تنظیم", +"customWeights": "وزن‌های سفارشی", +"customWeightsHelp": "اسلایدرها مستقل‌اند؛ سهم‌ها به‌صورت خودکار تا ۱۰۰٪ متعادل می‌شوند.", +"weightReliability": "قابلیت اطمینان", +"weightSpeed": "سرعت", +"weightIntelligence": "هوشمندی", +"weightRequired": "حداقل یکی از وزن‌ها باید بزرگ‌تر از صفر باشد.", +"scoreColumn": "امتیاز" +}, +"penaltyInspector": { +"title": "فشار مسیریاب", +"subtitle": "جریمه‌ها، دوره‌های cooldown و خطاهای {minutes} دقیقهٔ گذشته", +"rowCount": "{count} فعال", +"offChain": "خارج از زنجیره", +"penaltyValue": "جریمهٔ {value}", +"factor": "امتیاز ×{factor}", +"noCooldown": "بدون cooldown", +"cooldownChip": "{key} - {time}", +"errorsHeading": "{count} خطای اخیر", +"noRecentErrors": "هیچ خطای اخیر وجود ندارد", +"noKey": "بدون کلید", +"reasons": { +"penalty": "جریمه‌شده", +"cooldown": "cooldown", +"recent_errors": "ناموفق" +} +}, +"keys": { +"pageTitle": "کلیدها", +"pageDescription": "اعتبارنامه‌های ارائه‌دهنده و کلید API یکپارچه‌ای که برنامه‌های شما با آن متصل می‌شوند.", +"tabProviders": "ارائه‌دهندگان", +"tabQuotaSignals": "سیگنال‌های سهمیه", +"tabApiKey": "کلید API یکپارچه", +"tabAnthropic": "Anthropic", +"unifiedKey": "کلید API یکپارچهٔ شما", +"regenerate": "تولید مجدد", +"showKey": "نمایش", +"hideKey": "پنهان کردن", +"copyKey": "کپی", +"copiedKey": "کپی شد", +"baseUrl": "نشانی پایه", +"endpointChat": "چت", +"endpointResponses": "پاسخ‌ها", +"endpointEmbeddings": "امبدینگ‌ها", +"endpointEmbeddingsHint": "model: \"auto\" یا یک خانواده از زبانهٔ امبدینگ‌ها", + "endpointMessages": "پیام‌ها", +"endpointMessagesHint": "سازگار با Anthropic (Claude)", +"anthropicTitle": "مدل‌های Claude (Anthropic)", +"anthropicDesc": "یک کلاینت Claude یا Anthropic SDK را به این سرور متصل کنید. کلاینت‌های Anthropic نام مدل‌های Claude را می‌فرستند — هر کدام را به Auto (مسیریاب یک مدل رایگان را انتخاب می‌کند) نگاشت کنید یا یک مورد مشخص را ثابت کنید.", +"anthropicBaseUrl": "نشانی پایه", +"anthropicAuth": "هدر احراز هویت", +"anthropicAuto": "Auto — مسیریاب بهترین مدل را انتخاب می‌کند", +"anthropicSave": "ذخیرهٔ نگاشت", +"anthropicSaved": "ذخیره شد", +"anthropicNote": "کلاینت‌های Anthropic نام‌های داخلی Claude را نگه می‌دارند؛ نگاشت بالا تعیین می‌کند هر کدام چگونه به مجموعهٔ شما مسیریابی شوند.", +"familyDefault": "پیش‌فرض", +"familyOpus": "Opus", +"familySonnet": "Sonnet", +"familyHaiku": "Haiku", +"selectPlatform": "یک ارائه‌دهنده انتخاب کنید", +"addKey": "افزودن کلید", +"adding": "در حال افزودن…", +"selectProvider": "یک ارائه‌دهنده انتخاب کنید…", +"accountId": "شناسهٔ حساب", +"label": "برچسب", +"noKeyNeeded": "(نیازی به کلید نیست)", +"outboundProxy": "پروکسی خروجی", +"outboundProxyDescription": "درخواست‌های خروجی LLM را از طریق پروکسی مسیریابی کنید. از SOCKS5، HTTP و HTTPS پشتیبانی می‌کند.", +"proxyUrl": "نشانی پروکسی", +"saveProxy": "ذخیره", +"savingProxy": "در حال ذخیره…", +"proxyLoadFailed": "تنظیمات پروکسی بارگذاری نشد.", +"addCustom": "افزودن یک مدل سفارشی سازگار با OpenAI", +"addCustomDescription": "مدل‌های چت، امبدینگ، تصویر یا صوت را به هر endpoint سازگار با OpenAI متصل کنید. برای سرورهای محلی، کلید API اختیاری است.", +"customType": "نوع", +"customTypeChat": "چت", +"customTypeEmbedding": "امبدینگ", +"customTypeImage": "تصویر", +"customTypeAudio": "صوت", +"customBaseUrl": "نشانی پایه", +"customModels": "مدل‌ها", +"customModel": "مدل", +"customDisplayName": "نام نمایشی", +"customDisplayNamePerModel": "برای هر مدل", +"customDisplayNameOptional": "اختیاری", +"customFamily": "خانواده", +"customFamilyPlaceholder": "به‌طور پیش‌فرض برابر شناسهٔ مدل است", +"customApiKey": "کلید API", +"addModel": "افزودن مدل", +"addModels": "افزودن {count} مدل", +"addEmbeddingModel": "افزودن مدل امبدینگ", +"addImageModel": "افزودن مدل تصویر", +"addAudioModel": "افزودن مدل صوت", +"addingCustom": "در حال افزودن…", +"getApiKey": "دریافت کلید API", +"deleteKeyConfirm": "این کلید حذف شود؟ این کار قابل بازگشت نیست.", +"checkAll": "بررسی همه", +"checking": "در حال بررسی…", +"editLabel": "ویرایش برچسب", +"saveLabel": "ذخیرهٔ برچسب", +"unifiedKeyDescBefore": "از این به‌عنوان OpenAI ", +"unifiedKeyDescAfter": " خود استفاده کنید؛ این کلید درخواست‌ها را برای این پروکسی احراز هویت می‌کند.", +"serverUnreachableBefore": "نمی‌توان به سرور در ", +"serverUnreachableAfter": " دسترسی داشت. مطمئن شوید بخش پشتی در حال اجراست. npm run dev هر دو را اجرا می‌کند و لاگ‌های سرور با پیشوند server چاپ می‌شوند.", +"addProvider": "افزودن کلید ارائه‌دهنده", +"platform": "پلتفرم", +"apiToken": "توکن API", +"noKeyNeededPlaceholder": "نیازی به کلید API نیست", +"bearerTokenPlaceholder": "توکن Bearer", +"pasteKeyPlaceholder": "کلید را اینجا بچسبانید", +"keylessHint": "نیازی به کلید API نیست: سطح رایگان این ارائه‌دهنده ناشناس است (با محدودیت نرخ برای هر IP).", +"enable": "فعال‌سازی", +"noProviderKeys": "هنوز هیچ کلید ارائه‌دهنده‌ای وجود ندارد. یکی را در بالا اضافه کنید تا مسیریابی آغاز شود.", +"configuredProviders": "ارائه‌دهندگان پیکربندی‌شده", +"proxyToggleLabel": "پروکسی", +"keyCountOne": "{count} کلید", +"keyCountOther": "{count} کلید", +"proxyEnvHintBefore": "همچنین از طریق متغیر محیطی ", +"proxyEnvHintAfter": " قابل پیکربندی است (اولویت دارد). برای غیرفعال‌کردن خالی بگذارید. نمونه‌ها:", +"importKeys": "درون‌ریزی کلیدهای ارائه‌دهنده", +"importKeysDescription": "فایل‌های .env، JSON، JSONC، Markdown یا متنی را بارگذاری کنید.", +"importFiles": "فایل‌ها", +"importFileCount": "{count} انتخاب‌شده", +"previewFiles": "پیش‌نمایش", +"previewing": "در حال پیش‌نمایش…", +"selected": "انتخاب‌شده", +"provider": "ارائه‌دهنده", +"keyName": "نام کلید", +"keyValue": "مقدار کلید", +"chooseProvider": "انتخاب ارائه‌دهنده", +"noPreviewKeys": "هیچ کلیدی در آن فایل‌ها پیدا نشد.", +"skippedItems": "ردشده:", +"moreItems": "+{count} مورد دیگر", +"importSelected": "درون‌ریزی {count}", +"importing": "در حال درون‌ریزی…", +"noImportSelection": "حداقل یک ردیف با ارائه‌دهنده را انتخاب کنید.", +"importResult": "درون‌ریزی شد: {imported}؛ ناموفق: {failed}.", +"confirmRemove": "تأیید می‌کنید؟" +}, +"status": { +"healthy": "سالم", +"rateLimited": "دارای محدودیت نرخ", +"invalid": "نامعتبر", +"error": "خطا", +"unchecked": "بررسی‌نشده" +}, +"analytics": { +"title": "تحلیل‌ها", +"description": "حجم درخواست، تأخیر، مصرف توکن و خطاها.", +"range24h": "24h", +"range7d": "7d", +"range30d": "30d", +"requests": "درخواست‌ها", +"successRate": "نرخ موفقیت", +"inputTokens": "توکن‌های ورودی", +"outputTokens": "توکن‌های خروجی", +"avgLatency": "میانگین تأخیر", +"estSavings": "صرفه‌جویی تخمینی", +"requestsByProvider": "درخواست‌ها به تفکیک ارائه‌دهنده", +"avgLatencyByProvider": "میانگین تأخیر به تفکیک ارائه‌دهنده", +"requestsOverTime": "درخواست‌ها در طول زمان", +"byModel": "به تفکیک مدل", +"byPlatform": "به تفکیک پلتفرم", +"errors": "خطاها", +"errorDistribution": "توزیع خطا", +"pinnedRequests": "درخواست‌های ثابت‌شده", +"pinnedHonored": "رعایت‌شده", +"fallbackAttempts": "تلاش‌های جایگزین", +"savingsHint": "شما در {range} گذشته واقعاً ${actual} صرفه‌جویی کرده‌اید. این همان هزینه‌ای است که همان توکن‌ها در APIهای پولی، با قیمت‌گذاری بر اساس هر مدل، داشتند. عدد نمایش‌داده‌شده سرعت شما را از داده‌های {span} گذشته به کل ۳۰ روز برآورد می‌کند.", +"savingsHintExact": "شما در {range} گذشته واقعاً ${actual} صرفه‌جویی کرده‌اید. این همان هزینه‌ای است که همان توکن‌ها در APIهای پولی، با قیمت‌گذاری بر اساس هر مدل، داشتند. عدد نمایش‌داده‌شده مجموع واقعی ۳۰ روزهٔ شماست.", +"requestsHintPinned": "{pinned} مورد از این درخواست‌ها یک مدل مشخص را به‌نام ثابت کرده بودند. {honored} مورد توسط همان مدل ثابت‌شده سرویس شدند؛ {failed} مورد به مدل دیگری سوییچ شدند. بقیه به‌صورت خودکار مسیریابی شدند.", +"requestsHintAuto": "تمام درخواست‌های این بازه به‌صورت خودکار مسیریابی شدند؛ هیچ کلاینتی مدل مشخصی را به‌نام ثابت نکرده بود.", +"rangeLabel24h": "24 ساعت", +"rangeLabel7d": "7 روز", +"rangeLabel30d": "30 روز", +"spanDays": "{count} روز", +"spanHours": "{count} ساعت", +"latencyMs": "تأخیر (میلی‌ثانیه)", +"latency": "تأخیر", +"pinned": "ثابت‌شده", +"inTokens": "توکن ورودی", +"outTokens": "توکن خروجی", +"saved": "صرفه‌جویی‌شده", +"message": "پیام", +"time": "زمان", +"perModelBreakdown": "جزئیات به تفکیک مدل", +"errorsByProvider": "خطاها به تفکیک ارائه‌دهنده", +"recentErrors": "خطاهای اخیر", +"noErrors": "بدون خطا" +}, +"playground": { +"title": "محیط آزمایش", +"description": "یک تکمیل چت را از طریق مسیریاب ارسال کنید و ببینید کدام ارائه‌دهنده آن را سرویس می‌کند.", +"autoModel": "Auto (زنجیرهٔ جایگزین)", +"fusionModel": "فیوژن (ترکیب چندمدلی)", +"selectModel": "انتخاب مدل", +"searchModels": "جست‌وجوی مدل‌ها…", +"noModelsFound": "مدلی پیدا نشد", +"send": "ارسال", +"sending": "در حال ارسال…", +"clear": "پاک کردن", +"inputPlaceholder": "پیامی بنویسید… (⏎ برای ارسال، ⇧⏎ برای خط جدید)", +"emptyTitle": "برای شروع یک پیام ارسال کنید.", +"emptyDescription": "در حال استفاده از {model}. مدل‌ها را در انتخابگر بالا عوض کنید.", +"noModels": "هنوز مدلی وجود ندارد. برای پر کردن این فهرست، در صفحهٔ کلیدها یک کلید API اضافه کنید.", +"copyReply": "کپی پاسخ", +"fallback": "جایگزین", +"fallbacks": "جایگزین‌ها", +"fusionPanel": "پنل", +"fusionJudge": "داور", +"fusionTrace": "{count} پاسخ مدل", +"fusionFailed": "بدون پاسخ", +"fusionJudgeSynth": "پاسخ نهایی را ترکیب کرد", +"errorPrefix": "خطا:", +"systemPromptLabel": "پرامپت سیستم", +"systemPromptPlaceholder": "اختیاری. به‌عنوان یک پیام سیستم پیش از گفت‌وگوی شما ارسال می‌شود." +}, +"embeddings": { +"title": "مدل‌ها", +"description": "امبدینگ‌ها فقط درون یک خانواده سوییچ می‌شوند: همان مدل که توسط ارائه‌دهنده‌ای دیگر سرویس می‌شود. بردارهای مدل‌های مختلف ناسازگارند، بنابراین مسیریاب هرگز مدل‌ها را برای شما عوض نمی‌کند.", +"defaultBadge": "پیش‌فرض · auto", +"makeDefault": "تبدیل به پیش‌فرض", +"moveUp": "بالا بردن", +"moveDown": "پایین آوردن", +"usageToday": "{count} درخواست امروز", +"usageMonth": "{count} توکن در این ماه", +"autoDescription": "model: \"auto\" در POST /v1/embeddings به خانوادهٔ پیش‌فرض مسیریابی می‌شود. نام‌بردن از یک خانواده (یا شناسهٔ مدل ارائه‌دهنده) آن خانواده را ثابت می‌کند؛ ارائه‌دهندگان داخل آن به‌ترتیب آزموده می‌شوند.", + "unsavedChanges": "تغییرات ذخیره‌نشده", +"saveChanges": "ذخیرهٔ تغییرات", +"savingChanges": "در حال ذخیره…", +"tokMax": "{tokens} حداکثر توکن" +}, +"fusion": { +"title": "فیوژن", +"description": "یک پنل از مدل‌ها به‌صورت موازی پاسخ می‌دهند، سپس یک داور یک پاسخ قوی‌تر را ترکیب می‌کند. با فراخوانی API و model \"fusion\" از آن استفاده کنید.", + "panelSource": "منبع پنل", +"panelSourceHelp": "منشأ مدل‌های پنل وقتی خودِ درخواست چیزی مشخص نکرده باشد.", +"mode": { +"auto": "Auto (زنجیرهٔ جایگزین)", +"autoHelp": "یک مجموعهٔ متنوع از مدل‌ها را از زنجیرهٔ جایگزین خود انتخاب کنید، بر اساس راهبرد مسیریابی فعال شما رتبه‌بندی‌شده.", +"explicit": "پنل صریح", +"explicitHelp": "همیشه از مدل‌های مشخصی که در پایین انتخاب می‌کنید استفاده کنید." +}, +"panelModels": "مدل‌های پنل", +"selectedCount": "{count} از {max} انتخاب‌شده", +"noModels": "هنوز هیچ مدلی متصل نیست. یک کلید API اضافه کنید، سپس مدل‌ها را در زنجیرهٔ جایگزین فعال کنید.", +"panelSize": "اندازهٔ پنل", +"panelSizeHelp": "چند مدل متنوع به‌صورت خودکار انتخاب شوند (۱–{max}).", +"judge": "مدل داور", +"judgeHelp": "مدلی که پاسخ‌های پنل را به یک پاسخ ترکیب می‌کند. Auto از برترین مدل در دسترس شما استفاده می‌کند.", +"judgeAuto": "Auto (برترین مدل در دسترس)", +"strategy": "راهبرد", +"strategySynthesize": "ترکیب — پنل را به یک پاسخ واحد آمیخته کنید", +"strategyBestOf": "بهترین — فقط قوی‌ترین پاسخ را برگردانید (بدون فراخوانی داور)", +"strategySynthesizeShort": "ترکیب", +"strategyBestOfShort": "بهترین", +"exposePanel": "نمایش جزئیات پنل", +"exposePanelHelp": "پاسخ هر مدل و فرادادهٔ داور را زیر یک فیلد x_fusion در پاسخ ضمیمه کنید.", +"howToUse": "روش استفاده", +"howToUseHelp": "یک درخواست چت عادی با model \"fusion\" بفرستید. این تنظیمات پیش‌فرض هستند؛ هر درخواست می‌تواند با یک فیلد \"fusion\" آن‌ها را بازنویسی کند.", +"unsavedChanges": "تغییرات ذخیره‌نشده", +"save": "ذخیره" +}, +"premium": { +"title": "پریمیوم", +"description": "کاتالوگ زندهٔ مدل‌ها، روی هر دستگاه.", +"loading": "در حال بارگذاری…", +"checkForUpdates": "بررسی به‌روزرسانی‌ها", +"syncing": "در حال همگام‌سازی…", +"catalogFeed": "فید کاتالوگ", +"liveFeed": "فید زنده", +"monthlySnapshot": "نمای ماهانه", +"lastChecked": "آخرین بررسی: {when}", +"liveDescription": "مدل‌های رایگان جدید، تغییرات سهمیه و اصلاحات جزئی ظرف چند ساعت پس از انتشار اینجا ظاهر می‌شوند. برنامه روزی دو بار به‌طور خودکار بررسی می‌کند؛ نیازی به کار اضافه نیست.", +"snapshotDescription": "نسخهٔ رایگان: کاتالوگ از یک نمای ماهانه تازه می‌شود و روزی دو بار به‌طور خودکار بررسی می‌گردد. پریمیوم آن را به فید زنده تغییر می‌دهد که هر ۲–۳ روز به‌روزرسانی می‌شود.", +"lastSyncProblem": "آخرین مشکل همگام‌سازی: {error}", +"license": "مجوز", +"planAnnual": "پریمیوم سالانه", +"planLifetime": "پریمیوم دائمی", +"expired": "منقضی‌شده", +"inactive": "غیرفعال", +"lifetimeNote": "مجوز دائمی: هرگز منقضی نمی‌شود.", +"renewsOn": "در {date} تمدید می‌شود.", +"willNotRenew": "تمدید نمی‌شود. تا {date} پریمیوم فعال است، سپس این نصب به کاتالوگ ماهانهٔ رایگان برمی‌گردد.", +"keyInactive": "این کلید دیگر فعال نیست. برنامه همچنان با کاتالوگ ماهانهٔ رایگان کار می‌کند.", +"manageSubscription": "مدیریت اشتراک", +"openingPortal": "در حال باز کردن…", +"removeKey": "حذف کلید از این دستگاه", +"manageHint": "مدیریت اشتراک، درگاه صورتحساب Stripe را باز می‌کند: لغو، به‌روزرسانی کارت یا دانلود فاکتورها. حذف کلید فقط این دستگاه را غیرفعال می‌کند؛ خرید شما دست‌نخورده می‌ماند.", +"licenseKey": "کلید مجوز", +"licenseKeyPlaceholder": "fla_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"activate": "فعال‌سازی", +"activating": "در حال فعال‌سازی…", +"keyHint": "کلید شما در ایمیل خرید و در صفحهٔ پس از پرداخت قرار دارد. آن را گم کرده‌اید؟", +"recoverKey": "آن را در وب‌سایت بازیابی کنید", +"upsellTitle": "به نسخهٔ زنده با ۱۹ دلار در سال بروید", +"upsellDescription": "مدل‌های رایگان جدید درست در همان لحظه‌ای که وجود پیدا می‌کنند، نه ۳۰ روز بعد. یک کلید، برای همهٔ دستگاه‌ها. هر زمان خواستید لغو کنید؛ مسیریاب برای همیشه رایگان می‌ماند.", +"goPremium": "ارتقا به پریمیوم", +"bundled": "باندل‌شده", +"planGeneric": "پریمیوم" +}, +"languages": { +"en": "انگلیسی", +"zh-CN": "چینی (ساده)", +"fr": "فرانسوی", +"es": "اسپانیایی", +"pt-BR": "پرتغالی (برزیل)", +"it": "ایتالیایی", +"fa": "فارسی" +} +}