diff --git a/apps/app/.gitignore b/apps/app/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/apps/app/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/app/.prettierignore b/apps/app/.prettierignore new file mode 100644 index 0000000..b2dae58 --- /dev/null +++ b/apps/app/.prettierignore @@ -0,0 +1,4 @@ +/node_modules +/.next +/out +/build \ No newline at end of file diff --git a/apps/app/.prettierrc.json b/apps/app/.prettierrc.json new file mode 100644 index 0000000..4073b98 --- /dev/null +++ b/apps/app/.prettierrc.json @@ -0,0 +1,16 @@ +{ + "printWidth": 120, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "es5", + "plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-sort-json"], + "importOrder": [ + "^(react/(.*)$)|^(react$)", + "^(next/(.*)$)|^(next$)", + "", + "", + "^@/(.*)$", + "^[./]" + ], + "importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"] +} \ No newline at end of file diff --git a/apps/app/components.json b/apps/app/components.json new file mode 100644 index 0000000..ffe928f --- /dev/null +++ b/apps/app/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/apps/app/eslint.config.mjs b/apps/app/eslint.config.mjs new file mode 100644 index 0000000..a5fdc19 --- /dev/null +++ b/apps/app/eslint.config.mjs @@ -0,0 +1,66 @@ +/* eslint-disable import/no-anonymous-default-export */ +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { FlatCompat } from "@eslint/eslintrc"; +import js from "@eslint/js"; +import typescriptEslintEslintPlugin from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default [ + ...compat.extends("next", "next/core-web-vitals", "prettier"), + { + plugins: { + prettier, + }, + rules: { + "prettier/prettier": "error", + camelcase: "off", + "import/prefer-default-export": "off", + "react/jsx-filename-extension": "off", + "react/jsx-props-no-spreading": "off", + "react/no-unused-prop-types": "off", + "react/require-default-props": "off", + "react/no-unescaped-entities": "off", + "import/extensions": [ + "error", + "ignorePackages", + { + ts: "never", + tsx: "never", + js: "never", + jsx: "never", + }, + ], + }, + }, + ...compat.extends("plugin:@typescript-eslint/recommended", "prettier").map((config) => ({ + ...config, + files: ["**/*.+(ts|tsx)"], + })), + { + files: ["**/*.+(ts|tsx)"], + plugins: { + "@typescript-eslint": typescriptEslintEslintPlugin, + }, + languageOptions: { + parser: tsParser, + }, + rules: { + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "no-use-before-define": [0], + "@typescript-eslint/no-use-before-define": [1], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-var-requires": "off", + }, + }, +]; \ No newline at end of file diff --git a/apps/app/messages/ar-SA.json b/apps/app/messages/ar-SA.json new file mode 100644 index 0000000..b871a57 --- /dev/null +++ b/apps/app/messages/ar-SA.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "مرحبا بك", + "signInToContinue": "قم بتسجيل الدخول للمتابعة", + "emailLabel": "البريد الإلكتروني", + "emailPlaceholder": "أدخل بريدك الإلكتروني", + "passwordLabel": "كلمة المرور", + "passwordPlaceholder": "أدخل كلمة المرور", + "signIn": "تسجيل الدخول", + "signingIn": "جاري تسجيل الدخول...", + "forgotPassword": "نسيت كلمة المرور؟", + "pageTitle": "تسجيل الدخول" + }, + "errors": { + "invalidCredentials": "بريد إلكتروني أو كلمة مرور غير صحيحة", + "userNotFound": "المستخدم غير موجود", + "accountLocked": "تم قفل الحساب. يرجى المحاولة لاحقًا", + "unexpectedError": "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى" + }, + "validation": { + "invalidEmail": "عنوان بريد إلكتروني غير صالح", + "passwordMinLength": "يجب أن تحتوي كلمة المرور على 6 أحرف على الأقل", + "firstNameRequired": "الاسم الأول مطلوب", + "lastNameRequired": "اسم العائلة مطلوب", + "usernameLength": "يجب أن يحتوي اسم المستخدم على 3 أحرف على الأقل", + "usernameSpaces": "لا يمكن أن يحتوي اسم المستخدم على فراغات", + "passwordLength": "يجب أن تحتوي كلمة المرور على 8 أحرف على الأقل", + "passwordsMatch": "كلمتا المرور غير متطابقتين", + "emailRequired": "البريد الإلكتروني مطلوب", + "passwordRequired": "كلمة المرور مطلوبة" + }, + "fileSelector": { + "availableFiles": "الملفات المتاحة ({{count}})", + "shareFiles": "مشاركة الملفات ({{count}})", + "searchPlaceholder": "ابحث عن الملفات...", + "noMatchingFiles": "لا توجد ملفات مطابقة", + "noAvailableFiles": "لا توجد ملفات متاحة", + "noFilesInShare": "لا توجد ملفات للمشاركة", + "saveChanges": "احفظ التغييرات" + }, + "recipientSelector": { + "emailPlaceholder": "أدخل بريد المستلم الإلكتروني", + "add": "أضف", + "recipients": "المستلمون ({{count}})", + "notifyAll": "أبلغ الجميع", + "noRecipients": "لم يتم إضافة أي مستلمين بعد", + "addSuccess": "تم إضافة المستلم بنجاح", + "addError": "فشل في إضافة المستلم", + "removeSuccess": "تم إزالة المستلم بنجاح", + "removeError": "فشل في إزالة المستلم", + "sendingNotifications": "جاري إرسال الإشعارات...", + "notifySuccess": "تم إعلام المستلمين بنجاح", + "notifyError": "فشل في إعلام المستلمين" + }, + "navigation": { + "dashboard": "لوحة التحكم" + }, + "common": { + "loading": "جاري التحميل، يرجى الانتظار...", + "cancel": "إلغاء", + "save": "حفظ", + "delete": "حذف", + "close": "إغلاق", + "download": "تنزيل", + "unexpectedError": "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى.", + "yes": "نعم", + "no": "لا", + "dashboard": "لوحة التحكم" + }, + "createShare": { + "title": "إنشاء مشاركة", + "nameLabel": "اسم المشاركة", + "expirationLabel": "تاريخ الانتهاء", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "أقصى عدد للمشاهدات", + "maxViewsPlaceholder": "اتركه فارغاً للمحدودية غير المحدودة", + "passwordProtection": "حماية بكلمة المرور", + "passwordLabel": "كلمة المرور", + "create": "إنشاء المشاركة", + "success": "تم إنشاء المشاركة بنجاح", + "error": "فشل في إنشاء المشاركة" + }, + "fileActions": { + "editFile": "تعديل الملف", + "nameLabel": "الاسم", + "namePlaceholder": "أدخل اسمًا جديدًا", + "extension": "الامتداد", + "descriptionLabel": "الوصف", + "descriptionPlaceholder": "أدخل وصف الملف", + "deleteFile": "حذف الملف", + "deleteConfirmation": "هل أنت متأكد أنك تريد حذف \"{{fileName}}\"؟", + "deleteWarning": "هذا الإجراء لا يمكن التراجع عنه." + }, + "filePreview": { + "loading": "جاري تحميل المعاينة...", + "notAvailable": "المعاينة غير متوفرة", + "downloadToView": "قم بتنزيل الملف لعرض المحتوى", + "audioNotSupported": "المتصفح لا يدعم عنصر الصوت", + "videoNotSupported": "المتصفح لا يدعم عنصر الفيديو", + "loadError": "فشل في تحميل المعاينة", + "downloadError": "فشل في تنزيل الملف" + }, + "generateShareLink": { + "generateTitle": "إنشاء رابط المشاركة", + "updateTitle": "تحديث رابط المشاركة", + "generateDescription": "أنشئ رابطاً لمشاركة ملفاتك", + "updateDescription": "قم بتحديث اللقب لهذا الرابط", + "aliasPlaceholder": "أدخل لقبًا", + "linkReady": "رابط المشاركة جاهز:", + "generateButton": "إنشاء الرابط", + "updateButton": "تحديث الرابط", + "copyButton": "نسخ الرابط", + "success": "تم إنشاء الرابط بنجاح", + "error": "فشل في إنشاء الرابط", + "copied": "تم نسخ الرابط إلى الحافظة" + }, + "shareActions": { + "deleteTitle": "حذف المشاركة", + "deleteConfirmation": "هل أنت متأكد من رغبتك في حذف هذه المشاركة؟ هذا الإجراء لا يمكن التراجع عنه.", + "editTitle": "تعديل المشاركة", + "nameLabel": "اسم المشاركة", + "expirationLabel": "تاريخ الانتهاء", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "أقصى عدد للمشاهدات", + "maxViewsPlaceholder": "اتركه فارغاً للمحدودية غير المحدودة", + "passwordProtection": "محمي بكلمة المرور", + "passwordLabel": "كلمة المرور", + "passwordPlaceholder": "أدخل كلمة المرور", + "newPasswordLabel": "كلمة مرور جديدة (اتركه فارغاً للاحتفاظ بالحالي)", + "newPasswordPlaceholder": "أدخل كلمة مرور جديدة", + "manageFilesTitle": "إدارة الملفات", + "manageRecipientsTitle": "إدارة المستلمين", + "editSuccess": "تم تحديث المشاركة بنجاح", + "editError": "فشل في تحديث المشاركة" + }, + "shareDetails": { + "title": "تفاصيل المشاركة", + "subtitle": "معلومات مفصلة عن هذه المشاركة", + "basicInfo": "المعلومات الأساسية", + "name": "الاسم", + "untitled": "بدون عنوان", + "views": "المشاهدات", + "dates": "التواريخ", + "created": "تم الإنشاء", + "expires": "تنتهي", + "never": "أبدًا", + "security": "الأمان", + "passwordProtected": "محمي بكلمة المرور", + "publicAccess": "الوصول العام", + "maxViews": "أقصى عدد للمشاهدات: {{count}}", + "files": "الملفات ({{count}})", + "recipients": "المستلمون ({{count}})", + "notAvailable": "غير متوفر", + "invalidDate": "تاريخ غير صالح", + "loadError": "فشل في تحميل تفاصيل المشاركة" + }, + "uploadFile": { + "title": "رفع الملف", + "selectFile": "اضغط لاختيار ملف", + "preview": "المعاينة", + "uploadProgress": "تقدم الرفع", + "upload": "رفع", + "success": "تم رفع الملف بنجاح", + "error": "فشل في رفع الملف" + }, + "filesTable": { + "ariaLabel": "جدول الملفات", + "columns": { + "name": "الاسم", + "description": "الوصف", + "size": "الحجم", + "createdAt": "تاريخ الإنشاء", + "updatedAt": "تاريخ التحديث", + "actions": "الإجراءات" + }, + "actions": { + "menu": "قائمة إجراءات الملف", + "preview": "المعاينة", + "edit": "تعديل", + "download": "تنزيل", + "delete": "حذف" + } + }, + "sharesTable": { + "ariaLabel": "جدول المشاركات", + "never": "أبدًا", + "columns": { + "name": "الاسم", + "createdAt": "تاريخ الإنشاء", + "expiresAt": "تاريخ الانتهاء", + "status": "الحالة", + "security": "الأمان", + "files": "الملفات", + "recipients": "المستلمون", + "actions": "الإجراءات" + }, + "status": { + "neverExpires": "لا تنتهي", + "active": "نشطة", + "expired": "منتهية" + }, + "security": { + "protected": "محمي", + "public": "عام" + }, + "filesCount": "{{count}} ملف", + "recipientsCount": "{{count}} مستلم", + "actions": { + "menu": "قائمة إجراءات المشاركة", + "edit": "تعديل", + "manageFiles": "إدارة الملفات", + "manageRecipients": "إدارة المستلمين", + "viewDetails": "عرض التفاصيل", + "generateLink": "إنشاء الرابط", + "editLink": "تعديل الرابط", + "copyLink": "نسخ الرابط", + "notifyRecipients": "إعلام المستلمين", + "delete": "حذف" + } + }, + "footer": { + "poweredBy": "مدعوم من", + "kyanHomepage": "الصفحة الرئيسية لـ Kyantech" + }, + "fileManager": { + "downloadError": "فشل في تنزيل الملف", + "updateSuccess": "تم تحديث الملف بنجاح", + "updateError": "فشل في تحديث الملف", + "deleteSuccess": "تم حذف الملف بنجاح", + "deleteError": "فشل في حذف الملف" + }, + "shareManager": { + "deleteSuccess": "تم حذف المشاركة بنجاح", + "deleteError": "فشل في حذف المشاركة", + "updateSuccess": "تم تحديث المشاركة بنجاح", + "updateError": "فشل في تحديث المشاركة", + "filesUpdateSuccess": "تم تحديث الملفات بنجاح", + "filesUpdateError": "فشل في تحديث الملفات", + "recipientsUpdateSuccess": "تم تحديث المستلمين بنجاح", + "recipientsUpdateError": "فشل في تحديث المستلمين", + "linkGenerateSuccess": "تم إنشاء رابط المشاركة بنجاح", + "linkGenerateError": "فشل في إنشاء رابط المشاركة", + "notifyLoading": "جاري إرسال الإشعارات...", + "notifySuccess": "تم إعلام المستلمين بنجاح", + "notifyError": "فشل في إعلام المستلمين" + }, + "quickAccess": { + "files": { + "title": "ملفاتي", + "description": "الوصول إلى الملفات المرفوعة وإدارتها" + }, + "shares": { + "title": "مشاركاتي", + "description": "عرض وإدارة الملفات المشتركة" + } + }, + "recentFiles": { + "title": "الرفع الأخير", + "viewAll": "عرض الكل", + "uploadFile": "رفع ملف", + "noFiles": "لم يتم رفع أي ملفات بعد" + }, + "recentShares": { + "title": "المشاركات الأخيرة", + "viewAll": "عرض الكل", + "createShare": "إنشاء مشاركة", + "noShares": "لم يتم إنشاء أي مشاركات بعد", + "createFirst": "أنشئ مشاركتك الأولى" + }, + "storageUsage": { + "title": "استخدام التخزين", + "ariaLabel": "شريط تقدم استخدام التخزين", + "used": "المستخدمة: {{size}}", + "available": "المتاحة: {{size}}" + }, + "dashboard": { + "loadError": "فشل في تحميل بيانات لوحة التحكم", + "linkCopied": "تم نسخ الرابط إلى الحافظة", + "pageTitle": "لوحة التحكم", + "breadcrumb": "لوحة التحكم" + }, + "emptyState": { + "noFiles": "لم يتم رفع أي ملفات بعد", + "uploadFile": "رفع ملف" + }, + "files": { + "title": "كل الملفات", + "uploadFile": "رفع ملف", + "loadError": "فشل في تحميل الملفات", + "pageTitle": "ملفاتي", + "breadcrumb": "ملفاتي" + }, + "searchBar": { + "placeholder": "ابحث عن الملفات...", + "results": "تم العثور على {{filtered}} من {{total}} ملف" + }, + "forgotPassword": { + "emailLabel": "البريد الإلكتروني", + "emailPlaceholder": "أدخل بريدك الإلكتروني", + "sending": "جاري الإرسال...", + "submit": "أرسل تعليمات إعادة التعيين", + "backToLogin": "العودة إلى تسجيل الدخول", + "title": "نسيت كلمة المرور", + "description": "أدخل بريدك الإلكتروني وسنرسل لك تعليمات إعادة تعيين كلمة المرور.", + "resetInstructions": "تم إرسال تعليمات إعادة التعيين إلى بريدك الإلكتروني", + "pageTitle": "نسيت كلمة المرور" + }, + "home": { + "description": "البديل مفتوح المصدر لـ WeTransfer. شارك ملفاتك بأمان، دون تتبع أو قيود.", + "documentation": "التوثيق", + "starOnGithub": "ضع نجمة على GitHub", + "privacyMessage": "مصمم مع مراعاة الخصوصية. ملفاتك قبل الرفع متاحة فقط لأولئك الذين لديهم رابط المشاركة. مجاني ومفتوح المصدر دائمًا.", + "header": { + "fileSharing": "مشاركة الملفات", + "tagline": "بسيط ومجاني" + }, + "pageTitle": "الصفحة الرئيسية" + }, + "profile": { + "password": { + "title": "تغيير كلمة المرور", + "newPassword": "كلمة مرور جديدة", + "confirmPassword": "تأكيد كلمة المرور الجديدة", + "updateButton": "تحديث كلمة المرور" + }, + "form": { + "title": "معلومات الملف الشخصي", + "firstName": "الاسم الأول", + "lastName": "اسم العائلة", + "username": "اسم المستخدم", + "email": "البريد الإلكتروني", + "updateButton": "تحديث الملف الشخصي" + }, + "header": { + "title": "الملف الشخصي", + "subtitle": "إدارة معلوماتك الشخصية وكلمة المرور" + }, + "picture": { + "title": "صورة الملف الشخصي", + "description": "انقر على أيقونة الكاميرا لتغيير صورة الملف الشخصي", + "uploadPhoto": "رفع صورة", + "removePhoto": "حذف الصورة" + }, + "errors": { + "loadFailed": "فشل في تحميل بيانات المستخدم", + "updateFailed": "فشل في تحديث الملف الشخصي", + "passwordFailed": "فشل في تحديث كلمة المرور", + "imageFailed": "فشل في تحديث صورة الملف الشخصي", + "imageRemoveFailed": "فشل في حذف صورة الملف الشخصي" + }, + "messages": { + "noChanges": "لا توجد تغييرات للحفظ", + "updateSuccess": "تم تحديث الملف الشخصي بنجاح", + "fillPasswords": "يرجى ملء كلا حقلي كلمة المرور", + "passwordSuccess": "تم تحديث كلمة المرور بنجاح", + "imageSuccess": "تم تحديث صورة الملف الشخصي بنجاح", + "imageRemoved": "تم حذف صورة الملف الشخصي بنجاح" + }, + "pageTitle": "الملف الشخصي" + }, + "resetPassword": { + "pageTitle": "إعادة تعيين كلمة المرور", + "header": { + "title": "إعادة تعيين كلمة المرور", + "description": "أدخل كلمة المرور الجديدة أدناه" + }, + "form": { + "newPassword": "كلمة مرور جديدة", + "newPasswordPlaceholder": "أدخل كلمة المرور الجديدة", + "confirmPassword": "تأكيد كلمة المرور الجديدة", + "confirmPasswordPlaceholder": "أدخل تأكيد كلمة المرور الجديدة", + "resetting": "جاري إعادة تعيين كلمة المرور...", + "submit": "إعادة تعيين كلمة المرور", + "backToLogin": "العودة إلى تسجيل الدخول" + }, + "messages": { + "success": "تم إعادة تعيين كلمة المرور بنجاح" + }, + "errors": { + "serverError": "فشل في إعادة تعيين كلمة المرور. يرجى المحاولة مرة أخرى.", + "invalidToken": "رمز إعادة التعيين غير صالح أو مفقود" + } + }, + "settings": { + "groups": { + "defaultDescription": "خيارات التكوين", + "general": { + "title": "عام", + "description": "إعدادات التطبيق الأساسية" + }, + "email": { + "title": "البريد الإلكتروني", + "description": "تكوين خادم البريد الإلكتروني" + }, + "security": { + "title": "الأمان", + "description": "إعدادات الأمان والمصادقة" + }, + "storage": { + "title": "التخزين", + "description": "تكوين تخزين الملفات" + } + }, + "fields": { + "noDescription": "لا يوجد وصف متاح", + "appLogo": { + "title": "شعار التطبيق", + "description": "صورة شعار التطبيق" + }, + "appName": { + "title": "اسم التطبيق", + "description": "اسم التطبيق الذي يظهر للمستخدمين" + }, + "appDescription": { + "title": "وصف التطبيق", + "description": "وصف مختصر للتطبيق" + }, + "showHomePage": { + "title": "عرض الصفحة الرئيسية", + "description": "عرض الصفحة الرئيسية بعد التثبيت" + }, + "smtpEnabled": { + "title": "تمكين SMTP", + "description": "تمكين أو تعطيل وظيفة البريد الإلكتروني عبر SMTP" + }, + "smtpHost": { + "title": "خادم SMTP", + "description": "عنوان خادم SMTP" + }, + "smtpPort": { + "title": "منفذ SMTP", + "description": "منفذ خادم SMTP" + }, + "smtpUser": { + "title": "مستخدم SMTP", + "description": "اسم المستخدم لمصادقة SMTP" + }, + "smtpPass": { + "title": "كلمة مرور SMTP", + "description": "كلمة المرور لمصادقة SMTP" + }, + "smtpFromName": { + "title": "اسم المرسل", + "description": "الاسم الظاهر في الرسائل المرسلة" + }, + "smtpFromEmail": { + "title": "البريد الإلكتروني للمرسل", + "description": "عنوان البريد الإلكتروني للمرسل" + }, + "maxLoginAttempts": { + "title": "أقصى محاولات تسجيل دخول", + "description": "الحد الأقصى لمحاولات تسجيل الدخول قبل الحظر" + }, + "loginBlockDuration": { + "title": "مدة حظر تسجيل الدخول", + "description": "مدة الحظر (بالثواني) بعد تجاوز الحد الأقصى للمحاولات" + }, + "passwordMinLength": { + "title": "الحد الأدنى لطول كلمة المرور", + "description": "الحد الأدنى لعدد الأحرف في كلمة المرور" + }, + "passwordResetTokenExpiration": { + "title": "انتهاء صلاحية رمز إعادة التعيين", + "description": "مدة صلاحية رمز إعادة تعيين كلمة المرور (بالثواني)" + }, + "maxFileSize": { + "title": "أقصى حجم للملف", + "description": "الحد الأقصى لحجم الملف المسموح به للرفع (بالبايت)" + }, + "maxTotalStoragePerUser": { + "title": "أقصى تخزين لكل مستخدم", + "description": "الحد الإجمالي للتخزين لكل مستخدم (بالبايت)" + } + }, + "buttons": { + "save": "احفظ {{group}}" + }, + "errors": { + "loadFailed": "فشل في تحميل الإعدادات", + "updateFailed": "فشل في تحديث الإعدادات" + }, + "messages": { + "noChanges": "لا توجد تغييرات للحفظ", + "updateSuccess": "تم تحديث إعدادات {{group}} بنجاح" + }, + "title": "الإعدادات", + "breadcrumb": "الإعدادات", + "pageTitle": "الإعدادات" + }, + "share": { + "errors": { + "invalidPassword": "كلمة مرور غير صحيحة. يرجى المحاولة مرة أخرى.", + "loadFailed": "فشل في تحميل المشاركة", + "downloadFailed": "فشل في تنزيل الملف" + }, + "messages": { + "downloadStarted": "بدأ التنزيل" + }, + "password": { + "title": "مشاركة محمية بكلمة المرور", + "protected": "هذه المشاركة محمية بكلمة مرور", + "incorrect": "كلمة المرور غير صحيحة. يرجى المحاولة مرة أخرى.", + "label": "كلمة المرور", + "placeholder": "أدخل كلمة مرور المشاركة", + "submit": "إرسال" + }, + "details": { + "untitled": "بدون عنوان", + "created": "تم الإنشاء: {{date}}", + "expires": "تنتهي: {{date}}" + }, + "notFound": { + "title": "لم يتم العثور على المشاركة", + "description": "قد يكون تم حذف هذه المشاركة أو انتهت صلاحيتها." + }, + "pageTitle": "المشاركة" + }, + "shares": { + "errors": { + "loadFailed": "فشل في تحميل المشاركات", + "notifyFailed": "فشل في إعلام المستلمين", + "smtpConfigFailed": "فشل في تحميل إعدادات SMTP" + }, + "messages": { + "linkCopied": "تم نسخ الرابط إلى الحافظة", + "recipientsNotified": "تم إعلام المستلمين بنجاح" + }, + "empty": { + "message": "لم يتم إنشاء أي مشاركات بعد", + "createButton": "إنشاء مشاركة" + }, + "header": { + "title": "مشاركاتي", + "myShares": "مشاركاتي" + }, + "search": { + "title": "كل المشاركات", + "createButton": "إنشاء مشاركة", + "placeholder": "ابحث عن المشاركات...", + "results": "تم العثور على {{filtered}} من {{total}} مشاركات" + }, + "pageTitle": "المشاركات" + }, + "users": { + "modes": { + "create": "إنشاء", + "edit": "تعديل" + }, + "errors": { + "loadFailed": "فشل في تحميل المستخدمين", + "submitFailed": "فشل في {{mode}} المستخدم", + "deleteFailed": "فشل في حذف المستخدم", + "statusUpdateFailed": "فشل في تحديث حالة المستخدم" + }, + "messages": { + "createSuccess": "تم إنشاء المستخدم بنجاح", + "updateSuccess": "تم تحديث المستخدم بنجاح", + "deleteSuccess": "تم حذف المستخدم بنجاح", + "activateSuccess": "تم تفعيل المستخدم بنجاح", + "deactivateSuccess": "تم إلغاء تفعيل المستخدم بنجاح" + }, + "actions": { + "edit": "تعديل", + "activate": "تفعيل", + "deactivate": "إلغاء التفعيل", + "delete": "حذف" + }, + "delete": { + "title": "تأكيد حذف المستخدم", + "confirmation": "هل أنت متأكد من أنك تريد حذف {{firstName}} {{lastName}}؟ هذا الإجراء لا يمكن التراجع عنه.", + "confirm": "حذف المستخدم" + }, + "form": { + "titleCreate": "إضافة مستخدم جديد", + "titleEdit": "تعديل المستخدم", + "firstName": "الاسم الأول", + "lastName": "اسم العائلة", + "username": "اسم المستخدم", + "email": "البريد الإلكتروني", + "password": "كلمة المرور", + "newPassword": "كلمة مرور جديدة (اختياري)", + "passwordPlaceholder": "اتركه فارغاً للاحتفاظ بكلمة المرور الحالية", + "role": "الدور", + "roleUser": "مستخدم", + "roleAdmin": "مسؤول", + "create": "إنشاء", + "save": "حفظ" + }, + "status": { + "title": "تأكيد تغيير الحالة", + "confirmation": "هل أنت متأكد من أنك تريد {{action}} المستخدم {{firstName}} {{lastName}}؟", + "activate": "تفعيل", + "deactivate": "إلغاء التفعيل", + "user": "المستخدم" + }, + "header": { + "title": "إدارة المستخدمين", + "addUser": "إضافة مستخدم", + "management": "إدارة المستخدمين" + }, + "table": { + "user": "المستخدم", + "email": "البريد الإلكتروني", + "status": "الحالة", + "role": "الدور", + "actions": "الإجراءات", + "active": "مفعل", + "inactive": "غير مفعل", + "admin": "مسؤول", + "userr": "مستخدم" + } + }, + "logo": { + "labels": { + "appLogo": "شعار التطبيق" + }, + "buttons": { + "upload": "رفع الشعار", + "remove": "حذف الشعار" + }, + "messages": { + "uploadSuccess": "تم رفع الشعار بنجاح", + "removeSuccess": "تم حذف الشعار بنجاح" + }, + "errors": { + "uploadFailed": "فشل في رفع الشعار", + "removeFailed": "فشل في حذف الشعار" + } + }, + "navbar": { + "logoAlt": "شعار التطبيق", + "profileMenu": "قائمة الملف الشخصي", + "profile": "الملف الشخصي", + "settings": "الإعدادات", + "usersManagement": "إدارة المستخدمين", + "logout": "تسجيل الخروج" + } +} \ No newline at end of file diff --git a/apps/app/messages/de-DE.json b/apps/app/messages/de-DE.json new file mode 100644 index 0000000..75d397d --- /dev/null +++ b/apps/app/messages/de-DE.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "Willkommen zu", + "signInToContinue": "Melden Sie sich an, um fortzufahren", + "emailLabel": "E-Mail-Adresse", + "emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein", + "passwordLabel": "Passwort", + "passwordPlaceholder": "Geben Sie Ihr Passwort ein", + "signIn": "Anmelden", + "signingIn": "Melde an...", + "forgotPassword": "Passwort vergessen?", + "pageTitle": "Anmeldung" + }, + "errors": { + "invalidCredentials": "Ungültige E-Mail oder Passwort", + "userNotFound": "Benutzer nicht gefunden", + "accountLocked": "Konto gesperrt. Bitte versuchen Sie es später erneut", + "unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut" + }, + "validation": { + "invalidEmail": "Ungültige E-Mail-Adresse", + "passwordMinLength": "Das Passwort muss mindestens 6 Zeichen lang sein", + "firstNameRequired": "Vorname ist erforderlich", + "lastNameRequired": "Nachname ist erforderlich", + "usernameLength": "Der Benutzername muss mindestens 3 Zeichen lang sein", + "usernameSpaces": "Der Benutzername darf keine Leerzeichen enthalten", + "passwordLength": "Das Passwort muss mindestens 8 Zeichen lang sein", + "passwordsMatch": "Die Passwörter stimmen nicht überein", + "emailRequired": "E-Mail ist erforderlich", + "passwordRequired": "Passwort ist erforderlich" + }, + "fileSelector": { + "availableFiles": "Verfügbare Dateien ({{count}})", + "shareFiles": "Dateien teilen ({{count}})", + "searchPlaceholder": "Dateien suchen...", + "noMatchingFiles": "Keine übereinstimmenden Dateien", + "noAvailableFiles": "Keine Dateien verfügbar", + "noFilesInShare": "Keine Dateien in der Freigabe", + "saveChanges": "Änderungen speichern" + }, + "recipientSelector": { + "emailPlaceholder": "Empfänger-E-Mail eingeben", + "add": "Hinzufügen", + "recipients": "Empfänger ({{count}})", + "notifyAll": "Alle benachrichtigen", + "noRecipients": "Noch keine Empfänger hinzugefügt", + "addSuccess": "Empfänger erfolgreich hinzugefügt", + "addError": "Fehler beim Hinzufügen des Empfängers", + "removeSuccess": "Empfänger erfolgreich entfernt", + "removeError": "Fehler beim Entfernen des Empfängers", + "sendingNotifications": "Benachrichtigungen werden gesendet...", + "notifySuccess": "Empfänger erfolgreich benachrichtigt", + "notifyError": "Fehler beim Benachrichtigen der Empfänger" + }, + "navigation": { + "dashboard": "Übersicht" + }, + "common": { + "loading": "Lädt, bitte warten...", + "cancel": "Abbrechen", + "save": "Speichern", + "delete": "Löschen", + "close": "Schließen", + "download": "Herunterladen", + "unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.", + "yes": "Ja", + "no": "Nein", + "dashboard": "Übersicht" + }, + "createShare": { + "title": "Freigabe erstellen", + "nameLabel": "Freigabename", + "expirationLabel": "Ablaufdatum", + "expirationPlaceholder": "MM/TT/JJJJ SS:MM", + "maxViewsLabel": "Maximale Ansichten", + "maxViewsPlaceholder": "Leer lassen für unbegrenzt", + "passwordProtection": "Passwortgeschützt", + "passwordLabel": "Passwort", + "create": "Freigabe erstellen", + "success": "Freigabe erfolgreich erstellt", + "error": "Fehler beim Erstellen der Freigabe" + }, + "fileActions": { + "editFile": "Datei bearbeiten", + "nameLabel": "Name", + "namePlaceholder": "Neuen Namen eingeben", + "extension": "Erweiterung", + "descriptionLabel": "Beschreibung", + "descriptionPlaceholder": "Dateibeschreibung eingeben", + "deleteFile": "Datei löschen", + "deleteConfirmation": "Sind Sie sicher, dass Sie \"{{fileName}}\" löschen möchten?", + "deleteWarning": "Diese Aktion kann nicht rückgängig gemacht werden." + }, + "filePreview": { + "loading": "Vorschau wird geladen...", + "notAvailable": "Vorschau nicht verfügbar", + "downloadToView": "Datei herunterladen, um den Inhalt anzuzeigen", + "audioNotSupported": "Ihr Browser unterstützt das Audioelement nicht", + "videoNotSupported": "Ihr Browser unterstützt das Videoelement nicht", + "loadError": "Fehler beim Laden der Vorschau", + "downloadError": "Fehler beim Herunterladen der Datei" + }, + "generateShareLink": { + "generateTitle": "Freigabelink generieren", + "updateTitle": "Freigabelink aktualisieren", + "generateDescription": "Erstellen Sie einen Link, um Ihre Dateien zu teilen", + "updateDescription": "Aktualisieren Sie den Alias für diesen Freigabelink", + "aliasPlaceholder": "Alias eingeben", + "linkReady": "Ihr Freigabelink ist fertig:", + "generateButton": "Link generieren", + "updateButton": "Link aktualisieren", + "copyButton": "Link kopieren", + "success": "Link erfolgreich generiert", + "error": "Fehler beim Generieren des Links", + "copied": "Link in die Zwischenablage kopiert" + }, + "shareActions": { + "deleteTitle": "Freigabe löschen", + "deleteConfirmation": "Sind Sie sicher, dass Sie diese Freigabe löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", + "editTitle": "Freigabe bearbeiten", + "nameLabel": "Freigabename", + "expirationLabel": "Ablaufdatum", + "expirationPlaceholder": "MM/TT/JJJJ SS:MM", + "maxViewsLabel": "Maximale Ansichten", + "maxViewsPlaceholder": "Leer lassen für unbegrenzt", + "passwordProtection": "Passwortgeschützt", + "passwordLabel": "Passwort", + "passwordPlaceholder": "Passwort eingeben", + "newPasswordLabel": "Neues Passwort (leer lassen, um das aktuelle zu behalten)", + "newPasswordPlaceholder": "Neues Passwort eingeben", + "manageFilesTitle": "Dateien verwalten", + "manageRecipientsTitle": "Empfänger verwalten", + "editSuccess": "Freigabe erfolgreich aktualisiert", + "editError": "Fehler beim Aktualisieren der Freigabe" + }, + "shareDetails": { + "title": "Freigabedetails", + "subtitle": "Detaillierte Informationen zu dieser Freigabe", + "basicInfo": "Grundinformationen", + "name": "Name", + "untitled": "Ohne Titel", + "views": "Aufrufe", + "dates": "Daten", + "created": "Erstellt", + "expires": "Läuft ab", + "never": "Nie", + "security": "Sicherheit", + "passwordProtected": "Passwortgeschützt", + "publicAccess": "Öffentlicher Zugriff", + "maxViews": "Maximale Ansichten: {{count}}", + "files": "Dateien ({{count}})", + "recipients": "Empfänger ({{count}})", + "notAvailable": "N/V", + "invalidDate": "Ungültiges Datum", + "loadError": "Fehler beim Laden der Freigabedetails" + }, + "uploadFile": { + "title": "Datei hochladen", + "selectFile": "Klicken Sie, um eine Datei auszuwählen", + "preview": "Vorschau", + "uploadProgress": "Upload-Fortschritt", + "upload": "Hochladen", + "success": "Datei erfolgreich hochgeladen", + "error": "Fehler beim Hochladen der Datei" + }, + "filesTable": { + "ariaLabel": "Dateitabelle", + "columns": { + "name": "NAME", + "description": "BESCHREIBUNG", + "size": "GRÖSSE", + "createdAt": "ERSTELLT AM", + "updatedAt": "AKTUALISIERT AM", + "actions": "AKTIONEN" + }, + "actions": { + "menu": "Dateiaktionsmenü", + "preview": "Vorschau", + "edit": "Bearbeiten", + "download": "Herunterladen", + "delete": "Löschen" + } + }, + "sharesTable": { + "ariaLabel": "Freigabetabelle", + "never": "Nie", + "columns": { + "name": "NAME", + "createdAt": "ERSTELLT AM", + "expiresAt": "LÄUFT AB", + "status": "STATUS", + "security": "SICHERHEIT", + "files": "DATEIEN", + "recipients": "EMPFÄNGER", + "actions": "AKTIONEN" + }, + "status": { + "neverExpires": "Läuft nie ab", + "active": "Aktiv", + "expired": "Abgelaufen" + }, + "security": { + "protected": "Geschützt", + "public": "Öffentlich" + }, + "filesCount": "{{count}} Dateien", + "recipientsCount": "{{count}} Empfänger", + "actions": { + "menu": "Freigabeaktionsmenü", + "edit": "Bearbeiten", + "manageFiles": "Dateien verwalten", + "manageRecipients": "Empfänger verwalten", + "viewDetails": "Details anzeigen", + "generateLink": "Link generieren", + "editLink": "Link bearbeiten", + "copyLink": "Link kopieren", + "notifyRecipients": "Empfänger benachrichtigen", + "delete": "Löschen" + } + }, + "footer": { + "poweredBy": "Powered by", + "kyanHomepage": "Kyantech Homepage" + }, + "fileManager": { + "downloadError": "Fehler beim Herunterladen der Datei", + "updateSuccess": "Datei erfolgreich aktualisiert", + "updateError": "Fehler beim Aktualisieren der Datei", + "deleteSuccess": "Datei erfolgreich gelöscht", + "deleteError": "Fehler beim Löschen der Datei" + }, + "shareManager": { + "deleteSuccess": "Freigabe erfolgreich gelöscht", + "deleteError": "Fehler beim Löschen der Freigabe", + "updateSuccess": "Freigabe erfolgreich aktualisiert", + "updateError": "Fehler beim Aktualisieren der Freigabe", + "filesUpdateSuccess": "Dateien erfolgreich aktualisiert", + "filesUpdateError": "Fehler beim Aktualisieren der Dateien", + "recipientsUpdateSuccess": "Empfänger erfolgreich aktualisiert", + "recipientsUpdateError": "Fehler beim Aktualisieren der Empfänger", + "linkGenerateSuccess": "Freigabelink erfolgreich generiert", + "linkGenerateError": "Fehler beim Generieren des Freigabelinks", + "notifyLoading": "Benachrichtigungen werden gesendet...", + "notifySuccess": "Empfänger erfolgreich benachrichtigt", + "notifyError": "Fehler beim Benachrichtigen der Empfänger" + }, + "quickAccess": { + "files": { + "title": "Meine Dateien", + "description": "Zugriff und Verwaltung Ihrer hochgeladenen Dateien" + }, + "shares": { + "title": "Meine Freigaben", + "description": "Anzeigen und Verwalten Ihrer geteilten Dateien" + } + }, + "recentFiles": { + "title": "Kürzlich hochgeladen", + "viewAll": "Alle anzeigen", + "uploadFile": "Datei hochladen", + "noFiles": "Noch keine Dateien hochgeladen" + }, + "recentShares": { + "title": "Kürzlich geteilte", + "viewAll": "Alle anzeigen", + "createShare": "Freigabe erstellen", + "noShares": "Noch keine Freigaben erstellt", + "createFirst": "Erstellen Sie Ihre erste Freigabe" + }, + "storageUsage": { + "title": "Speichernutzung", + "ariaLabel": "Fortschrittsbalken der Speichernutzung", + "used": "{{size}} genutzt", + "available": "{{size}} verfügbar" + }, + "dashboard": { + "loadError": "Fehler beim Laden der Dashboard-Daten", + "linkCopied": "Link in die Zwischenablage kopiert", + "pageTitle": "Übersicht", + "breadcrumb": "Übersicht" + }, + "emptyState": { + "noFiles": "Noch keine Dateien hochgeladen", + "uploadFile": "Datei hochladen" + }, + "files": { + "title": "Alle Dateien", + "uploadFile": "Datei hochladen", + "loadError": "Fehler beim Laden der Dateien", + "pageTitle": "Meine Dateien", + "breadcrumb": "Meine Dateien" + }, + "searchBar": { + "placeholder": "Dateien suchen...", + "results": "Gefunden {{filtered}} von {{total}} Dateien" + }, + "forgotPassword": { + "emailLabel": "E-Mail-Adresse", + "emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein", + "sending": "Wird gesendet...", + "submit": "Anweisungen zum Zurücksetzen senden", + "backToLogin": "Zurück zur Anmeldung", + "title": "Passwort vergessen", + "description": "Geben Sie Ihre E-Mail-Adresse ein und wir senden Ihnen Anweisungen zum Zurücksetzen Ihres Passworts.", + "resetInstructions": "Anweisungen zum Zurücksetzen wurden an Ihre E-Mail gesendet", + "pageTitle": "Passwort vergessen" + }, + "home": { + "description": "Die Open-Source-Alternative zu WeTransfer. Teilen Sie Dateien sicher, ohne Tracking oder Einschränkungen.", + "documentation": "Dokumentation", + "starOnGithub": "Auf GitHub Sternchen vergeben", + "privacyMessage": "Mit Blick auf den Datenschutz entwickelt. Ihre Dateien sind vor dem Hochladen nur für diejenigen zugänglich, die den Freigabelink haben. Immer kostenlos und Open Source.", + "header": { + "fileSharing": "Dateifreigabe", + "tagline": "einfach und kostenlos" + }, + "pageTitle": "Startseite" + }, + "profile": { + "password": { + "title": "Passwort ändern", + "newPassword": "Neues Passwort", + "confirmPassword": "Neues Passwort bestätigen", + "updateButton": "Passwort aktualisieren" + }, + "form": { + "title": "Profilinformationen", + "firstName": "Vorname", + "lastName": "Nachname", + "username": "Benutzername", + "email": "E-Mail", + "updateButton": "Profil aktualisieren" + }, + "header": { + "title": "Profil", + "subtitle": "Verwalten Sie Ihre persönlichen Informationen und Ihr Passwort" + }, + "picture": { + "title": "Profilbild", + "description": "Klicken Sie auf das Kamerasymbol, um Ihr Profilbild zu ändern", + "uploadPhoto": "Foto hochladen", + "removePhoto": "Foto entfernen" + }, + "errors": { + "loadFailed": "Fehler beim Laden der Benutzerdaten", + "updateFailed": "Fehler beim Aktualisieren des Profils", + "passwordFailed": "Fehler beim Aktualisieren des Passworts", + "imageFailed": "Fehler beim Aktualisieren des Profilbilds", + "imageRemoveFailed": "Fehler beim Entfernen des Profilbilds" + }, + "messages": { + "noChanges": "Keine Änderungen zum Speichern", + "updateSuccess": "Profil erfolgreich aktualisiert", + "fillPasswords": "Bitte beide Passwortfelder ausfüllen", + "passwordSuccess": "Passwort erfolgreich aktualisiert", + "imageSuccess": "Profilbild erfolgreich aktualisiert", + "imageRemoved": "Profilbild erfolgreich entfernt" + }, + "pageTitle": "Profil" + }, + "resetPassword": { + "pageTitle": "Passwort zurücksetzen", + "header": { + "title": "Passwort zurücksetzen", + "description": "Geben Sie unten Ihr neues Passwort ein" + }, + "form": { + "newPassword": "Neues Passwort", + "newPasswordPlaceholder": "Geben Sie Ihr neues Passwort ein", + "confirmPassword": "Neues Passwort bestätigen", + "confirmPasswordPlaceholder": "Bestätigen Sie Ihr neues Passwort", + "resetting": "Passwort wird zurückgesetzt...", + "submit": "Passwort zurücksetzen", + "backToLogin": "Zurück zur Anmeldung" + }, + "messages": { + "success": "Passwort erfolgreich zurückgesetzt" + }, + "errors": { + "serverError": "Fehler beim Zurücksetzen des Passworts. Bitte versuchen Sie es erneut.", + "invalidToken": "Ungültiges oder fehlendes Zurücksetzungstoken" + } + }, + "settings": { + "groups": { + "defaultDescription": "Konfigurationsoptionen", + "general": { + "title": "Allgemein", + "description": "Grundlegende Anwendungseinstellungen" + }, + "email": { + "title": "E-Mail", + "description": "Konfiguration des E-Mail-Servers" + }, + "security": { + "title": "Sicherheit", + "description": "Sicherheits- und Authentifizierungseinstellungen" + }, + "storage": { + "title": "Speicher", + "description": "Konfiguration des Dateispeichers" + } + }, + "fields": { + "noDescription": "Keine Beschreibung verfügbar", + "appLogo": { + "title": "Anwendungslogo", + "description": "Logo-Bild der Anwendung" + }, + "appName": { + "title": "Anwendungsname", + "description": "Anwendungsname, der den Benutzern angezeigt wird" + }, + "appDescription": { + "title": "Anwendungsbeschreibung", + "description": "Kurze Beschreibung der Anwendung" + }, + "showHomePage": { + "title": "Startseite anzeigen", + "description": "Startseite nach der Installation anzeigen" + }, + "smtpEnabled": { + "title": "SMTP aktiviert", + "description": "SMTP-E-Mail-Funktionalität aktivieren oder deaktivieren" + }, + "smtpHost": { + "title": "SMTP-Server", + "description": "Adresse des SMTP-Servers" + }, + "smtpPort": { + "title": "SMTP-Port", + "description": "Port des SMTP-Servers" + }, + "smtpUser": { + "title": "SMTP-Benutzer", + "description": "Benutzername für die SMTP-Authentifizierung" + }, + "smtpPass": { + "title": "SMTP-Passwort", + "description": "Passwort für die SMTP-Authentifizierung" + }, + "smtpFromName": { + "title": "Absendername", + "description": "Anzeigename für gesendete E-Mails" + }, + "smtpFromEmail": { + "title": "Absender-E-Mail", + "description": "E-Mail-Adresse des Absenders" + }, + "maxLoginAttempts": { + "title": "Maximale Anmeldeversuche", + "description": "Maximale Anzahl von Anmeldeversuchen, bevor gesperrt wird" + }, + "loginBlockDuration": { + "title": "Sperrdauer", + "description": "Dauer (in Sekunden) der Sperre nach Überschreiten der Versuche" + }, + "passwordMinLength": { + "title": "Minimale Passwortlänge", + "description": "Minimale Anzahl an Zeichen für Passwörter" + }, + "passwordResetTokenExpiration": { + "title": "Ablauf des Reset-Tokens", + "description": "Gültigkeitsdauer (in Sekunden) des Passwort-Reset-Tokens" + }, + "maxFileSize": { + "title": "Maximale Dateigröße", + "description": "Maximal erlaubte Dateigröße für Uploads (in Bytes)" + }, + "maxTotalStoragePerUser": { + "title": "Maximaler Speicher pro Benutzer", + "description": "Gesamtspeicherlimit pro Benutzer (in Bytes)" + } + }, + "buttons": { + "save": "{{group}} speichern" + }, + "errors": { + "loadFailed": "Fehler beim Laden der Einstellungen", + "updateFailed": "Fehler beim Aktualisieren der Einstellungen" + }, + "messages": { + "noChanges": "Keine Änderungen zum Speichern", + "updateSuccess": "{{group}}-Einstellungen erfolgreich aktualisiert" + }, + "title": "Einstellungen", + "breadcrumb": "Einstellungen", + "pageTitle": "Einstellungen" + }, + "share": { + "errors": { + "invalidPassword": "Ungültiges Passwort. Bitte versuchen Sie es erneut.", + "loadFailed": "Fehler beim Laden der Freigabe", + "downloadFailed": "Fehler beim Herunterladen der Datei" + }, + "messages": { + "downloadStarted": "Download gestartet" + }, + "password": { + "title": "Passwortgeschützte Freigabe", + "protected": "Diese Freigabe ist passwortgeschützt", + "incorrect": "Falsches Passwort. Bitte versuchen Sie es erneut.", + "label": "Passwort", + "placeholder": "Passwort der Freigabe eingeben", + "submit": "Absenden" + }, + "details": { + "untitled": "Unbenannte Freigabe", + "created": "Erstellt: {{date}}", + "expires": "Läuft ab: {{date}}" + }, + "notFound": { + "title": "Freigabe nicht gefunden", + "description": "Diese Freigabe wurde möglicherweise gelöscht oder ist abgelaufen." + }, + "pageTitle": "Freigabe" + }, + "shares": { + "errors": { + "loadFailed": "Fehler beim Laden der Freigaben", + "notifyFailed": "Fehler beim Benachrichtigen der Empfänger", + "smtpConfigFailed": "Fehler beim Laden der SMTP-Konfiguration" + }, + "messages": { + "linkCopied": "Link in die Zwischenablage kopiert", + "recipientsNotified": "Empfänger erfolgreich benachrichtigt" + }, + "empty": { + "message": "Noch keine Freigaben erstellt", + "createButton": "Freigabe erstellen" + }, + "header": { + "title": "Meine Freigaben", + "myShares": "Meine Freigaben" + }, + "search": { + "title": "Alle Freigaben", + "createButton": "Freigabe erstellen", + "placeholder": "Freigaben suchen...", + "results": "Gefunden {{filtered}} von {{total}} Freigaben" + }, + "pageTitle": "Freigaben" + }, + "users": { + "modes": { + "create": "erstellen", + "edit": "bearbeiten" + }, + "errors": { + "loadFailed": "Fehler beim Laden der Benutzer", + "submitFailed": "Fehler beim {{mode}} des Benutzers", + "deleteFailed": "Fehler beim Löschen des Benutzers", + "statusUpdateFailed": "Fehler beim Aktualisieren des Benutzerstatus" + }, + "messages": { + "createSuccess": "Benutzer erfolgreich erstellt", + "updateSuccess": "Benutzer erfolgreich aktualisiert", + "deleteSuccess": "Benutzer erfolgreich gelöscht", + "activateSuccess": "Benutzer erfolgreich aktiviert", + "deactivateSuccess": "Benutzer erfolgreich deaktiviert" + }, + "actions": { + "edit": "Bearbeiten", + "activate": "Aktivieren", + "deactivate": "Deaktivieren", + "delete": "Löschen" + }, + "delete": { + "title": "Löschen des Benutzers bestätigen", + "confirmation": "Sind Sie sicher, dass Sie den Benutzer {{firstName}} {{lastName}} löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", + "confirm": "Benutzer löschen" + }, + "form": { + "titleCreate": "Neuen Benutzer hinzufügen", + "titleEdit": "Benutzer bearbeiten", + "firstName": "Vorname", + "lastName": "Nachname", + "username": "Benutzername", + "email": "E-Mail", + "password": "Passwort", + "newPassword": "Neues Passwort (optional)", + "passwordPlaceholder": "Leer lassen, um das aktuelle Passwort zu behalten", + "role": "Rolle", + "roleUser": "Benutzer", + "roleAdmin": "Administrator", + "create": "Erstellen", + "save": "Speichern" + }, + "status": { + "title": "Statusänderung bestätigen", + "confirmation": "Sind Sie sicher, dass Sie den Benutzer {{firstName}} {{lastName}} {{action}} möchten?", + "activate": "aktivieren", + "deactivate": "deaktivieren", + "user": "Benutzer" + }, + "header": { + "title": "Benutzerverwaltung", + "addUser": "Benutzer hinzufügen", + "management": "Benutzerverwaltung" + }, + "table": { + "user": "BENUTZER", + "email": "E-MAIL", + "status": "STATUS", + "role": "ROLLE", + "actions": "AKTIONEN", + "active": "Aktiv", + "inactive": "Inaktiv", + "admin": "Administrator", + "userr": "Benutzer" + } + }, + "logo": { + "labels": { + "appLogo": "Anwendungslogo" + }, + "buttons": { + "upload": "Logo hochladen", + "remove": "Logo entfernen" + }, + "messages": { + "uploadSuccess": "Logo erfolgreich hochgeladen", + "removeSuccess": "Logo erfolgreich entfernt" + }, + "errors": { + "uploadFailed": "Fehler beim Hochladen des Logos", + "removeFailed": "Fehler beim Entfernen des Logos" + } + }, + "navbar": { + "logoAlt": "Anwendungslogo", + "profileMenu": "Profilmenü", + "profile": "Profil", + "settings": "Einstellungen", + "usersManagement": "Benutzerverwaltung", + "logout": "Abmelden" + } +} \ No newline at end of file diff --git a/apps/app/messages/en-US.json b/apps/app/messages/en-US.json new file mode 100644 index 0000000..6385c46 --- /dev/null +++ b/apps/app/messages/en-US.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "Welcome to", + "signInToContinue": "Sign in to continue", + "emailLabel": "Email Address", + "emailPlaceholder": "Enter your email", + "passwordLabel": "Password", + "passwordPlaceholder": "Enter your password", + "signIn": "Sign In", + "signingIn": "Signing in...", + "forgotPassword": "Forgot password?", + "pageTitle": "Login" + }, + "errors": { + "invalidCredentials": "Invalid email or password", + "userNotFound": "User not found", + "accountLocked": "Account locked. Please try again later", + "unexpectedError": "An unexpected error occurred. Please try again" + }, + "validation": { + "invalidEmail": "Invalid email address", + "passwordMinLength": "Password must be at least 6 characters", + "firstNameRequired": "First name is required", + "lastNameRequired": "Last name is required", + "usernameLength": "Username must be at least 3 characters", + "usernameSpaces": "Username cannot contain spaces", + "passwordLength": "Password must be at least 8 characters", + "passwordsMatch": "Passwords do not match", + "emailRequired": "Email is required", + "passwordRequired": "Password is required" + }, + "fileSelector": { + "availableFiles": "Available Files ({{count}})", + "shareFiles": "Share Files ({{count}})", + "searchPlaceholder": "Search files...", + "noMatchingFiles": "No matching files", + "noAvailableFiles": "No files available", + "noFilesInShare": "No files in share", + "saveChanges": "Save Changes" + }, + "recipientSelector": { + "emailPlaceholder": "Enter recipient email", + "add": "Add", + "recipients": "Recipients ({{count}})", + "notifyAll": "Notify All", + "noRecipients": "No recipients added yet", + "addSuccess": "Recipient added successfully", + "addError": "Failed to add recipient", + "removeSuccess": "Recipient removed successfully", + "removeError": "Failed to remove recipient", + "sendingNotifications": "Sending notifications...", + "notifySuccess": "Recipients notified successfully", + "notifyError": "Failed to notify recipients" + }, + "navigation": { + "dashboard": "Dashboard" + }, + "common": { + "loading": "Loading, please wait...", + "cancel": "Cancel", + "save": "Save", + "delete": "Delete", + "close": "Close", + "download": "Download", + "unexpectedError": "An unexpected error occurred. Please try again.", + "yes": "Yes", + "no": "No", + "dashboard": "Dashboard" + }, + "createShare": { + "title": "Create Share", + "nameLabel": "Share Name", + "expirationLabel": "Expiration Date", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "Max Views", + "maxViewsPlaceholder": "Leave empty for unlimited", + "passwordProtection": "Password Protected", + "passwordLabel": "Password", + "create": "Create Share", + "success": "Share created successfully", + "error": "Failed to create share" + }, + "fileActions": { + "editFile": "Edit File", + "nameLabel": "Name", + "namePlaceholder": "Enter new name", + "extension": "Extension", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Enter file description", + "deleteFile": "Delete File", + "deleteConfirmation": "Are you sure you want to delete \"{{fileName}}\"?", + "deleteWarning": "This action cannot be undone." + }, + "filePreview": { + "loading": "Loading preview...", + "notAvailable": "Preview not available", + "downloadToView": "Download file to view contents", + "audioNotSupported": "Your browser does not support the audio element", + "videoNotSupported": "Your browser does not support the video element", + "loadError": "Failed to load preview", + "downloadError": "Failed to download file" + }, + "generateShareLink": { + "generateTitle": "Generate Share Link", + "updateTitle": "Update Share Link", + "generateDescription": "Generate a link to share your files", + "updateDescription": "Update the alias for this share link", + "aliasPlaceholder": "Enter alias", + "linkReady": "Your share link is ready:", + "generateButton": "Generate Link", + "updateButton": "Update Link", + "copyButton": "Copy Link", + "success": "Link generated successfully", + "error": "Failed to generate link", + "copied": "Link copied to clipboard" + }, + "shareActions": { + "deleteTitle": "Delete Share", + "deleteConfirmation": "Are you sure you want to delete this share? This action cannot be undone.", + "editTitle": "Edit Share", + "nameLabel": "Share Name", + "expirationLabel": "Expiration Date", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "Max Views", + "maxViewsPlaceholder": "Leave empty for unlimited", + "passwordProtection": "Password Protected", + "passwordLabel": "Password", + "passwordPlaceholder": "Enter password", + "newPasswordLabel": "New Password (leave empty to keep current)", + "newPasswordPlaceholder": "Enter new password", + "manageFilesTitle": "Manage Files", + "manageRecipientsTitle": "Manage Recipients", + "editSuccess": "Share updated successfully", + "editError": "Failed to update share" + }, + "shareDetails": { + "title": "Share Details", + "subtitle": "Detailed information about this share", + "basicInfo": "Basic Information", + "name": "Name", + "untitled": "Untitled", + "views": "Views", + "dates": "Dates", + "created": "Created", + "expires": "Expires", + "never": "Never", + "security": "Security", + "passwordProtected": "Password Protected", + "publicAccess": "Public Access", + "maxViews": "Max Views: {{count}}", + "files": "Files ({{count}})", + "recipients": "Recipients ({{count}})", + "notAvailable": "N/A", + "invalidDate": "Invalid date", + "loadError": "Failed to load share details" + }, + "uploadFile": { + "title": "Upload File", + "selectFile": "Click to select a file", + "preview": "Preview", + "uploadProgress": "Upload progress", + "upload": "Upload", + "success": "File uploaded successfully", + "error": "Failed to upload file" + }, + "filesTable": { + "ariaLabel": "Files table", + "columns": { + "name": "NAME", + "description": "DESCRIPTION", + "size": "SIZE", + "createdAt": "CREATED AT", + "updatedAt": "UPDATED AT", + "actions": "ACTIONS" + }, + "actions": { + "menu": "File actions menu", + "preview": "Preview", + "edit": "Edit", + "download": "Download", + "delete": "Delete" + } + }, + "sharesTable": { + "ariaLabel": "Shares table", + "never": "Never", + "columns": { + "name": "NAME", + "createdAt": "CREATED AT", + "expiresAt": "EXPIRES AT", + "status": "STATUS", + "security": "SECURITY", + "files": "FILES", + "recipients": "RECIPIENTS", + "actions": "ACTIONS" + }, + "status": { + "neverExpires": "Never Expires", + "active": "Active", + "expired": "Expired" + }, + "security": { + "protected": "Protected", + "public": "Public" + }, + "filesCount": "{{count}} files", + "recipientsCount": "{{count}} recipients", + "actions": { + "menu": "Share actions menu", + "edit": "Edit", + "manageFiles": "Manage Files", + "manageRecipients": "Manage Recipients", + "viewDetails": "View Details", + "generateLink": "Generate Link", + "editLink": "Edit Link", + "copyLink": "Copy Link", + "notifyRecipients": "Notify Recipients", + "delete": "Delete" + } + }, + "footer": { + "poweredBy": "Powered by", + "kyanHomepage": "Kyantech homepage" + }, + "fileManager": { + "downloadError": "Failed to download file", + "updateSuccess": "File updated successfully", + "updateError": "Failed to update file", + "deleteSuccess": "File deleted successfully", + "deleteError": "Failed to delete file" + }, + "shareManager": { + "deleteSuccess": "Share deleted successfully", + "deleteError": "Failed to delete share", + "updateSuccess": "Share updated successfully", + "updateError": "Failed to update share", + "filesUpdateSuccess": "Files updated successfully", + "filesUpdateError": "Failed to update files", + "recipientsUpdateSuccess": "Recipients updated successfully", + "recipientsUpdateError": "Failed to update recipients", + "linkGenerateSuccess": "Share link generated successfully", + "linkGenerateError": "Failed to generate share link", + "notifyLoading": "Sending notifications...", + "notifySuccess": "Recipients notified successfully", + "notifyError": "Failed to notify recipients" + }, + "quickAccess": { + "files": { + "title": "My Files", + "description": "Access and manage your uploaded files" + }, + "shares": { + "title": "My Shares", + "description": "View and manage your shared files" + } + }, + "recentFiles": { + "title": "Recent Uploads", + "viewAll": "View All", + "uploadFile": "Upload File", + "noFiles": "No files uploaded yet" + }, + "recentShares": { + "title": "Recent Shares", + "viewAll": "View All", + "createShare": "Create Share", + "noShares": "No shares created yet", + "createFirst": "Create your first share" + }, + "storageUsage": { + "title": "Storage Usage", + "ariaLabel": "Storage usage progress bar", + "used": "{{size}} used", + "available": "{{size}} available" + }, + "dashboard": { + "loadError": "Failed to load dashboard data", + "linkCopied": "Link copied to clipboard", + "pageTitle": "Dashboard", + "breadcrumb": "Dashboard" + }, + "emptyState": { + "noFiles": "No files uploaded yet", + "uploadFile": "Upload File" + }, + "files": { + "title": "All Files", + "uploadFile": "Upload File", + "loadError": "Failed to load files", + "pageTitle": "My Files", + "breadcrumb": "My Files" + }, + "searchBar": { + "placeholder": "Search files...", + "results": "Found {{filtered}} of {{total}} files" + }, + "forgotPassword": { + "emailLabel": "Email Address", + "emailPlaceholder": "Enter your email", + "sending": "Sending...", + "submit": "Send Reset Instructions", + "backToLogin": "Back to Login", + "title": "Forgot Password", + "description": "Enter your email address and we'll send you instructions to reset your password.", + "resetInstructions": "Reset instructions sent to your email", + "pageTitle": "Forgot Password" + }, + "home": { + "description": "The open-source alternative to WeTransfer. Share files securely, without tracking, or limitations.", + "documentation": "Documentation", + "starOnGithub": "Star on GitHub", + "privacyMessage": "Built with privacy in mind. Your files before upload only accessible by those with the sharing link. Forever free and open source.", + "header": { + "fileSharing": "File sharing", + "tagline": "made simple and free" + }, + "pageTitle": "Home" + }, + "profile": { + "password": { + "title": "Change Password", + "newPassword": "New Password", + "confirmPassword": "Confirm New Password", + "updateButton": "Update Password" + }, + "form": { + "title": "Profile Information", + "firstName": "First Name", + "lastName": "Last Name", + "username": "Username", + "email": "Email", + "updateButton": "Update Profile" + }, + "header": { + "title": "Profile", + "subtitle": "Manage your personal information and password" + }, + "picture": { + "title": "Profile Picture", + "description": "Click the camera icon to change your profile picture", + "uploadPhoto": "Upload Photo", + "removePhoto": "Remove Photo" + }, + "errors": { + "loadFailed": "Failed to load user data", + "updateFailed": "Failed to update profile", + "passwordFailed": "Failed to update password", + "imageFailed": "Failed to update profile image", + "imageRemoveFailed": "Failed to remove profile image" + }, + "messages": { + "noChanges": "No changes to save", + "updateSuccess": "Profile updated successfully", + "fillPasswords": "Please fill in both password fields", + "passwordSuccess": "Password updated successfully", + "imageSuccess": "Profile image updated successfully", + "imageRemoved": "Profile image removed successfully" + }, + "pageTitle": "Profile" + }, + "resetPassword": { + "pageTitle": "Reset Password", + "header": { + "title": "Reset Password", + "description": "Enter your new password below" + }, + "form": { + "newPassword": "New Password", + "newPasswordPlaceholder": "Enter your new password", + "confirmPassword": "Confirm New Password", + "confirmPasswordPlaceholder": "Confirm your new password", + "resetting": "Resetting Password...", + "submit": "Reset Password", + "backToLogin": "Back to Login" + }, + "messages": { + "success": "Password reset successfully" + }, + "errors": { + "serverError": "Failed to reset password. Please try again.", + "invalidToken": "Invalid or missing reset token" + } + }, + "settings": { + "groups": { + "defaultDescription": "Configuration options", + "general": { + "title": "General", + "description": "Basic application settings" + }, + "email": { + "title": "Email", + "description": "Email server configuration" + }, + "security": { + "title": "Security", + "description": "Security and authentication settings" + }, + "storage": { + "title": "Storage", + "description": "File storage configuration" + } + }, + "fields": { + "noDescription": "No description available", + "appLogo": { + "title": "Application Logo", + "description": "Application logo image" + }, + "appName": { + "title": "Application Name", + "description": "Application name displayed to users" + }, + "appDescription": { + "title": "Application Description", + "description": "Brief description of the application" + }, + "showHomePage": { + "title": "Show Home Page", + "description": "Show Home Page after installation" + }, + "smtpEnabled": { + "title": "SMTP Enabled", + "description": "Enable or disable SMTP email functionality" + }, + "smtpHost": { + "title": "SMTP Server", + "description": "SMTP server address" + }, + "smtpPort": { + "title": "SMTP Port", + "description": "SMTP server port" + }, + "smtpUser": { + "title": "SMTP Username", + "description": "Username for SMTP authentication" + }, + "smtpPass": { + "title": "SMTP Password", + "description": "Password for SMTP authentication" + }, + "smtpFromName": { + "title": "Sender Name", + "description": "Display name for sent emails" + }, + "smtpFromEmail": { + "title": "Sender Email", + "description": "Sender email address" + }, + "maxLoginAttempts": { + "title": "Maximum Login Attempts", + "description": "Maximum number of login attempts before blocking" + }, + "loginBlockDuration": { + "title": "Block Duration", + "description": "Duration (in seconds) to block after exceeding attempts" + }, + "passwordMinLength": { + "title": "Minimum Password Length", + "description": "Minimum number of characters for passwords" + }, + "passwordResetTokenExpiration": { + "title": "Reset Token Expiration", + "description": "Validity time (in seconds) for password reset token" + }, + "maxFileSize": { + "title": "Maximum File Size", + "description": "Maximum allowed file size for uploads (in bytes)" + }, + "maxTotalStoragePerUser": { + "title": "Maximum Storage Per User", + "description": "Total storage limit per user (in bytes)" + } + }, + "buttons": { + "save": "Save {{group}}" + }, + "errors": { + "loadFailed": "Failed to load settings", + "updateFailed": "Failed to update settings" + }, + "messages": { + "noChanges": "No changes to save", + "updateSuccess": "{{group}} settings updated successfully" + }, + "title": "Settings", + "breadcrumb": "Settings", + "pageTitle": "Settings" + }, + "share": { + "errors": { + "invalidPassword": "Invalid password. Please try again.", + "loadFailed": "Failed to load share", + "downloadFailed": "Failed to download file" + }, + "messages": { + "downloadStarted": "Download started" + }, + "password": { + "title": "Password Protected Share", + "protected": "This share is password protected", + "incorrect": "Incorrect password. Please try again.", + "label": "Password", + "placeholder": "Enter share password", + "submit": "Submit" + }, + "details": { + "untitled": "Untitled Share", + "created": "Created: {{date}}", + "expires": "Expires: {{date}}" + }, + "notFound": { + "title": "Share Not Found", + "description": "This share may have been deleted or expired." + }, + "pageTitle": "Share" + }, + "shares": { + "errors": { + "loadFailed": "Failed to load shares", + "notifyFailed": "Failed to notify recipients", + "smtpConfigFailed": "Failed to load SMTP configuration" + }, + "messages": { + "linkCopied": "Link copied to clipboard", + "recipientsNotified": "Recipients notified successfully" + }, + "empty": { + "message": "No shares created yet", + "createButton": "Create Share" + }, + "header": { + "title": "My Shares", + "myShares": "My Shares" + }, + "search": { + "title": "All Shares", + "createButton": "Create Share", + "placeholder": "Search shares...", + "results": "Found {{filtered}} of {{total}} shares" + }, + "pageTitle": "Shares" + }, + "users": { + "modes": { + "create": "create", + "edit": "edit" + }, + "errors": { + "loadFailed": "Failed to load users", + "submitFailed": "Failed to {{mode}} user", + "deleteFailed": "Failed to delete user", + "statusUpdateFailed": "Failed to update user status" + }, + "messages": { + "createSuccess": "User created successfully", + "updateSuccess": "User updated successfully", + "deleteSuccess": "User deleted successfully", + "activateSuccess": "User activated successfully", + "deactivateSuccess": "User deactivated successfully" + }, + "actions": { + "edit": "Edit", + "activate": "Activate", + "deactivate": "Deactivate", + "delete": "Delete" + }, + "delete": { + "title": "Confirm Delete User", + "confirmation": "Are you sure you want to delete user {{firstName}} {{lastName}}? This action cannot be undone.", + "confirm": "Delete User" + }, + "form": { + "titleCreate": "Add New User", + "titleEdit": "Edit User", + "firstName": "First Name", + "lastName": "Last Name", + "username": "Username", + "email": "Email", + "password": "Password", + "newPassword": "New Password (optional)", + "passwordPlaceholder": "Leave blank to keep current password", + "role": "Role", + "roleUser": "User", + "roleAdmin": "Admin", + "create": "Create", + "save": "Save" + }, + "status": { + "title": "Confirm Status Change", + "confirmation": "Are you sure you want to {{action}} user {{firstName}} {{lastName}}?", + "activate": "activate", + "deactivate": "deactivate", + "user": "User" + }, + "header": { + "title": "User Management", + "addUser": "Add User", + "management": "User Management" + }, + "table": { + "user": "USER", + "email": "EMAIL", + "status": "STATUS", + "role": "ROLE", + "actions": "ACTIONS", + "active": "Active", + "inactive": "Inactive", + "admin": "Admin", + "userr": "User" + } + }, + "logo": { + "labels": { + "appLogo": "App Logo" + }, + "buttons": { + "upload": "Upload Logo", + "remove": "Remove Logo" + }, + "messages": { + "uploadSuccess": "Logo uploaded successfully", + "removeSuccess": "Logo removed successfully" + }, + "errors": { + "uploadFailed": "Failed to upload logo", + "removeFailed": "Failed to remove logo" + } + }, + "navbar": { + "logoAlt": "App Logo", + "profileMenu": "Profile Menu", + "profile": "Profile", + "settings": "Settings", + "usersManagement": "Users Management", + "logout": "Log Out" + } +} \ No newline at end of file diff --git a/apps/app/messages/es-ES.json b/apps/app/messages/es-ES.json new file mode 100644 index 0000000..b41f7a2 --- /dev/null +++ b/apps/app/messages/es-ES.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "Bienvenido a", + "signInToContinue": "Inicia sesión para continuar", + "emailLabel": "Dirección de correo electrónico", + "emailPlaceholder": "Introduce tu correo electrónico", + "passwordLabel": "Contraseña", + "passwordPlaceholder": "Introduce tu contraseña", + "signIn": "Iniciar sesión", + "signingIn": "Iniciando sesión...", + "forgotPassword": "¿Olvidaste tu contraseña?", + "pageTitle": "Iniciar sesión" + }, + "errors": { + "invalidCredentials": "Correo electrónico o contraseña inválidos", + "userNotFound": "Usuario no encontrado", + "accountLocked": "Cuenta bloqueada. Por favor, inténtalo de nuevo más tarde", + "unexpectedError": "Ocurrió un error inesperado. Por favor, inténtalo de nuevo" + }, + "validation": { + "invalidEmail": "Dirección de correo electrónico no válida", + "passwordMinLength": "La contraseña debe tener al menos 6 caracteres", + "firstNameRequired": "Se requiere el nombre", + "lastNameRequired": "Se requiere el apellido", + "usernameLength": "El nombre de usuario debe tener al menos 3 caracteres", + "usernameSpaces": "El nombre de usuario no puede contener espacios", + "passwordLength": "La contraseña debe tener al menos 8 caracteres", + "passwordsMatch": "Las contraseñas no coinciden", + "emailRequired": "Se requiere el correo electrónico", + "passwordRequired": "Se requiere la contraseña" + }, + "fileSelector": { + "availableFiles": "Archivos disponibles ({{count}})", + "shareFiles": "Compartir archivos ({{count}})", + "searchPlaceholder": "Buscar archivos...", + "noMatchingFiles": "No hay archivos que coincidan", + "noAvailableFiles": "No hay archivos disponibles", + "noFilesInShare": "No hay archivos compartidos", + "saveChanges": "Guardar cambios" + }, + "recipientSelector": { + "emailPlaceholder": "Introduce el correo del destinatario", + "add": "Agregar", + "recipients": "Destinatarios ({{count}})", + "notifyAll": "Notificar a todos", + "noRecipients": "Aún no se han agregado destinatarios", + "addSuccess": "Destinatario agregado exitosamente", + "addError": "Error al agregar el destinatario", + "removeSuccess": "Destinatario eliminado exitosamente", + "removeError": "Error al eliminar el destinatario", + "sendingNotifications": "Enviando notificaciones...", + "notifySuccess": "Destinatarios notificados exitosamente", + "notifyError": "Error al notificar a los destinatarios" + }, + "navigation": { + "dashboard": "Panel de control" + }, + "common": { + "loading": "Cargando, por favor espera...", + "cancel": "Cancelar", + "save": "Guardar", + "delete": "Eliminar", + "close": "Cerrar", + "download": "Descargar", + "unexpectedError": "Ocurrió un error inesperado. Por favor, inténtalo de nuevo.", + "yes": "Sí", + "no": "No", + "dashboard": "Panel de control" + }, + "createShare": { + "title": "Crear compartición", + "nameLabel": "Nombre de la compartición", + "expirationLabel": "Fecha de expiración", + "expirationPlaceholder": "MM/DD/AAAA HH:MM", + "maxViewsLabel": "Máximo de visualizaciones", + "maxViewsPlaceholder": "Dejar vacío para ilimitado", + "passwordProtection": "Protección por contraseña", + "passwordLabel": "Contraseña", + "create": "Crear compartición", + "success": "Compartición creada exitosamente", + "error": "Error al crear la compartición" + }, + "fileActions": { + "editFile": "Editar archivo", + "nameLabel": "Nombre", + "namePlaceholder": "Introduce un nuevo nombre", + "extension": "Extensión", + "descriptionLabel": "Descripción", + "descriptionPlaceholder": "Introduce una descripción del archivo", + "deleteFile": "Eliminar archivo", + "deleteConfirmation": "¿Estás seguro de que deseas eliminar \"{{fileName}}\"?", + "deleteWarning": "Esta acción no se puede deshacer." + }, + "filePreview": { + "loading": "Cargando vista previa...", + "notAvailable": "Vista previa no disponible", + "downloadToView": "Descarga el archivo para ver su contenido", + "audioNotSupported": "Tu navegador no soporta el elemento de audio", + "videoNotSupported": "Tu navegador no soporta el elemento de video", + "loadError": "Error al cargar la vista previa", + "downloadError": "Error al descargar el archivo" + }, + "generateShareLink": { + "generateTitle": "Generar enlace de compartición", + "updateTitle": "Actualizar enlace de compartición", + "generateDescription": "Genera un enlace para compartir tus archivos", + "updateDescription": "Actualiza el alias para este enlace de compartición", + "aliasPlaceholder": "Introduce un alias", + "linkReady": "Tu enlace de compartición está listo:", + "generateButton": "Generar enlace", + "updateButton": "Actualizar enlace", + "copyButton": "Copiar enlace", + "success": "Enlace generado exitosamente", + "error": "Error al generar el enlace", + "copied": "Enlace copiado al portapapeles" + }, + "shareActions": { + "deleteTitle": "Eliminar compartición", + "deleteConfirmation": "¿Estás seguro de que deseas eliminar esta compartición? Esta acción no se puede deshacer.", + "editTitle": "Editar compartición", + "nameLabel": "Nombre de la compartición", + "expirationLabel": "Fecha de expiración", + "expirationPlaceholder": "MM/DD/AAAA HH:MM", + "maxViewsLabel": "Máximo de visualizaciones", + "maxViewsPlaceholder": "Dejar vacío para ilimitado", + "passwordProtection": "Protegido con contraseña", + "passwordLabel": "Contraseña", + "passwordPlaceholder": "Introduce la contraseña", + "newPasswordLabel": "Nueva contraseña (dejar vacío para mantener la actual)", + "newPasswordPlaceholder": "Introduce la nueva contraseña", + "manageFilesTitle": "Gestionar archivos", + "manageRecipientsTitle": "Gestionar destinatarios", + "editSuccess": "Compartición actualizada exitosamente", + "editError": "Error al actualizar la compartición" + }, + "shareDetails": { + "title": "Detalles de la compartición", + "subtitle": "Información detallada sobre esta compartición", + "basicInfo": "Información básica", + "name": "Nombre", + "untitled": "Sin título", + "views": "Visualizaciones", + "dates": "Fechas", + "created": "Creada", + "expires": "Expira", + "never": "Nunca", + "security": "Seguridad", + "passwordProtected": "Protegido con contraseña", + "publicAccess": "Acceso público", + "maxViews": "Máximo de visualizaciones: {{count}}", + "files": "Archivos ({{count}})", + "recipients": "Destinatarios ({{count}})", + "notAvailable": "N/D", + "invalidDate": "Fecha inválida", + "loadError": "Error al cargar los detalles de la compartición" + }, + "uploadFile": { + "title": "Subir archivo", + "selectFile": "Haz clic para seleccionar un archivo", + "preview": "Vista previa", + "uploadProgress": "Progreso de la subida", + "upload": "Subir", + "success": "Archivo subido exitosamente", + "error": "Error al subir el archivo" + }, + "filesTable": { + "ariaLabel": "Tabla de archivos", + "columns": { + "name": "NOMBRE", + "description": "DESCRIPCIÓN", + "size": "TAMAÑO", + "createdAt": "CREADO", + "updatedAt": "ACTUALIZADO", + "actions": "ACCIONES" + }, + "actions": { + "menu": "Menú de acciones del archivo", + "preview": "Vista previa", + "edit": "Editar", + "download": "Descargar", + "delete": "Eliminar" + } + }, + "sharesTable": { + "ariaLabel": "Tabla de comparticiones", + "never": "Nunca", + "columns": { + "name": "NOMBRE", + "createdAt": "CREADO", + "expiresAt": "EXPIRA", + "status": "ESTADO", + "security": "SEGURIDAD", + "files": "ARCHIVOS", + "recipients": "DESTINATARIOS", + "actions": "ACCIONES" + }, + "status": { + "neverExpires": "Nunca expira", + "active": "Activa", + "expired": "Expirada" + }, + "security": { + "protected": "Protegida", + "public": "Pública" + }, + "filesCount": "{{count}} archivos", + "recipientsCount": "{{count}} destinatarios", + "actions": { + "menu": "Menú de acciones de la compartición", + "edit": "Editar", + "manageFiles": "Gestionar archivos", + "manageRecipients": "Gestionar destinatarios", + "viewDetails": "Ver detalles", + "generateLink": "Generar enlace", + "editLink": "Editar enlace", + "copyLink": "Copiar enlace", + "notifyRecipients": "Notificar destinatarios", + "delete": "Eliminar" + } + }, + "footer": { + "poweredBy": "Desarrollado por", + "kyanHomepage": "Página principal de Kyantech" + }, + "fileManager": { + "downloadError": "Error al descargar el archivo", + "updateSuccess": "Archivo actualizado exitosamente", + "updateError": "Error al actualizar el archivo", + "deleteSuccess": "Archivo eliminado exitosamente", + "deleteError": "Error al eliminar el archivo" + }, + "shareManager": { + "deleteSuccess": "Compartición eliminada exitosamente", + "deleteError": "Error al eliminar la compartición", + "updateSuccess": "Compartición actualizada exitosamente", + "updateError": "Error al actualizar la compartición", + "filesUpdateSuccess": "Archivos actualizados exitosamente", + "filesUpdateError": "Error al actualizar los archivos", + "recipientsUpdateSuccess": "Destinatarios actualizados exitosamente", + "recipientsUpdateError": "Error al actualizar los destinatarios", + "linkGenerateSuccess": "Enlace de compartición generado exitosamente", + "linkGenerateError": "Error al generar el enlace de compartición", + "notifyLoading": "Enviando notificaciones...", + "notifySuccess": "Destinatarios notificados exitosamente", + "notifyError": "Error al notificar a los destinatarios" + }, + "quickAccess": { + "files": { + "title": "Mis archivos", + "description": "Accede y gestiona tus archivos subidos" + }, + "shares": { + "title": "Mis comparticiones", + "description": "Visualiza y gestiona tus archivos compartidos" + } + }, + "recentFiles": { + "title": "Subidas recientes", + "viewAll": "Ver todo", + "uploadFile": "Subir archivo", + "noFiles": "Aún no se han subido archivos" + }, + "recentShares": { + "title": "Comparticiones recientes", + "viewAll": "Ver todo", + "createShare": "Crear compartición", + "noShares": "Aún no se han creado comparticiones", + "createFirst": "Crea tu primera compartición" + }, + "storageUsage": { + "title": "Uso de almacenamiento", + "ariaLabel": "Barra de progreso del uso de almacenamiento", + "used": "{{size}} usados", + "available": "{{size}} disponibles" + }, + "dashboard": { + "loadError": "Error al cargar los datos del tablero", + "linkCopied": "Enlace copiado al portapapeles", + "pageTitle": "Panel de control", + "breadcrumb": "Panel de control" + }, + "emptyState": { + "noFiles": "Aún no se han subido archivos", + "uploadFile": "Subir archivo" + }, + "files": { + "title": "Todos los archivos", + "uploadFile": "Subir archivo", + "loadError": "Error al cargar los archivos", + "pageTitle": "Mis archivos", + "breadcrumb": "Mis archivos" + }, + "searchBar": { + "placeholder": "Buscar archivos...", + "results": "Se encontraron {{filtered}} de {{total}} archivos" + }, + "forgotPassword": { + "emailLabel": "Dirección de correo electrónico", + "emailPlaceholder": "Introduce tu correo electrónico", + "sending": "Enviando...", + "submit": "Enviar instrucciones de restablecimiento", + "backToLogin": "Volver a iniciar sesión", + "title": "Recuperar contraseña", + "description": "Introduce tu dirección de correo electrónico y te enviaremos instrucciones para restablecer tu contraseña.", + "resetInstructions": "Instrucciones de restablecimiento enviadas a tu correo electrónico", + "pageTitle": "Recuperar contraseña" + }, + "home": { + "description": "La alternativa de código abierto a WeTransfer. Comparte archivos de forma segura, sin rastreo ni limitaciones.", + "documentation": "Documentación", + "starOnGithub": "Dale una estrella en GitHub", + "privacyMessage": "Construido con la privacidad en mente. Tus archivos antes de la subida son accesibles solo para aquellos con el enlace de compartición. Siempre libre y de código abierto.", + "header": { + "fileSharing": "Compartir archivos", + "tagline": "simple y gratuito" + }, + "pageTitle": "Inicio" + }, + "profile": { + "password": { + "title": "Cambiar contraseña", + "newPassword": "Nueva contraseña", + "confirmPassword": "Confirmar nueva contraseña", + "updateButton": "Actualizar contraseña" + }, + "form": { + "title": "Información del perfil", + "firstName": "Nombre", + "lastName": "Apellido", + "username": "Nombre de usuario", + "email": "Correo electrónico", + "updateButton": "Actualizar perfil" + }, + "header": { + "title": "Perfil", + "subtitle": "Gestiona tu información personal y contraseña" + }, + "picture": { + "title": "Foto de perfil", + "description": "Haz clic en el icono de la cámara para cambiar tu foto de perfil", + "uploadPhoto": "Subir foto", + "removePhoto": "Eliminar foto" + }, + "errors": { + "loadFailed": "Error al cargar los datos del usuario", + "updateFailed": "Error al actualizar el perfil", + "passwordFailed": "Error al actualizar la contraseña", + "imageFailed": "Error al actualizar la imagen del perfil", + "imageRemoveFailed": "Error al eliminar la imagen del perfil" + }, + "messages": { + "noChanges": "No hay cambios para guardar", + "updateSuccess": "Perfil actualizado exitosamente", + "fillPasswords": "Por favor, completa ambos campos de contraseña", + "passwordSuccess": "Contraseña actualizada exitosamente", + "imageSuccess": "Imagen de perfil actualizada exitosamente", + "imageRemoved": "Imagen de perfil eliminada exitosamente" + }, + "pageTitle": "Perfil" + }, + "resetPassword": { + "pageTitle": "Restablecer contraseña", + "header": { + "title": "Restablecer contraseña", + "description": "Introduce tu nueva contraseña abajo" + }, + "form": { + "newPassword": "Nueva contraseña", + "newPasswordPlaceholder": "Introduce tu nueva contraseña", + "confirmPassword": "Confirmar nueva contraseña", + "confirmPasswordPlaceholder": "Confirma tu nueva contraseña", + "resetting": "Restableciendo contraseña...", + "submit": "Restablecer contraseña", + "backToLogin": "Volver a iniciar sesión" + }, + "messages": { + "success": "Contraseña restablecida exitosamente" + }, + "errors": { + "serverError": "Error al restablecer la contraseña. Por favor, inténtalo de nuevo.", + "invalidToken": "Token de restablecimiento inválido o ausente" + } + }, + "settings": { + "groups": { + "defaultDescription": "Opciones de configuración", + "general": { + "title": "General", + "description": "Configuraciones básicas de la aplicación" + }, + "email": { + "title": "Correo electrónico", + "description": "Configuración del servidor de correo electrónico" + }, + "security": { + "title": "Seguridad", + "description": "Configuraciones de seguridad y autenticación" + }, + "storage": { + "title": "Almacenamiento", + "description": "Configuración del almacenamiento de archivos" + } + }, + "fields": { + "noDescription": "No hay descripción disponible", + "appLogo": { + "title": "Logo de la aplicación", + "description": "Imagen del logo de la aplicación" + }, + "appName": { + "title": "Nombre de la aplicación", + "description": "Nombre de la aplicación mostrado a los usuarios" + }, + "appDescription": { + "title": "Descripción de la aplicación", + "description": "Breve descripción de la aplicación" + }, + "showHomePage": { + "title": "Mostrar página de inicio", + "description": "Mostrar la página de inicio después de la instalación" + }, + "smtpEnabled": { + "title": "SMTP activado", + "description": "Habilitar o deshabilitar la funcionalidad de correo electrónico SMTP" + }, + "smtpHost": { + "title": "Servidor SMTP", + "description": "Dirección del servidor SMTP" + }, + "smtpPort": { + "title": "Puerto SMTP", + "description": "Puerto del servidor SMTP" + }, + "smtpUser": { + "title": "Usuario SMTP", + "description": "Nombre de usuario para la autenticación SMTP" + }, + "smtpPass": { + "title": "Contraseña SMTP", + "description": "Contraseña para la autenticación SMTP" + }, + "smtpFromName": { + "title": "Nombre del remitente", + "description": "Nombre mostrado para los correos enviados" + }, + "smtpFromEmail": { + "title": "Correo del remitente", + "description": "Dirección de correo del remitente" + }, + "maxLoginAttempts": { + "title": "Máximo de intentos de inicio de sesión", + "description": "Número máximo de intentos antes de bloquear" + }, + "loginBlockDuration": { + "title": "Duración del bloqueo", + "description": "Duración (en segundos) del bloqueo tras exceder los intentos" + }, + "passwordMinLength": { + "title": "Longitud mínima de contraseña", + "description": "Número mínimo de caracteres para las contraseñas" + }, + "passwordResetTokenExpiration": { + "title": "Expiración del token de restablecimiento", + "description": "Tiempo de validez (en segundos) para el token de restablecimiento de contraseña" + }, + "maxFileSize": { + "title": "Tamaño máximo de archivo", + "description": "Tamaño máximo permitido para subir archivos (en bytes)" + }, + "maxTotalStoragePerUser": { + "title": "Almacenamiento máximo por usuario", + "description": "Límite total de almacenamiento por usuario (en bytes)" + } + }, + "buttons": { + "save": "Guardar {{group}}" + }, + "errors": { + "loadFailed": "Error al cargar la configuración", + "updateFailed": "Error al actualizar la configuración" + }, + "messages": { + "noChanges": "No hay cambios para guardar", + "updateSuccess": "Configuración de {{group}} actualizada exitosamente" + }, + "title": "Configuración", + "breadcrumb": "Configuración", + "pageTitle": "Configuración" + }, + "share": { + "errors": { + "invalidPassword": "Contraseña inválida. Por favor, inténtalo de nuevo.", + "loadFailed": "Error al cargar la compartición", + "downloadFailed": "Error al descargar el archivo" + }, + "messages": { + "downloadStarted": "Descarga iniciada" + }, + "password": { + "title": "Compartición protegida por contraseña", + "protected": "Esta compartición está protegida por contraseña", + "incorrect": "Contraseña incorrecta. Por favor, inténtalo de nuevo.", + "label": "Contraseña", + "placeholder": "Introduce la contraseña de la compartición", + "submit": "Enviar" + }, + "details": { + "untitled": "Compartición sin título", + "created": "Creada: {{date}}", + "expires": "Expira: {{date}}" + }, + "notFound": { + "title": "Compartición no encontrada", + "description": "Esta compartición puede haber sido eliminada o haber expirado." + }, + "pageTitle": "Compartición" + }, + "shares": { + "errors": { + "loadFailed": "Error al cargar las comparticiones", + "notifyFailed": "Error al notificar a los destinatarios", + "smtpConfigFailed": "Error al cargar la configuración SMTP" + }, + "messages": { + "linkCopied": "Enlace copiado al portapapeles", + "recipientsNotified": "Destinatarios notificados exitosamente" + }, + "empty": { + "message": "Aún no se han creado comparticiones", + "createButton": "Crear compartición" + }, + "header": { + "title": "Mis comparticiones", + "myShares": "Mis comparticiones" + }, + "search": { + "title": "Todas las comparticiones", + "createButton": "Crear compartición", + "placeholder": "Buscar comparticiones...", + "results": "Se encontraron {{filtered}} de {{total}} comparticiones" + }, + "pageTitle": "Comparticiones" + }, + "users": { + "modes": { + "create": "crear", + "edit": "editar" + }, + "errors": { + "loadFailed": "Error al cargar los usuarios", + "submitFailed": "Error al {{mode}} el usuario", + "deleteFailed": "Error al eliminar el usuario", + "statusUpdateFailed": "Error al actualizar el estado del usuario" + }, + "messages": { + "createSuccess": "Usuario creado exitosamente", + "updateSuccess": "Usuario actualizado exitosamente", + "deleteSuccess": "Usuario eliminado exitosamente", + "activateSuccess": "Usuario activado exitosamente", + "deactivateSuccess": "Usuario desactivado exitosamente" + }, + "actions": { + "edit": "Editar", + "activate": "Activar", + "deactivate": "Desactivar", + "delete": "Eliminar" + }, + "delete": { + "title": "Confirmar eliminación del usuario", + "confirmation": "¿Estás seguro de que deseas eliminar al usuario {{firstName}} {{lastName}}? Esta acción no se puede deshacer.", + "confirm": "Eliminar usuario" + }, + "form": { + "titleCreate": "Agregar nuevo usuario", + "titleEdit": "Editar usuario", + "firstName": "Nombre", + "lastName": "Apellido", + "username": "Nombre de usuario", + "email": "Correo electrónico", + "password": "Contraseña", + "newPassword": "Nueva contraseña (opcional)", + "passwordPlaceholder": "Dejar en blanco para mantener la contraseña actual", + "role": "Rol", + "roleUser": "Usuario", + "roleAdmin": "Administrador", + "create": "Crear", + "save": "Guardar" + }, + "status": { + "title": "Confirmar cambio de estado", + "confirmation": "¿Estás seguro de que deseas {{action}} al usuario {{firstName}} {{lastName}}?", + "activate": "activar", + "deactivate": "desactivar", + "user": "Usuario" + }, + "header": { + "title": "Gestión de usuarios", + "addUser": "Agregar usuario", + "management": "Gestión de usuarios" + }, + "table": { + "user": "USUARIO", + "email": "CORREO", + "status": "ESTADO", + "role": "ROL", + "actions": "ACCIONES", + "active": "Activo", + "inactive": "Inactivo", + "admin": "Administrador", + "userr": "Usuario" + } + }, + "logo": { + "labels": { + "appLogo": "Logo de la aplicación" + }, + "buttons": { + "upload": "Subir logo", + "remove": "Eliminar logo" + }, + "messages": { + "uploadSuccess": "Logo subido exitosamente", + "removeSuccess": "Logo eliminado exitosamente" + }, + "errors": { + "uploadFailed": "Error al subir el logo", + "removeFailed": "Error al eliminar el logo" + } + }, + "navbar": { + "logoAlt": "Logo de la aplicación", + "profileMenu": "Menú de perfil", + "profile": "Perfil", + "settings": "Configuración", + "usersManagement": "Gestión de usuarios", + "logout": "Cerrar sesión" + } +} \ No newline at end of file diff --git a/apps/app/messages/fr-FR.json b/apps/app/messages/fr-FR.json new file mode 100644 index 0000000..75ccce7 --- /dev/null +++ b/apps/app/messages/fr-FR.json @@ -0,0 +1,637 @@ +{ + "login": { + "welcome": "Bienvenue à", + "signInToContinue": "Connectez-vous pour continuer", + "emailLabel": "Adresse e-mail", + "emailPlaceholder": "Entrez votre e-mail", + "passwordLabel": "Mot de passe", + "passwordPlaceholder": "Entrez votre mot de passe", + "signIn": "Se connecter", + "signingIn": "Connexion en cours...", + "forgotPassword": "Mot de passe oublié ?", + "pageTitle": "Connexion" + }, + "errors": { + "invalidCredentials": "E-mail ou mot de passe invalide", + "userNotFound": "Utilisateur non trouvé", + "accountLocked": "Compte bloqué. Veuillez réessayer plus tard", + "unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer" + }, + "validation": { + "invalidEmail": "Adresse email invalide", + "passwordMinLength": "Le mot de passe doit contenir au moins 6 caractères", + "firstNameRequired": "Le prénom est requis", + "lastNameRequired": "Le nom est requis", + "usernameLength": "Le nom d'utilisateur doit contenir au moins 3 caractères", + "usernameSpaces": "Le nom d'utilisateur ne peut pas contenir d'espaces", + "passwordLength": "Le mot de passe doit contenir au moins 8 caractères", + "passwordsMatch": "Les mots de passe ne correspondent pas", + "emailRequired": "L'email est requis", + "passwordRequired": "Le mot de passe est requis" + }, + "fileSelector": { + "availableFiles": "Fichiers Disponibles ({{count}})", + "shareFiles": "Fichiers Partagés ({{count}})", + "searchPlaceholder": "Rechercher des fichiers...", + "noMatchingFiles": "Aucun fichier correspondant", + "noAvailableFiles": "Aucun fichier disponible", + "noFilesInShare": "Aucun fichier partagé", + "saveChanges": "Enregistrer les Modifications" + }, + "recipientSelector": { + "emailPlaceholder": "Entrez l'e-mail du destinataire", + "add": "Ajouter", + "recipients": "Destinataires ({{count}})", + "notifyAll": "Notifier Tous", + "noRecipients": "Aucun destinataire ajouté", + "addSuccess": "Destinataire ajouté avec succès", + "addError": "Échec de l'ajout du destinataire", + "removeSuccess": "Destinataire supprimé avec succès", + "removeError": "Échec de la suppression du destinataire", + "sendingNotifications": "Envoi des notifications...", + "notifySuccess": "Destinataires notifiés avec succès", + "notifyError": "Échec de la notification des destinataires" + }, + "navigation": { + "dashboard": "Tableau de bord" + }, + "common": { + "loading": "Chargement, veuillez patienter...", + "cancel": "Annuler", + "save": "Enregistrer", + "delete": "Supprimer", + "close": "Fermer", + "download": "Télécharger", + "unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer.", + "yes": "Oui", + "no": "Non", + "dashboard": "Tableau de Bord" + }, + "createShare": { + "title": "Créer un Partage", + "nameLabel": "Nom du Partage", + "expirationLabel": "Date d'Expiration", + "expirationPlaceholder": "JJ/MM/AAAA HH:MM", + "maxViewsLabel": "Vues Maximales", + "maxViewsPlaceholder": "Laisser vide pour illimité", + "passwordProtection": "Protégé par Mot de Passe", + "passwordLabel": "Mot de Passe", + "create": "Créer le Partage", + "success": "Partage créé avec succès", + "error": "Échec de la création du partage" + }, + "fileActions": { + "editFile": "Modifier le Fichier", + "nameLabel": "Nom", + "namePlaceholder": "Entrez le nouveau nom", + "extension": "Extension", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Entrez la description du fichier", + "deleteFile": "Supprimer le Fichier", + "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer \"{{fileName}}\" ?", + "deleteWarning": "Cette action ne peut pas être annulée." + }, + "filePreview": { + "loading": "Chargement de l'aperçu...", + "notAvailable": "Aperçu non disponible", + "downloadToView": "Téléchargez le fichier pour voir le contenu", + "audioNotSupported": "Votre navigateur ne prend pas en charge l'élément audio", + "videoNotSupported": "Votre navigateur ne prend pas en charge l'élément vidéo", + "loadError": "Échec du chargement de l'aperçu", + "downloadError": "Échec du téléchargement du fichier" + }, + "generateShareLink": { + "generateTitle": "Générer un Lien de Partage", + "updateTitle": "Mettre à Jour le Lien de Partage", + "generateDescription": "Générez un lien pour partager vos fichiers", + "updateDescription": "Mettez à jour l'alias de ce lien de partage", + "aliasPlaceholder": "Entrez l'alias", + "linkReady": "Votre lien de partage est prêt :", + "generateButton": "Générer le Lien", + "updateButton": "Mettre à Jour le Lien", + "copyButton": "Copier le Lien", + "success": "Lien généré avec succès", + "error": "Échec de la génération du lien", + "copied": "Lien copié dans le presse-papiers" + }, + "shareActions": { + "deleteTitle": "Supprimer le Partage", + "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer ce partage ? Cette action ne peut pas être annulée.", + "editTitle": "Modifier le Partage", + "nameLabel": "Nom du Partage", + "expirationLabel": "Date d'Expiration", + "expirationPlaceholder": "JJ/MM/AAAA HH:MM", + "maxViewsLabel": "Vues Maximales", + "maxViewsPlaceholder": "Laisser vide pour illimité", + "passwordProtection": "Protégé par Mot de Passe", + "passwordLabel": "Mot de Passe", + "passwordPlaceholder": "Entrez le mot de passe", + "newPasswordLabel": "Nouveau Mot de Passe (laisser vide pour garder l'actuel)", + "newPasswordPlaceholder": "Entrez le nouveau mot de passe", + "manageFilesTitle": "Gérer les Fichiers", + "manageRecipientsTitle": "Gérer les Destinataires", + "editSuccess": "Partage mis à jour avec succès", + "editError": "Échec de la mise à jour du partage" + }, + "shareDetails": { + "title": "Détails du Partage", + "subtitle": "Informations détaillées sur ce partage", + "basicInfo": "Informations de Base", + "name": "Nom", + "untitled": "Partage sans titre", + "views": "Vues", + "dates": "Dates", + "created": "Créé le: {{date}}", + "expires": "Expire le: {{date}}", + "never": "Jamais", + "security": "Sécurité", + "passwordProtected": "Protégé par Mot de Passe", + "publicAccess": "Accès Public", + "maxViews": "Vues Maximales : {{count}}", + "files": "Fichiers ({{count}})", + "recipients": "Destinataires ({{count}})", + "notAvailable": "N/D", + "invalidDate": "Date invalide", + "loadError": "Échec du chargement des détails du partage" + }, + "uploadFile": { + "title": "Envoyer un Fichier", + "selectFile": "Cliquez pour sélectionner un fichier", + "preview": "Aperçu", + "uploadProgress": "Progression de l'envoi", + "upload": "Envoyer", + "success": "Fichier envoyé avec succès", + "error": "Échec de l'envoi du fichier" + }, + "filesTable": { + "ariaLabel": "Tableau des fichiers", + "columns": { + "name": "NOM", + "description": "DESCRIPTION", + "size": "TAILLE", + "createdAt": "CRÉÉ LE", + "updatedAt": "MODIFIÉ LE", + "actions": "ACTIONS" + }, + "actions": { + "menu": "Menu d'actions du fichier", + "preview": "Aperçu", + "edit": "Modifier", + "download": "Télécharger", + "delete": "Supprimer" + } + }, + "sharesTable": { + "ariaLabel": "Tableau des partages", + "never": "Jamais", + "columns": { + "name": "NOM", + "createdAt": "CRÉÉ LE", + "expiresAt": "EXPIRE LE", + "status": "STATUT", + "security": "SÉCURITÉ", + "files": "FICHIERS", + "recipients": "DESTINATAIRES", + "actions": "ACTIONS" + }, + "status": { + "neverExpires": "N'expire Jamais", + "active": "Actif", + "expired": "Expiré" + }, + "security": { + "protected": "Protégé", + "public": "Public" + }, + "filesCount": "{{count}} fichiers", + "recipientsCount": "{{count}} destinataires", + "actions": { + "menu": "Menu d'actions du partage", + "edit": "Modifier", + "manageFiles": "Gérer les Fichiers", + "manageRecipients": "Gérer les Destinataires", + "viewDetails": "Voir les Détails", + "generateLink": "Générer un Lien", + "editLink": "Modifier le Lien", + "copyLink": "Copier le Lien", + "notifyRecipients": "Notifier les Destinataires", + "delete": "Supprimer" + } + }, + "footer": { + "poweredBy": "Propulsé par", + "kyanHomepage": "Page d'accueil de Kyantech" + }, + "fileManager": { + "downloadError": "Échec du téléchargement du fichier", + "updateSuccess": "Fichier mis à jour avec succès", + "updateError": "Échec de la mise à jour du fichier", + "deleteSuccess": "Fichier supprimé avec succès", + "deleteError": "Échec de la suppression du fichier" + }, + "shareManager": { + "deleteSuccess": "Partage supprimé avec succès", + "deleteError": "Échec de la suppression du partage", + "updateSuccess": "Partage mis à jour avec succès", + "updateError": "Échec de la mise à jour du partage", + "filesUpdateSuccess": "Fichiers mis à jour avec succès", + "filesUpdateError": "Échec de la mise à jour des fichiers", + "recipientsUpdateSuccess": "Destinataires mis à jour avec succès", + "recipientsUpdateError": "Échec de la mise à jour des destinataires", + "linkGenerateSuccess": "Lien de partage généré avec succès", + "linkGenerateError": "Échec de la génération du lien de partage", + "notifyLoading": "Envoi des notifications...", + "notifySuccess": "Destinataires notifiés avec succès", + "notifyError": "Échec de la notification des destinataires" + }, + "quickAccess": { + "files": { + "title": "Mes Fichiers", + "description": "Accédez et gérez vos fichiers téléchargés" + }, + "shares": { + "title": "Mes Partages", + "description": "Visualisez et gérez vos fichiers partagés" + } + }, + "recentFiles": { + "title": "Téléchargements Récents", + "viewAll": "Voir Tout", + "uploadFile": "Envoyer un Fichier", + "noFiles": "Aucun fichier téléchargé pour le moment" + }, + "recentShares": { + "title": "Partages Récents", + "viewAll": "Voir Tout", + "createShare": "Créer un Partage", + "noShares": "Aucun partage créé pour le moment", + "createFirst": "Créer votre premier partage" + }, + "storageUsage": { + "title": "Utilisation du Stockage", + "ariaLabel": "Barre de progression de l'utilisation du stockage", + "used": "{{size}} utilisé", + "available": "{{size}} disponible" + }, + "dashboard": { + "loadError": "Échec du chargement des données du tableau de bord", + "linkCopied": "Lien copié dans le presse-papiers", + "pageTitle": "Tableau de Bord", + "breadcrumb": "Tableau de Bord" + }, + "emptyState": { + "noFiles": "Aucun fichier téléchargé pour le moment", + "uploadFile": "Envoyer un Fichier" + }, + "files": { + "title": "Tous les Fichiers", + "uploadFile": "Envoyer un Fichier", + "loadError": "Échec du chargement des fichiers", + "pageTitle": "Mes Fichiers", + "breadcrumb": "Mes Fichiers" + }, + "searchBar": { + "placeholder": "Rechercher des fichiers...", + "results": "Trouvé {{filtered}} sur {{total}} fichiers" + }, + "forgotPassword": { + "emailLabel": "Adresse Email", + "emailPlaceholder": "Entrez votre email", + "sending": "Envoi en cours...", + "submit": "Envoyer les Instructions", + "backToLogin": "Retour à la Connexion", + "title": "Mot de Passe Oublié", + "description": "Entrez votre adresse email et nous vous enverrons les instructions pour réinitialiser votre mot de passe.", + "resetInstructions": "Instructions de réinitialisation envoyées à votre email", + "pageTitle": "Mot de Passe Oublié" + }, + "home": { + "description": "L'alternative open-source à WeTransfer. Partagez des fichiers en toute sécurité, sans suivi ni limitations.", + "documentation": "Documentation", + "starOnGithub": "Star sur GitHub", + "privacyMessage": "Conçu avec la confidentialité à l'esprit. Vos fichiers avant téléchargement ne sont accessibles que par ceux ayant le lien de partage. Gratuit et open source pour toujours.", + "header": { + "fileSharing": "Partage de fichiers", + "tagline": "simple et gratuit" + }, + "pageTitle": "Accueil" + }, + "profile": { + "password": { + "title": "Changer le Mot de Passe", + "newPassword": "Nouveau Mot de Passe", + "confirmPassword": "Confirmer le Nouveau Mot de Passe", + "updateButton": "Mettre à Jour le Mot de Passe" + }, + "form": { + "title": "Informations du Profil", + "firstName": "Prénom", + "lastName": "Nom", + "username": "Nom d'Utilisateur", + "email": "Email", + "updateButton": "Mettre à Jour le Profil" + }, + "header": { + "title": "Profil", + "subtitle": "Gérez vos informations personnelles et votre mot de passe" + }, + "picture": { + "title": "Photo de Profil", + "description": "Cliquez sur l'icône de l'appareil photo pour changer votre photo de profil", + "uploadPhoto": "Télécharger une Photo", + "removePhoto": "Supprimer la Photo" + }, + "errors": { + "loadFailed": "Échec du chargement des données utilisateur", + "updateFailed": "Échec de la mise à jour du profil", + "passwordFailed": "Échec de la mise à jour du mot de passe", + "imageFailed": "Échec de la mise à jour de l'image", + "imageRemoveFailed": "Échec de la suppression de l'image" + }, + "messages": { + "noChanges": "Aucun changement à enregistrer", + "updateSuccess": "Profil mis à jour avec succès", + "fillPasswords": "Veuillez remplir les deux champs de mot de passe", + "passwordSuccess": "Mot de passe mis à jour avec succès", + "imageSuccess": "Image de profil mise à jour avec succès", + "imageRemoved": "Image de profil supprimée avec succès" + }, + "pageTitle": "Profil" + }, + "resetPassword": { + "pageTitle": "Réinitialiser le Mot de Passe", + "header": { + "title": "Réinitialiser le Mot de Passe", + "description": "Entrez votre nouveau mot de passe ci-dessous" + }, + "form": { + "newPassword": "Nouveau Mot de Passe", + "newPasswordPlaceholder": "Entrez votre nouveau mot de passe", + "confirmPassword": "Confirmer le Nouveau Mot de Passe", + "confirmPasswordPlaceholder": "Confirmez votre nouveau mot de passe", + "resetting": "Réinitialisation en Cours...", + "submit": "Réinitialiser le Mot de Passe", + "backToLogin": "Retour à la Connexion" + }, + "messages": { + "success": "Mot de passe réinitialisé avec succès" + }, + "errors": { + "serverError": "Échec de la réinitialisation du mot de passe. Veuillez réessayer.", + "invalidToken": "Jeton de réinitialisation invalide ou manquant" + } + }, + "settings": { + "title": "Paramètres", + "breadcrumb": "Paramètres", + "pageTitle": "Paramètres", + "groups": { + "defaultDescription": "Options de configuration", + "general": { + "title": "Général", + "description": "Paramètres de base de l'application" + }, + "email": { + "title": "Email", + "description": "Configuration du serveur de messagerie" + }, + "security": { + "title": "Sécurité", + "description": "Paramètres de sécurité et d'authentification" + }, + "storage": { + "title": "Stockage", + "description": "Configuration du stockage des fichiers" + } + }, + "fields": { + "noDescription": "Aucune description disponible", + "appLogo": { + "title": "Logo de l'Application", + "description": "Image du logo de l'application" + }, + "appName": { + "title": "Nom de l'Application", + "description": "Nom de l'application affiché aux utilisateurs" + }, + "appDescription": { + "title": "Description de l'Application", + "description": "Brève description de l'application" + }, + "showHomePage": { + "title": "Afficher la Page d'Accueil", + "description": "Afficher la page d'accueil après l'installation" + }, + "smtpEnabled": { + "description": "Activer les notifications par email" + }, + "smtpHost": { + "title": "Serveur SMTP", + "description": "Adresse du serveur SMTP" + }, + "smtpPort": { + "title": "Port SMTP", + "description": "Port du serveur SMTP" + }, + "smtpUser": { + "title": "Utilisateur SMTP", + "description": "Nom d'utilisateur pour l'authentification SMTP" + }, + "smtpPass": { + "title": "Mot de passe SMTP", + "description": "Mot de passe pour l'authentification SMTP" + }, + "smtpFromName": { + "title": "Nom de l'Expéditeur", + "description": "Nom affiché dans les emails envoyés" + }, + "smtpFromEmail": { + "title": "Email de l'Expéditeur", + "description": "Adresse email de l'expéditeur" + }, + "maxLoginAttempts": { + "title": "Tentatives de Connexion Maximum", + "description": "Nombre maximum de tentatives de connexion avant le blocage" + }, + "loginBlockDuration": { + "title": "Durée du Blocage", + "description": "Durée (en secondes) du blocage après dépassement des tentatives" + }, + "passwordMinLength": { + "title": "Longueur Minimale du Mot de Passe", + "description": "Nombre minimum de caractères pour les mots de passe" + }, + "passwordResetTokenExpiration": { + "title": "Expiration du Jeton de Réinitialisation", + "description": "Durée de validité (en secondes) du jeton de réinitialisation" + }, + "maxFileSize": { + "title": "Taille Maximale de Fichier", + "description": "Taille maximale autorisée pour les fichiers (en octets)" + }, + "maxTotalStoragePerUser": { + "title": "Stockage Maximum par Utilisateur", + "description": "Limite totale de stockage par utilisateur (en octets)" + } + }, + "buttons": { + "save": "Enregistrer {{group}}" + }, + "errors": { + "loadFailed": "Échec du chargement des paramètres", + "updateFailed": "Échec de la mise à jour des paramètres" + }, + "messages": { + "noChanges": "Aucun changement à enregistrer", + "updateSuccess": "Paramètres {{group}} mis à jour avec succès" + } + }, + "share": { + "errors": { + "invalidPassword": "Mot de passe invalide. Veuillez réessayer.", + "loadFailed": "Échec du chargement du partage", + "downloadFailed": "Échec du téléchargement du fichier" + }, + "messages": { + "downloadStarted": "Téléchargement commencé" + }, + "password": { + "title": "Partage Protégé par Mot de Passe", + "protected": "Ce partage est protégé par mot de passe", + "incorrect": "Mot de passe incorrect. Veuillez réessayer.", + "label": "Mot de passe", + "placeholder": "Entrez le mot de passe du partage", + "submit": "Envoyer" + }, + "details": { + "untitled": "Partage sans titre", + "created": "Créé le: {{date}}", + "expires": "Expire le: {{date}}" + }, + "notFound": { + "title": "Partage Non Trouvé", + "description": "Ce partage a peut-être été supprimé ou a expiré." + }, + "pageTitle": "Partage" + }, + "shares": { + "errors": { + "loadFailed": "Échec du chargement des partages", + "notifyFailed": "Échec de la notification des destinataires", + "smtpConfigFailed": "Échec du chargement de la configuration SMTP" + }, + "messages": { + "linkCopied": "Lien copié dans le presse-papiers", + "recipientsNotified": "Destinataires notifiés avec succès" + }, + "empty": { + "message": "Aucun partage créé pour le moment", + "createButton": "Créer un Partage" + }, + "header": { + "title": "Mes Partages", + "myShares": "Mes Partages" + }, + "search": { + "title": "Tous les Partages", + "createButton": "Créer un Partage", + "placeholder": "Rechercher des partages...", + "results": "Trouvé {{filtered}} sur {{total}} partages" + }, + "pageTitle": "Partages" + }, + "users": { + "modes": { + "create": "créer", + "edit": "modifier" + }, + "errors": { + "loadFailed": "Échec du chargement des utilisateurs", + "submitFailed": "Échec de {{mode}} l'utilisateur", + "deleteFailed": "Échec de la suppression de l'utilisateur", + "statusUpdateFailed": "Échec de la mise à jour du statut de l'utilisateur" + }, + "messages": { + "createSuccess": "Utilisateur créé avec succès", + "updateSuccess": "Utilisateur mis à jour avec succès", + "deleteSuccess": "Utilisateur supprimé avec succès", + "activateSuccess": "Utilisateur activé avec succès", + "deactivateSuccess": "Utilisateur désactivé avec succès" + }, + "actions": { + "edit": "Modifier", + "activate": "Activer", + "deactivate": "Désactiver", + "delete": "Supprimer" + }, + "delete": { + "title": "Confirmer la Suppression de l'Utilisateur", + "confirmation": "Êtes-vous sûr de vouloir supprimer l'utilisateur {{firstName}} {{lastName}} ? Cette action ne peut pas être annulée.", + "confirm": "Supprimer l'Utilisateur" + }, + "form": { + "titleCreate": "Ajouter un Nouvel Utilisateur", + "titleEdit": "Modifier l'Utilisateur", + "firstName": "Prénom", + "lastName": "Nom", + "username": "Nom d'Utilisateur", + "email": "Email", + "password": "Mot de Passe", + "newPassword": "Nouveau Mot de Passe (optionnel)", + "passwordPlaceholder": "Laisser vide pour garder le mot de passe actuel", + "role": "Rôle", + "roleUser": "Utilisateur", + "roleAdmin": "Administrateur", + "create": "Créer", + "save": "Enregistrer" + }, + "status": { + "title": "Confirmer le Changement de Statut", + "confirmation": "Êtes-vous sûr de vouloir {{action}} l'utilisateur {{firstName}} {{lastName}} ?", + "activate": "activer", + "deactivate": "désactiver", + "user": "Utilisateur" + }, + "header": { + "title": "Gestion des Utilisateurs", + "addUser": "Ajouter un Utilisateur", + "management": "Gestion des Utilisateurs" + }, + "table": { + "user": "UTILISATEUR", + "email": "EMAIL", + "status": "STATUT", + "role": "RÔLE", + "actions": "ACTIONS", + "active": "Actif", + "inactive": "Inactif", + "admin": "Admin", + "userr": "Utilisateur" + } + }, + "logo": { + "labels": { + "appLogo": "Logo de l'application" + }, + "buttons": { + "upload": "Télécharger le logo", + "remove": "Supprimer le logo" + }, + "messages": { + "uploadSuccess": "Logo téléchargé avec succès", + "removeSuccess": "Logo supprimé avec succès" + }, + "errors": { + "uploadFailed": "Échec du téléchargement du logo", + "removeFailed": "Échec de la suppression du logo" + } + }, + "navbar": { + "logoAlt": "Logo de l'Application", + "profileMenu": "Menu du Profil", + "profile": "Profil", + "settings": "Paramètres", + "usersManagement": "Gestion des Utilisateurs", + "logout": "Déconnexion" + } +} \ No newline at end of file diff --git a/apps/app/messages/hi-IN.json b/apps/app/messages/hi-IN.json new file mode 100644 index 0000000..b07567f --- /dev/null +++ b/apps/app/messages/hi-IN.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "स्वागत है में", + "signInToContinue": "जारी रखने के लिए साइन इन करें", + "emailLabel": "ईमेल पता", + "emailPlaceholder": "अपना ईमेल दर्ज करें", + "passwordLabel": "पासवर्ड", + "passwordPlaceholder": "अपना पासवर्ड दर्ज करें", + "signIn": "साइन इन करें", + "signingIn": "साइन इन हो रहा है...", + "forgotPassword": "पासवर्ड भूल गए?", + "pageTitle": "लॉगिन" + }, + "errors": { + "invalidCredentials": "गलत ईमेल या पासवर्ड", + "userNotFound": "उपयोगकर्ता नहीं मिला", + "accountLocked": "खाता लॉक है। कृपया बाद में प्रयास करें", + "unexpectedError": "एक अप्रत्याशित त्रुटि हुई। कृपया पुनः प्रयास करें" + }, + "validation": { + "invalidEmail": "अमान्य ईमेल पता", + "passwordMinLength": "पासवर्ड कम से कम 6 अक्षर का होना चाहिए", + "firstNameRequired": "पहला नाम आवश्यक है", + "lastNameRequired": "अंतिम नाम आवश्यक है", + "usernameLength": "उपयोगकर्ता नाम कम से कम 3 अक्षर का होना चाहिए", + "usernameSpaces": "उपयोगकर्ता नाम में रिक्त स्थान नहीं हो सकते", + "passwordLength": "पासवर्ड कम से कम 8 अक्षर का होना चाहिए", + "passwordsMatch": "पासवर्ड मेल नहीं खाते", + "emailRequired": "ईमेल आवश्यक है", + "passwordRequired": "पासवर्ड आवश्यक है" + }, + "fileSelector": { + "availableFiles": "उपलब्ध फाइलें ({{count}})", + "shareFiles": "फाइलें साझा करें ({{count}})", + "searchPlaceholder": "फाइलें खोजें...", + "noMatchingFiles": "कोई मेल खाने वाली फाइलें नहीं", + "noAvailableFiles": "कोई फाइल उपलब्ध नहीं", + "noFilesInShare": "साझाकरण में कोई फाइलें नहीं", + "saveChanges": "परिवर्तन सहेजें" + }, + "recipientSelector": { + "emailPlaceholder": "प्राप्तकर्ता का ईमेल दर्ज करें", + "add": "जोड़ें", + "recipients": "प्राप्तकर्ता ({{count}})", + "notifyAll": "सभी को सूचित करें", + "noRecipients": "अभी तक कोई प्राप्तकर्ता नहीं जोड़ा गया", + "addSuccess": "प्राप्तकर्ता सफलतापूर्वक जोड़ा गया", + "addError": "प्राप्तकर्ता जोड़ने में विफल", + "removeSuccess": "प्राप्तकर्ता सफलतापूर्वक हटाया गया", + "removeError": "प्राप्तकर्ता हटाने में विफल", + "sendingNotifications": "सूचनाएँ भेजी जा रही हैं...", + "notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया", + "notifyError": "प्राप्तकर्ताओं को सूचित करने में विफल" + }, + "navigation": { + "dashboard": "डैशबोर्ड" + }, + "common": { + "loading": "लोड हो रहा है, कृपया प्रतीक्षा करें...", + "cancel": "रद्द करें", + "save": "सहेजें", + "delete": "हटाएं", + "close": "बंद करें", + "download": "डाउनलोड करें", + "unexpectedError": "एक अप्रत्याशित त्रुटि हुई। कृपया पुनः प्रयास करें।", + "yes": "हाँ", + "no": "नहीं", + "dashboard": "डैशबोर्ड" + }, + "createShare": { + "title": "साझा करें बनाएं", + "nameLabel": "साझाकरण का नाम", + "expirationLabel": "समाप्ति तिथि", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "अधिकतम दृश्य", + "maxViewsPlaceholder": "अनलिमिटेड के लिए खाली छोड़ें", + "passwordProtection": "पासवर्ड सुरक्षा", + "passwordLabel": "पासवर्ड", + "create": "साझा करें बनाएं", + "success": "साझाकरण सफलतापूर्वक बनाया गया", + "error": "साझाकरण बनाने में विफल" + }, + "fileActions": { + "editFile": "फाइल संपादित करें", + "nameLabel": "नाम", + "namePlaceholder": "नया नाम दर्ज करें", + "extension": "एक्सटेंशन", + "descriptionLabel": "विवरण", + "descriptionPlaceholder": "फाइल का विवरण दर्ज करें", + "deleteFile": "फाइल हटाएं", + "deleteConfirmation": "क्या आप वाकई \"{{fileName}}\" हटाना चाहते हैं?", + "deleteWarning": "यह क्रिया अपरिवर्तनीय है।" + }, + "filePreview": { + "loading": "पूर्वावलोकन लोड हो रहा है...", + "notAvailable": "पूर्वावलोकन उपलब्ध नहीं", + "downloadToView": "सामग्री देखने के लिए फाइल डाउनलोड करें", + "audioNotSupported": "आपका ब्राउज़र ऑडियो तत्व का समर्थन नहीं करता", + "videoNotSupported": "आपका ब्राउज़र वीडियो तत्व का समर्थन नहीं करता", + "loadError": "पूर्वावलोकन लोड करने में विफल", + "downloadError": "फाइल डाउनलोड करने में विफल" + }, + "generateShareLink": { + "generateTitle": "साझाकरण लिंक उत्पन्न करें", + "updateTitle": "साझाकरण लिंक अपडेट करें", + "generateDescription": "अपनी फाइलें साझा करने के लिए एक लिंक उत्पन्न करें", + "updateDescription": "इस साझाकरण लिंक के लिए उपनाम अपडेट करें", + "aliasPlaceholder": "उपनाम दर्ज करें", + "linkReady": "आपका साझाकरण लिंक तैयार है:", + "generateButton": "लिंक उत्पन्न करें", + "updateButton": "लिंक अपडेट करें", + "copyButton": "लिंक कॉपी करें", + "success": "लिंक सफलतापूर्वक उत्पन्न हुआ", + "error": "लिंक उत्पन्न करने में विफल", + "copied": "लिंक क्लिपबोर्ड में कॉपी किया गया" + }, + "shareActions": { + "deleteTitle": "साझाकरण हटाएं", + "deleteConfirmation": "क्या आप वाकई इस साझाकरण को हटाना चाहते हैं? यह क्रिया अपरिवर्तनीय है।", + "editTitle": "साझाकरण संपादित करें", + "nameLabel": "साझाकरण का नाम", + "expirationLabel": "समाप्ति तिथि", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "अधिकतम दृश्य", + "maxViewsPlaceholder": "अनलिमिटेड के लिए खाली छोड़ें", + "passwordProtection": "पासवर्ड सुरक्षा", + "passwordLabel": "पासवर्ड", + "passwordPlaceholder": "पासवर्ड दर्ज करें", + "newPasswordLabel": "नया पासवर्ड (वर्तमान रखने के लिए खाली छोड़ें)", + "newPasswordPlaceholder": "नया पासवर्ड दर्ज करें", + "manageFilesTitle": "फाइलें प्रबंधित करें", + "manageRecipientsTitle": "प्राप्तकर्ताओं का प्रबंधन करें", + "editSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ", + "editError": "साझाकरण अपडेट करने में विफल" + }, + "shareDetails": { + "title": "साझाकरण विवरण", + "subtitle": "इस साझाकरण की विस्तृत जानकारी", + "basicInfo": "मूल जानकारी", + "name": "नाम", + "untitled": "बिना शीर्षक के", + "views": "दृश्य", + "dates": "तिथियाँ", + "created": "बनाया गया", + "expires": "समाप्त होता है", + "never": "कभी नहीं", + "security": "सुरक्षा", + "passwordProtected": "पासवर्ड द्वारा संरक्षित", + "publicAccess": "सार्वजनिक पहुँच", + "maxViews": "अधिकतम दृश्य: {{count}}", + "files": "फाइलें ({{count}})", + "recipients": "प्राप्तकर्ता ({{count}})", + "notAvailable": "एन/ए", + "invalidDate": "अमान्य तिथि", + "loadError": "साझाकरण विवरण लोड करने में विफल" + }, + "uploadFile": { + "title": "फाइल अपलोड करें", + "selectFile": "फाइल चुनने के लिए क्लिक करें", + "preview": "पूर्वावलोकन", + "uploadProgress": "अपलोड प्रगति", + "upload": "अपलोड करें", + "success": "फाइल सफलतापूर्वक अपलोड हुई", + "error": "फाइल अपलोड करने में विफल" + }, + "filesTable": { + "ariaLabel": "फाइल टेबल", + "columns": { + "name": "नाम", + "description": "विवरण", + "size": "आकार", + "createdAt": "बनाया गया", + "updatedAt": "अपडेट किया गया", + "actions": "क्रियाएं" + }, + "actions": { + "menu": "फाइल क्रिया मेनू", + "preview": "पूर्वावलोकन", + "edit": "संपादित करें", + "download": "डाउनलोड करें", + "delete": "हटाएं" + } + }, + "sharesTable": { + "ariaLabel": "साझाकरण टेबल", + "never": "कभी नहीं", + "columns": { + "name": "नाम", + "createdAt": "बनाया गया", + "expiresAt": "समाप्त होता है", + "status": "स्थिति", + "security": "सुरक्षा", + "files": "फाइलें", + "recipients": "प्राप्तकर्ता", + "actions": "क्रियाएं" + }, + "status": { + "neverExpires": "कभी समाप्त नहीं", + "active": "सक्रिय", + "expired": "समाप्त" + }, + "security": { + "protected": "संरक्षित", + "public": "सार्वजनिक" + }, + "filesCount": "{{count}} फाइलें", + "recipientsCount": "{{count}} प्राप्तकर्ता", + "actions": { + "menu": "साझाकरण क्रिया मेनू", + "edit": "संपादित करें", + "manageFiles": "फाइलें प्रबंधित करें", + "manageRecipients": "प्राप्तकर्ताओं का प्रबंधन करें", + "viewDetails": "विवरण देखें", + "generateLink": "लिंक उत्पन्न करें", + "editLink": "लिंक संपादित करें", + "copyLink": "लिंक कॉपी करें", + "notifyRecipients": "प्राप्तकर्ताओं को सूचित करें", + "delete": "हटाएं" + } + }, + "footer": { + "poweredBy": "द्वारा संचालित", + "kyanHomepage": "Kyantech होमपेज" + }, + "fileManager": { + "downloadError": "फाइल डाउनलोड करने में त्रुटि", + "updateSuccess": "फाइल सफलतापूर्वक अपडेट हुई", + "updateError": "फाइल अपडेट करने में त्रुटि", + "deleteSuccess": "फाइल सफलतापूर्वक हटाई गई", + "deleteError": "फाइल हटाने में त्रुटि" + }, + "shareManager": { + "deleteSuccess": "साझाकरण सफलतापूर्वक हटाया गया", + "deleteError": "साझाकरण हटाने में त्रुटि", + "updateSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ", + "updateError": "साझाकरण अपडेट करने में त्रुटि", + "filesUpdateSuccess": "फाइलें सफलतापूर्वक अपडेट हुईं", + "filesUpdateError": "फाइलें अपडेट करने में त्रुटि", + "recipientsUpdateSuccess": "प्राप्तकर्ता सफलतापूर्वक अपडेट हुए", + "recipientsUpdateError": "प्राप्तकर्ता अपडेट करने में त्रुटि", + "linkGenerateSuccess": "साझाकरण लिंक सफलतापूर्वक उत्पन्न हुआ", + "linkGenerateError": "साझाकरण लिंक उत्पन्न करने में त्रुटि", + "notifyLoading": "सूचनाएँ भेजी जा रही हैं...", + "notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया", + "notifyError": "प्राप्तकर्ताओं को सूचित करने में त्रुटि" + }, + "quickAccess": { + "files": { + "title": "मेरी फाइलें", + "description": "अपलोड की गई फाइलों तक पहुंच और प्रबंधन" + }, + "shares": { + "title": "मेरे साझाकरण", + "description": "साझा की गई फाइलों को देखें और प्रबंधित करें" + } + }, + "recentFiles": { + "title": "हाल की अपलोड्स", + "viewAll": "सभी देखें", + "uploadFile": "फाइल अपलोड करें", + "noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई" + }, + "recentShares": { + "title": "हाल के साझाकरण", + "viewAll": "सभी देखें", + "createShare": "साझा करें बनाएं", + "noShares": "अभी तक कोई साझाकरण नहीं बनाया गया", + "createFirst": "अपना पहला साझाकरण बनाएं" + }, + "storageUsage": { + "title": "स्टोरेज उपयोग", + "ariaLabel": "स्टोरेज उपयोग प्रगति पट्टी", + "used": "{{size}} उपयोग किया गया", + "available": "{{size}} उपलब्ध" + }, + "dashboard": { + "loadError": "डैशबोर्ड डेटा लोड करने में त्रुटि", + "linkCopied": "लिंक क्लिपबोर्ड में कॉपी हुआ", + "pageTitle": "डैशबोर्ड", + "breadcrumb": "डैशबोर्ड" + }, + "emptyState": { + "noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई", + "uploadFile": "फाइल अपलोड करें" + }, + "files": { + "title": "सभी फाइलें", + "uploadFile": "फाइल अपलोड करें", + "loadError": "फाइलें लोड करने में त्रुटि", + "pageTitle": "मेरी फाइलें", + "breadcrumb": "मेरी फाइलें" + }, + "searchBar": { + "placeholder": "फाइलें खोजें...", + "results": "{{total}} में से {{filtered}} फाइलें मिलीं" + }, + "forgotPassword": { + "emailLabel": "ईमेल पता", + "emailPlaceholder": "अपना ईमेल दर्ज करें", + "sending": "भेजा जा रहा है...", + "submit": "रीसेट निर्देश भेजें", + "backToLogin": "लॉगिन पर वापस जाएं", + "title": "पासवर्ड भूल गए", + "description": "अपना ईमेल पता दर्ज करें और हम आपको पासवर्ड रीसेट करने के निर्देश भेजेंगे।", + "resetInstructions": "रीसेट निर्देश आपके ईमेल पर भेज दिए गए हैं", + "pageTitle": "पासवर्ड भूल गए" + }, + "home": { + "description": "WeTransfer का ओपन-सोर्स विकल्प। फाइलें सुरक्षित रूप से साझा करें, बिना ट्रैकिंग या सीमाओं के।", + "documentation": "दस्तावेज", + "starOnGithub": "GitHub पर स्टार करें", + "privacyMessage": "गोपनीयता को ध्यान में रखते हुए बनाया गया। अपलोड से पहले आपकी फाइलें केवल उनके लिए उपलब्ध हैं जिनके पास साझाकरण लिंक है। हमेशा मुफ्त और ओपन सोर्स।", + "header": { + "fileSharing": "फाइल साझा करें", + "tagline": "सरल और मुफ्त" + }, + "pageTitle": "होम" + }, + "profile": { + "password": { + "title": "पासवर्ड बदलें", + "newPassword": "नया पासवर्ड", + "confirmPassword": "नया पासवर्ड पुष्टि करें", + "updateButton": "पासवर्ड अपडेट करें" + }, + "form": { + "title": "प्रोफ़ाइल जानकारी", + "firstName": "पहला नाम", + "lastName": "अंतिम नाम", + "username": "उपयोगकर्ता नाम", + "email": "ईमेल", + "updateButton": "प्रोफ़ाइल अपडेट करें" + }, + "header": { + "title": "प्रोफ़ाइल", + "subtitle": "अपनी व्यक्तिगत जानकारी और पासवर्ड प्रबंधित करें" + }, + "picture": { + "title": "प्रोफ़ाइल चित्र", + "description": "प्रोफ़ाइल चित्र बदलने के लिए कैमरा आइकन पर क्लिक करें", + "uploadPhoto": "फोटो अपलोड करें", + "removePhoto": "फोटो हटाएं" + }, + "errors": { + "loadFailed": "उपयोगकर्ता डेटा लोड करने में विफल", + "updateFailed": "प्रोफ़ाइल अपडेट करने में त्रुटि", + "passwordFailed": "पासवर्ड अपडेट करने में त्रुटि", + "imageFailed": "प्रोफ़ाइल चित्र अपडेट करने में त्रुटि", + "imageRemoveFailed": "प्रोफ़ाइल चित्र हटाने में त्रुटि" + }, + "messages": { + "noChanges": "सहेजने के लिए कोई परिवर्तन नहीं", + "updateSuccess": "प्रोफ़ाइल सफलतापूर्वक अपडेट हुई", + "fillPasswords": "कृपया दोनों पासवर्ड फील्ड भरें", + "passwordSuccess": "पासवर्ड सफलतापूर्वक अपडेट हुआ", + "imageSuccess": "प्रोफ़ाइल चित्र सफलतापूर्वक अपडेट हुआ", + "imageRemoved": "प्रोफ़ाइल चित्र सफलतापूर्वक हटाया गया" + }, + "pageTitle": "प्रोफ़ाइल" + }, + "resetPassword": { + "pageTitle": "पासवर्ड रीसेट करें", + "header": { + "title": "पासवर्ड रीसेट करें", + "description": "नीचे अपना नया पासवर्ड दर्ज करें" + }, + "form": { + "newPassword": "नया पासवर्ड", + "newPasswordPlaceholder": "अपना नया पासवर्ड दर्ज करें", + "confirmPassword": "नया पासवर्ड पुष्टि करें", + "confirmPasswordPlaceholder": "अपना नया पासवर्ड पुष्टि करें", + "resetting": "पासवर्ड रीसेट हो रहा है...", + "submit": "पासवर्ड रीसेट करें", + "backToLogin": "लॉगिन पर वापस जाएं" + }, + "messages": { + "success": "पासवर्ड सफलतापूर्वक रीसेट हुआ" + }, + "errors": { + "serverError": "पासवर्ड रीसेट करने में विफल। कृपया पुनः प्रयास करें।", + "invalidToken": "अमान्य या गायब रीसेट टोकन" + } + }, + "settings": { + "groups": { + "defaultDescription": "कॉन्फ़िगरेशन विकल्प", + "general": { + "title": "सामान्य", + "description": "एप्लिकेशन की बुनियादी सेटिंग्स" + }, + "email": { + "title": "ईमेल", + "description": "ईमेल सर्वर कॉन्फ़िगरेशन" + }, + "security": { + "title": "सुरक्षा", + "description": "सुरक्षा और प्रमाणीकरण सेटिंग्स" + }, + "storage": { + "title": "स्टोरेज", + "description": "फाइल स्टोरेज कॉन्फ़िगरेशन" + } + }, + "fields": { + "noDescription": "कोई विवरण उपलब्ध नहीं", + "appLogo": { + "title": "एप्लिकेशन लोगो", + "description": "एप्लिकेशन का लोगो चित्र" + }, + "appName": { + "title": "एप्लिकेशन नाम", + "description": "उपयोगकर्ताओं को दिखाया जाने वाला एप्लिकेशन नाम" + }, + "appDescription": { + "title": "एप्लिकेशन विवरण", + "description": "एप्लिकेशन का संक्षिप्त विवरण" + }, + "showHomePage": { + "title": "होम पेज दिखाएं", + "description": "इंस्टॉलेशन के बाद होम पेज दिखाएं" + }, + "smtpEnabled": { + "title": "SMTP सक्षम", + "description": "SMTP ईमेल कार्यक्षमता सक्षम या अक्षम करें" + }, + "smtpHost": { + "title": "SMTP सर्वर", + "description": "SMTP सर्वर पता" + }, + "smtpPort": { + "title": "SMTP पोर्ट", + "description": "SMTP सर्वर पोर्ट" + }, + "smtpUser": { + "title": "SMTP उपयोगकर्ता", + "description": "SMTP प्रमाणीकरण के लिए उपयोगकर्ता नाम" + }, + "smtpPass": { + "title": "SMTP पासवर्ड", + "description": "SMTP प्रमाणीकरण के लिए पासवर्ड" + }, + "smtpFromName": { + "title": "प्रेषक का नाम", + "description": "भेजे गए ईमेल के लिए डिस्प्ले नाम" + }, + "smtpFromEmail": { + "title": "प्रेषक का ईमेल", + "description": "प्रेषक का ईमेल पता" + }, + "maxLoginAttempts": { + "title": "अधिकतम लॉगिन प्रयास", + "description": "ब्लॉक करने से पहले अधिकतम लॉगिन प्रयासों की संख्या" + }, + "loginBlockDuration": { + "title": "लॉगिन ब्लॉक अवधि", + "description": "प्रयासों की सीमा पार करने पर ब्लॉक की अवधि (सेकंड में)" + }, + "passwordMinLength": { + "title": "न्यूनतम पासवर्ड लंबाई", + "description": "पासवर्ड के लिए न्यूनतम अक्षरों की संख्या" + }, + "passwordResetTokenExpiration": { + "title": "रीसेट टोकन समाप्ति", + "description": "पासवर्ड रीसेट टोकन की वैधता (सेकंड में)" + }, + "maxFileSize": { + "title": "अधिकतम फाइल आकार", + "description": "अपलोड के लिए अधिकतम अनुमत फाइल आकार (बाइट में)" + }, + "maxTotalStoragePerUser": { + "title": "प्रति उपयोगकर्ता अधिकतम स्टोरेज", + "description": "प्रति उपयोगकर्ता कुल स्टोरेज सीमा (बाइट में)" + } + }, + "buttons": { + "save": "{{group}} सहेजें" + }, + "errors": { + "loadFailed": "सेटिंग्स लोड करने में विफल", + "updateFailed": "सेटिंग्स अपडेट करने में विफल" + }, + "messages": { + "noChanges": "सहेजने के लिए कोई परिवर्तन नहीं", + "updateSuccess": "{{group}} सेटिंग्स सफलतापूर्वक अपडेट हुईं" + }, + "title": "सेटिंग्स", + "breadcrumb": "सेटिंग्स", + "pageTitle": "सेटिंग्स" + }, + "share": { + "errors": { + "invalidPassword": "अमान्य पासवर्ड। कृपया पुनः प्रयास करें।", + "loadFailed": "साझाकरण लोड करने में विफल", + "downloadFailed": "फाइल डाउनलोड करने में विफल" + }, + "messages": { + "downloadStarted": "डाउनलोड शुरू हुआ" + }, + "password": { + "title": "पासवर्ड संरक्षित साझाकरण", + "protected": "यह साझाकरण पासवर्ड द्वारा संरक्षित है", + "incorrect": "गलत पासवर्ड। कृपया पुनः प्रयास करें।", + "label": "पासवर्ड", + "placeholder": "साझाकरण का पासवर्ड दर्ज करें", + "submit": "सबमिट करें" + }, + "details": { + "untitled": "बिना शीर्षक के", + "created": "बनाया गया: {{date}}", + "expires": "समाप्त होता है: {{date}}" + }, + "notFound": { + "title": "साझाकरण नहीं मिला", + "description": "यह साझाकरण हटा दिया गया हो सकता है या समाप्त हो चुका है।" + }, + "pageTitle": "साझाकरण" + }, + "shares": { + "errors": { + "loadFailed": "साझाकरण लोड करने में विफल", + "notifyFailed": "प्राप्तकर्ताओं को सूचित करने में विफल", + "smtpConfigFailed": "SMTP कॉन्फ़िगरेशन लोड करने में विफल" + }, + "messages": { + "linkCopied": "लिंक क्लिपबोर्ड में कॉपी किया गया", + "recipientsNotified": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया" + }, + "empty": { + "message": "अभी तक कोई साझाकरण नहीं बनाया गया", + "createButton": "साझाकरण बनाएं" + }, + "header": { + "title": "मेरे साझाकरण", + "myShares": "मेरे साझाकरण" + }, + "search": { + "title": "सभी साझाकरण", + "createButton": "साझाकरण बनाएं", + "placeholder": "साझाकरण खोजें...", + "results": "{{total}} में से {{filtered}} साझाकरण मिले" + }, + "pageTitle": "साझाकरण" + }, + "users": { + "modes": { + "create": "बनाएं", + "edit": "संपादित करें" + }, + "errors": { + "loadFailed": "उपयोगकर्ता लोड करने में विफल", + "submitFailed": "{{mode}} करने में विफल", + "deleteFailed": "उपयोगकर्ता हटाने में विफल", + "statusUpdateFailed": "उपयोगकर्ता की स्थिति अपडेट करने में विफल" + }, + "messages": { + "createSuccess": "उपयोगकर्ता सफलतापूर्वक बनाया गया", + "updateSuccess": "उपयोगकर्ता सफलतापूर्वक अपडेट हुआ", + "deleteSuccess": "उपयोगकर्ता सफलतापूर्वक हटाया गया", + "activateSuccess": "उपयोगकर्ता सफलतापूर्वक सक्रिय हुआ", + "deactivateSuccess": "उपयोगकर्ता सफलतापूर्वक निष्क्रिय हुआ" + }, + "actions": { + "edit": "संपादित करें", + "activate": "सक्रिय करें", + "deactivate": "निष्क्रिय करें", + "delete": "हटाएं" + }, + "delete": { + "title": "उपयोगकर्ता हटाने की पुष्टि करें", + "confirmation": "क्या आप वाकई {{firstName}} {{lastName}} को हटाना चाहते हैं? यह क्रिया अपरिवर्तनीय है।", + "confirm": "उपयोगकर्ता हटाएं" + }, + "form": { + "titleCreate": "नया उपयोगकर्ता जोड़ें", + "titleEdit": "उपयोगकर्ता संपादित करें", + "firstName": "पहला नाम", + "lastName": "अंतिम नाम", + "username": "उपयोगकर्ता नाम", + "email": "ईमेल", + "password": "पासवर्ड", + "newPassword": "नया पासवर्ड (वैकल्पिक)", + "passwordPlaceholder": "वर्तमान पासवर्ड रखने के लिए खाली छोड़ें", + "role": "भूमिका", + "roleUser": "उपयोगकर्ता", + "roleAdmin": "व्यवस्थापक", + "create": "बनाएं", + "save": "सहेजें" + }, + "status": { + "title": "स्थिति परिवर्तन की पुष्टि करें", + "confirmation": "क्या आप वाकई {{firstName}} {{lastName}} को {{action}} करना चाहते हैं?", + "activate": "सक्रिय करें", + "deactivate": "निष्क्रिय करें", + "user": "उपयोगकर्ता" + }, + "header": { + "title": "उपयोगकर्ता प्रबंधन", + "addUser": "उपयोगकर्ता जोड़ें", + "management": "उपयोगकर्ता प्रबंधन" + }, + "table": { + "user": "उपयोगकर्ता", + "email": "ईमेल", + "status": "स्थिति", + "role": "भूमिका", + "actions": "क्रियाएं", + "active": "सक्रिय", + "inactive": "निष्क्रिय", + "admin": "व्यवस्थापक", + "userr": "उपयोगकर्ता" + } + }, + "logo": { + "labels": { + "appLogo": "एप्लिकेशन लोगो" + }, + "buttons": { + "upload": "लोगो अपलोड करें", + "remove": "लोगो हटाएं" + }, + "messages": { + "uploadSuccess": "लोगो सफलतापूर्वक अपलोड हुआ", + "removeSuccess": "लोगो सफलतापूर्वक हटाया गया" + }, + "errors": { + "uploadFailed": "लोगो अपलोड करने में विफल", + "removeFailed": "लोगो हटाने में विफल" + } + }, + "navbar": { + "logoAlt": "एप्लिकेशन लोगो", + "profileMenu": "प्रोफ़ाइल मेन्यू", + "profile": "प्रोफ़ाइल", + "settings": "सेटिंग्स", + "usersManagement": "उपयोगकर्ता प्रबंधन", + "logout": "लॉग आउट" + } +} \ No newline at end of file diff --git a/apps/app/messages/ja-JP.json b/apps/app/messages/ja-JP.json new file mode 100644 index 0000000..2f0a7a8 --- /dev/null +++ b/apps/app/messages/ja-JP.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "ようこそへ", + "signInToContinue": "続行するにはサインインしてください", + "emailLabel": "メールアドレス", + "emailPlaceholder": "メールアドレスを入力してください", + "passwordLabel": "パスワード", + "passwordPlaceholder": "パスワードを入力してください", + "signIn": "サインイン", + "signingIn": "サインイン中...", + "forgotPassword": "パスワードをお忘れですか?", + "pageTitle": "ログイン" + }, + "errors": { + "invalidCredentials": "無効なメールアドレスまたはパスワードです", + "userNotFound": "ユーザーが見つかりません", + "accountLocked": "アカウントがロックされています。後でもう一度お試しください", + "unexpectedError": "予期しないエラーが発生しました。もう一度お試しください" + }, + "validation": { + "invalidEmail": "無効なメールアドレスです", + "passwordMinLength": "パスワードは最低6文字必要です", + "firstNameRequired": "名は必須です", + "lastNameRequired": "姓は必須です", + "usernameLength": "ユーザー名は最低3文字必要です", + "usernameSpaces": "ユーザー名にスペースは使用できません", + "passwordLength": "パスワードは最低8文字必要です", + "passwordsMatch": "パスワードが一致しません", + "emailRequired": "メールアドレスは必須です", + "passwordRequired": "パスワードは必須です" + }, + "fileSelector": { + "availableFiles": "利用可能なファイル ({{count}})", + "shareFiles": "ファイルを共有 ({{count}})", + "searchPlaceholder": "ファイルを検索...", + "noMatchingFiles": "一致するファイルがありません", + "noAvailableFiles": "利用可能なファイルがありません", + "noFilesInShare": "共有ファイルがありません", + "saveChanges": "変更を保存" + }, + "recipientSelector": { + "emailPlaceholder": "受信者のメールを入力してください", + "add": "追加", + "recipients": "受信者 ({{count}})", + "notifyAll": "全員に通知", + "noRecipients": "まだ受信者が追加されていません", + "addSuccess": "受信者が正常に追加されました", + "addError": "受信者の追加に失敗しました", + "removeSuccess": "受信者が正常に削除されました", + "removeError": "受信者の削除に失敗しました", + "sendingNotifications": "通知を送信中...", + "notifySuccess": "受信者に正常に通知しました", + "notifyError": "受信者への通知に失敗しました" + }, + "navigation": { + "dashboard": "ダッシュボード" + }, + "common": { + "loading": "読み込み中です。しばらくお待ちください...", + "cancel": "キャンセル", + "save": "保存", + "delete": "削除", + "close": "閉じる", + "download": "ダウンロード", + "unexpectedError": "予期しないエラーが発生しました。もう一度お試しください。", + "yes": "はい", + "no": "いいえ", + "dashboard": "ダッシュボード" + }, + "createShare": { + "title": "共有を作成", + "nameLabel": "共有名", + "expirationLabel": "有効期限", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "最大ビュー数", + "maxViewsPlaceholder": "無制限の場合は空白のままにする", + "passwordProtection": "パスワード保護", + "passwordLabel": "パスワード", + "create": "共有を作成", + "success": "共有が正常に作成されました", + "error": "共有の作成に失敗しました" + }, + "fileActions": { + "editFile": "ファイルを編集", + "nameLabel": "名前", + "namePlaceholder": "新しい名前を入力してください", + "extension": "拡張子", + "descriptionLabel": "説明", + "descriptionPlaceholder": "ファイルの説明を入力してください", + "deleteFile": "ファイルを削除", + "deleteConfirmation": "\"{{fileName}}\"を削除してもよろしいですか?", + "deleteWarning": "この操作は元に戻せません。" + }, + "filePreview": { + "loading": "プレビューを読み込み中...", + "notAvailable": "プレビューは利用できません", + "downloadToView": "内容を見るためにファイルをダウンロードしてください", + "audioNotSupported": "お使いのブラウザはオーディオ要素をサポートしていません", + "videoNotSupported": "お使いのブラウザはビデオ要素をサポートしていません", + "loadError": "プレビューの読み込みに失敗しました", + "downloadError": "ファイルのダウンロードに失敗しました" + }, + "generateShareLink": { + "generateTitle": "共有リンクを生成", + "updateTitle": "共有リンクを更新", + "generateDescription": "ファイルを共有するためのリンクを生成します", + "updateDescription": "この共有リンクのエイリアスを更新します", + "aliasPlaceholder": "エイリアスを入力してください", + "linkReady": "共有リンクの準備ができました:", + "generateButton": "リンクを生成", + "updateButton": "リンクを更新", + "copyButton": "リンクをコピー", + "success": "リンクが正常に生成されました", + "error": "リンクの生成に失敗しました", + "copied": "リンクがクリップボードにコピーされました" + }, + "shareActions": { + "deleteTitle": "共有を削除", + "deleteConfirmation": "この共有を削除してもよろしいですか?この操作は元に戻せません。", + "editTitle": "共有を編集", + "nameLabel": "共有名", + "expirationLabel": "有効期限", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "最大ビュー数", + "maxViewsPlaceholder": "無制限の場合は空白のままにする", + "passwordProtection": "パスワード保護", + "passwordLabel": "パスワード", + "passwordPlaceholder": "パスワードを入力してください", + "newPasswordLabel": "新しいパスワード(現在のパスワードを保持する場合は空白のまま)", + "newPasswordPlaceholder": "新しいパスワードを入力してください", + "manageFilesTitle": "ファイルの管理", + "manageRecipientsTitle": "受信者の管理", + "editSuccess": "共有が正常に更新されました", + "editError": "共有の更新に失敗しました" + }, + "shareDetails": { + "title": "共有の詳細", + "subtitle": "この共有の詳細情報", + "basicInfo": "基本情報", + "name": "名前", + "untitled": "無題", + "views": "ビュー数", + "dates": "日付", + "created": "作成日", + "expires": "有効期限", + "never": "なし", + "security": "セキュリティ", + "passwordProtected": "パスワード保護", + "publicAccess": "公開アクセス", + "maxViews": "最大ビュー数: {{count}}", + "files": "ファイル ({{count}})", + "recipients": "受信者 ({{count}})", + "notAvailable": "該当なし", + "invalidDate": "無効な日付です", + "loadError": "共有の詳細の読み込みに失敗しました" + }, + "uploadFile": { + "title": "ファイルをアップロード", + "selectFile": "ファイルを選択するにはクリックしてください", + "preview": "プレビュー", + "uploadProgress": "アップロードの進行状況", + "upload": "アップロード", + "success": "ファイルが正常にアップロードされました", + "error": "ファイルのアップロードに失敗しました" + }, + "filesTable": { + "ariaLabel": "ファイルテーブル", + "columns": { + "name": "名前", + "description": "説明", + "size": "サイズ", + "createdAt": "作成日", + "updatedAt": "更新日", + "actions": "操作" + }, + "actions": { + "menu": "ファイル操作メニュー", + "preview": "プレビュー", + "edit": "編集", + "download": "ダウンロード", + "delete": "削除" + } + }, + "sharesTable": { + "ariaLabel": "共有テーブル", + "never": "なし", + "columns": { + "name": "名前", + "createdAt": "作成日", + "expiresAt": "有効期限", + "status": "ステータス", + "security": "セキュリティ", + "files": "ファイル", + "recipients": "受信者", + "actions": "操作" + }, + "status": { + "neverExpires": "無期限", + "active": "アクティブ", + "expired": "期限切れ" + }, + "security": { + "protected": "保護済み", + "public": "公開" + }, + "filesCount": "{{count}} ファイル", + "recipientsCount": "{{count}} 受信者", + "actions": { + "menu": "共有操作メニュー", + "edit": "編集", + "manageFiles": "ファイル管理", + "manageRecipients": "受信者管理", + "viewDetails": "詳細を表示", + "generateLink": "リンクを生成", + "editLink": "リンクを編集", + "copyLink": "リンクをコピー", + "notifyRecipients": "受信者に通知", + "delete": "削除" + } + }, + "footer": { + "poweredBy": "提供:", + "kyanHomepage": "Kyantech ホームページ" + }, + "fileManager": { + "downloadError": "ファイルのダウンロードに失敗しました", + "updateSuccess": "ファイルが正常に更新されました", + "updateError": "ファイルの更新に失敗しました", + "deleteSuccess": "ファイルが正常に削除されました", + "deleteError": "ファイルの削除に失敗しました" + }, + "shareManager": { + "deleteSuccess": "共有が正常に削除されました", + "deleteError": "共有の削除に失敗しました", + "updateSuccess": "共有が正常に更新されました", + "updateError": "共有の更新に失敗しました", + "filesUpdateSuccess": "ファイルが正常に更新されました", + "filesUpdateError": "ファイルの更新に失敗しました", + "recipientsUpdateSuccess": "受信者が正常に更新されました", + "recipientsUpdateError": "受信者の更新に失敗しました", + "linkGenerateSuccess": "共有リンクが正常に生成されました", + "linkGenerateError": "共有リンクの生成に失敗しました", + "notifyLoading": "通知を送信中...", + "notifySuccess": "受信者に正常に通知しました", + "notifyError": "受信者への通知に失敗しました" + }, + "quickAccess": { + "files": { + "title": "マイファイル", + "description": "アップロードされたファイルにアクセスし、管理します" + }, + "shares": { + "title": "マイ共有", + "description": "共有されたファイルを表示および管理します" + } + }, + "recentFiles": { + "title": "最近のアップロード", + "viewAll": "すべて表示", + "uploadFile": "ファイルをアップロード", + "noFiles": "まだファイルがアップロードされていません" + }, + "recentShares": { + "title": "最近の共有", + "viewAll": "すべて表示", + "createShare": "共有を作成", + "noShares": "まだ共有が作成されていません", + "createFirst": "最初の共有を作成してください" + }, + "storageUsage": { + "title": "ストレージ使用量", + "ariaLabel": "ストレージ使用状況のプログレスバー", + "used": "{{size}} 使用済み", + "available": "{{size}} 利用可能" + }, + "dashboard": { + "loadError": "ダッシュボードデータの読み込みに失敗しました", + "linkCopied": "リンクがクリップボードにコピーされました", + "pageTitle": "ダッシュボード", + "breadcrumb": "ダッシュボード" + }, + "emptyState": { + "noFiles": "まだファイルがアップロードされていません", + "uploadFile": "ファイルをアップロード" + }, + "files": { + "title": "すべてのファイル", + "uploadFile": "ファイルをアップロード", + "loadError": "ファイルの読み込みに失敗しました", + "pageTitle": "マイファイル", + "breadcrumb": "マイファイル" + }, + "searchBar": { + "placeholder": "ファイルを検索...", + "results": "全{{total}}件中{{filtered}}件が見つかりました" + }, + "forgotPassword": { + "emailLabel": "メールアドレス", + "emailPlaceholder": "メールアドレスを入力してください", + "sending": "送信中...", + "submit": "パスワードリセットの指示を送信", + "backToLogin": "ログインに戻る", + "title": "パスワードをお忘れですか?", + "description": "メールアドレスを入力すると、パスワードリセットの指示を送信します。", + "resetInstructions": "パスワードリセットの指示がメールに送信されました", + "pageTitle": "パスワードをお忘れですか?" + }, + "home": { + "description": "WeTransferのオープンソース代替です。トラッキングや制限なしに安全にファイルを共有します。", + "documentation": "ドキュメント", + "starOnGithub": "GitHubでスターを付ける", + "privacyMessage": "プライバシーを重視して作られています。アップロード前のファイルは、共有リンクを持つ人だけがアクセスできます。常に無料でオープンソースです。", + "header": { + "fileSharing": "ファイル共有", + "tagline": "シンプルで無料" + }, + "pageTitle": "ホーム" + }, + "profile": { + "password": { + "title": "パスワードを変更", + "newPassword": "新しいパスワード", + "confirmPassword": "新しいパスワードの確認", + "updateButton": "パスワードを更新" + }, + "form": { + "title": "プロフィール情報", + "firstName": "名", + "lastName": "姓", + "username": "ユーザー名", + "email": "メール", + "updateButton": "プロフィールを更新" + }, + "header": { + "title": "プロフィール", + "subtitle": "個人情報とパスワードを管理" + }, + "picture": { + "title": "プロフィール写真", + "description": "写真アイコンをクリックしてプロフィール写真を変更", + "uploadPhoto": "写真をアップロード", + "removePhoto": "写真を削除" + }, + "errors": { + "loadFailed": "ユーザーデータの読み込みに失敗しました", + "updateFailed": "プロフィールの更新に失敗しました", + "passwordFailed": "パスワードの更新に失敗しました", + "imageFailed": "プロフィール画像の更新に失敗しました", + "imageRemoveFailed": "プロフィール画像の削除に失敗しました" + }, + "messages": { + "noChanges": "保存する変更はありません", + "updateSuccess": "プロフィールが正常に更新されました", + "fillPasswords": "両方のパスワードフィールドに入力してください", + "passwordSuccess": "パスワードが正常に更新されました", + "imageSuccess": "プロフィール画像が正常に更新されました", + "imageRemoved": "プロフィール画像が正常に削除されました" + }, + "pageTitle": "プロフィール" + }, + "resetPassword": { + "pageTitle": "パスワードリセット", + "header": { + "title": "パスワードリセット", + "description": "以下に新しいパスワードを入力してください" + }, + "form": { + "newPassword": "新しいパスワード", + "newPasswordPlaceholder": "新しいパスワードを入力してください", + "confirmPassword": "新しいパスワードの確認", + "confirmPasswordPlaceholder": "新しいパスワードを再入力してください", + "resetting": "パスワードをリセット中...", + "submit": "パスワードをリセット", + "backToLogin": "ログインに戻る" + }, + "messages": { + "success": "パスワードが正常にリセットされました" + }, + "errors": { + "serverError": "パスワードのリセットに失敗しました。もう一度お試しください。", + "invalidToken": "無効なリセットトークン、またはトークンが存在しません" + } + }, + "settings": { + "groups": { + "defaultDescription": "構成オプション", + "general": { + "title": "一般", + "description": "基本的なアプリケーション設定" + }, + "email": { + "title": "メール", + "description": "メールサーバーの設定" + }, + "security": { + "title": "セキュリティ", + "description": "セキュリティおよび認証設定" + }, + "storage": { + "title": "ストレージ", + "description": "ファイルストレージの設定" + } + }, + "fields": { + "noDescription": "利用可能な説明はありません", + "appLogo": { + "title": "アプリケーションロゴ", + "description": "アプリケーションのロゴ画像" + }, + "appName": { + "title": "アプリケーション名", + "description": "ユーザーに表示されるアプリケーション名" + }, + "appDescription": { + "title": "アプリケーションの説明", + "description": "アプリケーションの簡単な説明" + }, + "showHomePage": { + "title": "ホームページを表示", + "description": "インストール後にホームページを表示" + }, + "smtpEnabled": { + "title": "SMTP有効", + "description": "SMTPメール機能を有効または無効にする" + }, + "smtpHost": { + "title": "SMTPサーバー", + "description": "SMTPサーバーのアドレス" + }, + "smtpPort": { + "title": "SMTPポート", + "description": "SMTPサーバーのポート" + }, + "smtpUser": { + "title": "SMTPユーザー", + "description": "SMTP認証用のユーザー名" + }, + "smtpPass": { + "title": "SMTPパスワード", + "description": "SMTP認証用のパスワード" + }, + "smtpFromName": { + "title": "送信者名", + "description": "送信されるメールの表示名" + }, + "smtpFromEmail": { + "title": "送信者メール", + "description": "送信者のメールアドレス" + }, + "maxLoginAttempts": { + "title": "最大ログイン試行回数", + "description": "ブロックする前の最大ログイン試行回数" + }, + "loginBlockDuration": { + "title": "ログインブロック期間", + "description": "試行回数超過後のブロック期間(秒単位)" + }, + "passwordMinLength": { + "title": "パスワードの最小長", + "description": "パスワードに必要な最小文字数" + }, + "passwordResetTokenExpiration": { + "title": "リセットトークンの有効期限", + "description": "パスワードリセットトークンの有効期間(秒単位)" + }, + "maxFileSize": { + "title": "最大ファイルサイズ", + "description": "アップロード可能な最大ファイルサイズ(バイト単位)" + }, + "maxTotalStoragePerUser": { + "title": "ユーザーごとの最大ストレージ", + "description": "ユーザーごとの総ストレージ制限(バイト単位)" + } + }, + "buttons": { + "save": "{{group}}を保存" + }, + "errors": { + "loadFailed": "設定の読み込みに失敗しました", + "updateFailed": "設定の更新に失敗しました" + }, + "messages": { + "noChanges": "保存する変更はありません", + "updateSuccess": "{{group}}の設定が正常に更新されました" + }, + "title": "設定", + "breadcrumb": "設定", + "pageTitle": "設定" + }, + "share": { + "errors": { + "invalidPassword": "無効なパスワードです。もう一度お試しください。", + "loadFailed": "共有の読み込みに失敗しました", + "downloadFailed": "ファイルのダウンロードに失敗しました" + }, + "messages": { + "downloadStarted": "ダウンロードが開始されました" + }, + "password": { + "title": "パスワード保護された共有", + "protected": "この共有はパスワードで保護されています", + "incorrect": "パスワードが正しくありません。もう一度お試しください。", + "label": "パスワード", + "placeholder": "共有のパスワードを入力してください", + "submit": "送信" + }, + "details": { + "untitled": "無題", + "created": "作成日: {{date}}", + "expires": "有効期限: {{date}}" + }, + "notFound": { + "title": "共有が見つかりません", + "description": "この共有は削除されたか、期限が切れている可能性があります。" + }, + "pageTitle": "共有" + }, + "shares": { + "errors": { + "loadFailed": "共有の読み込みに失敗しました", + "notifyFailed": "受信者への通知に失敗しました", + "smtpConfigFailed": "SMTP設定の読み込みに失敗しました" + }, + "messages": { + "linkCopied": "リンクがクリップボードにコピーされました", + "recipientsNotified": "受信者に正常に通知されました" + }, + "empty": { + "message": "まだ共有が作成されていません", + "createButton": "共有を作成" + }, + "header": { + "title": "マイ共有", + "myShares": "マイ共有" + }, + "search": { + "title": "すべての共有", + "createButton": "共有を作成", + "placeholder": "共有を検索...", + "results": "全{{total}}件中{{filtered}}件が見つかりました" + }, + "pageTitle": "共有" + }, + "users": { + "modes": { + "create": "作成", + "edit": "編集" + }, + "errors": { + "loadFailed": "ユーザーの読み込みに失敗しました", + "submitFailed": "ユーザーの{{mode}}に失敗しました", + "deleteFailed": "ユーザーの削除に失敗しました", + "statusUpdateFailed": "ユーザー状態の更新に失敗しました" + }, + "messages": { + "createSuccess": "ユーザーが正常に作成されました", + "updateSuccess": "ユーザーが正常に更新されました", + "deleteSuccess": "ユーザーが正常に削除されました", + "activateSuccess": "ユーザーが正常にアクティブ化されました", + "deactivateSuccess": "ユーザーが正常に非アクティブ化されました" + }, + "actions": { + "edit": "編集", + "activate": "アクティブ化", + "deactivate": "非アクティブ化", + "delete": "削除" + }, + "delete": { + "title": "ユーザー削除の確認", + "confirmation": "{{firstName}} {{lastName}} を削除してもよろしいですか?この操作は元に戻せません。", + "confirm": "ユーザーを削除" + }, + "form": { + "titleCreate": "新しいユーザーを追加", + "titleEdit": "ユーザーを編集", + "firstName": "名", + "lastName": "姓", + "username": "ユーザー名", + "email": "メール", + "password": "パスワード", + "newPassword": "新しいパスワード(任意)", + "passwordPlaceholder": "現在のパスワードを保持する場合は空白のままにする", + "role": "役割", + "roleUser": "ユーザー", + "roleAdmin": "管理者", + "create": "作成", + "save": "保存" + }, + "status": { + "title": "状態変更の確認", + "confirmation": "{{firstName}} {{lastName}} を{{action}}してもよろしいですか?", + "activate": "アクティブ化", + "deactivate": "非アクティブ化", + "user": "ユーザー" + }, + "header": { + "title": "ユーザー管理", + "addUser": "ユーザーを追加", + "management": "ユーザー管理" + }, + "table": { + "user": "ユーザー", + "email": "メール", + "status": "状態", + "role": "役割", + "actions": "操作", + "active": "アクティブ", + "inactive": "非アクティブ", + "admin": "管理者", + "userr": "ユーザー" + } + }, + "logo": { + "labels": { + "appLogo": "アプリケーションロゴ" + }, + "buttons": { + "upload": "ロゴをアップロード", + "remove": "ロゴを削除" + }, + "messages": { + "uploadSuccess": "ロゴが正常にアップロードされました", + "removeSuccess": "ロゴが正常に削除されました" + }, + "errors": { + "uploadFailed": "ロゴのアップロードに失敗しました", + "removeFailed": "ロゴの削除に失敗しました" + } + }, + "navbar": { + "logoAlt": "アプリケーションロゴ", + "profileMenu": "プロフィールメニュー", + "profile": "プロフィール", + "settings": "設定", + "usersManagement": "ユーザー管理", + "logout": "ログアウト" + } +} \ No newline at end of file diff --git a/apps/app/messages/ko-KR.json b/apps/app/messages/ko-KR.json new file mode 100644 index 0000000..8f5012d --- /dev/null +++ b/apps/app/messages/ko-KR.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "에 오신 것을 환영합니다", + "signInToContinue": "계속하려면 로그인하세요", + "emailLabel": "이메일 주소", + "emailPlaceholder": "이메일을 입력하세요", + "passwordLabel": "비밀번호", + "passwordPlaceholder": "비밀번호를 입력하세요", + "signIn": "로그인", + "signingIn": "로그인 중...", + "forgotPassword": "비밀번호를 잊으셨나요?", + "pageTitle": "로그인" + }, + "errors": { + "invalidCredentials": "잘못된 이메일 또는 비밀번호입니다", + "userNotFound": "사용자를 찾을 수 없습니다", + "accountLocked": "계정이 잠겼습니다. 나중에 다시 시도하세요", + "unexpectedError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요" + }, + "validation": { + "invalidEmail": "유효하지 않은 이메일 주소입니다", + "passwordMinLength": "비밀번호는 최소 6자 이상이어야 합니다", + "firstNameRequired": "이름은 필수입니다", + "lastNameRequired": "성을 입력하세요", + "usernameLength": "사용자 이름은 최소 3자 이상이어야 합니다", + "usernameSpaces": "사용자 이름에는 공백을 사용할 수 없습니다", + "passwordLength": "비밀번호는 최소 8자 이상이어야 합니다", + "passwordsMatch": "비밀번호가 일치하지 않습니다", + "emailRequired": "이메일은 필수입니다", + "passwordRequired": "비밀번호는 필수입니다" + }, + "fileSelector": { + "availableFiles": "사용 가능한 파일 ({{count}})", + "shareFiles": "파일 공유 ({{count}})", + "searchPlaceholder": "파일 검색...", + "noMatchingFiles": "일치하는 파일이 없습니다", + "noAvailableFiles": "사용 가능한 파일이 없습니다", + "noFilesInShare": "공유된 파일이 없습니다", + "saveChanges": "변경 사항 저장" + }, + "recipientSelector": { + "emailPlaceholder": "수신자 이메일을 입력하세요", + "add": "추가", + "recipients": "수신자 ({{count}})", + "notifyAll": "모두에게 알림", + "noRecipients": "아직 수신자가 추가되지 않았습니다", + "addSuccess": "수신자가 성공적으로 추가되었습니다", + "addError": "수신자 추가에 실패했습니다", + "removeSuccess": "수신자가 성공적으로 제거되었습니다", + "removeError": "수신자 제거에 실패했습니다", + "sendingNotifications": "알림 전송 중...", + "notifySuccess": "수신자에게 성공적으로 알렸습니다", + "notifyError": "수신자 알림 전송에 실패했습니다" + }, + "navigation": { + "dashboard": "대시보드" + }, + "common": { + "loading": "로딩 중입니다. 잠시 기다려주세요...", + "cancel": "취소", + "save": "저장", + "delete": "삭제", + "close": "닫기", + "download": "다운로드", + "unexpectedError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요.", + "yes": "예", + "no": "아니오", + "dashboard": "대시보드" + }, + "createShare": { + "title": "공유 생성", + "nameLabel": "공유 이름", + "expirationLabel": "만료 날짜", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "최대 조회수", + "maxViewsPlaceholder": "무제한인 경우 비워두세요", + "passwordProtection": "비밀번호 보호", + "passwordLabel": "비밀번호", + "create": "공유 생성", + "success": "공유가 성공적으로 생성되었습니다", + "error": "공유 생성에 실패했습니다" + }, + "fileActions": { + "editFile": "파일 편집", + "nameLabel": "이름", + "namePlaceholder": "새 이름을 입력하세요", + "extension": "확장자", + "descriptionLabel": "설명", + "descriptionPlaceholder": "파일 설명을 입력하세요", + "deleteFile": "파일 삭제", + "deleteConfirmation": "\"{{fileName}}\"을(를) 삭제하시겠습니까?", + "deleteWarning": "이 작업은 취소할 수 없습니다." + }, + "filePreview": { + "loading": "미리보기를 불러오는 중...", + "notAvailable": "미리보기를 사용할 수 없습니다", + "downloadToView": "내용을 보려면 파일을 다운로드하세요", + "audioNotSupported": "브라우저가 오디오 요소를 지원하지 않습니다", + "videoNotSupported": "브라우저가 비디오 요소를 지원하지 않습니다", + "loadError": "미리보기 불러오기에 실패했습니다", + "downloadError": "파일 다운로드에 실패했습니다" + }, + "generateShareLink": { + "generateTitle": "공유 링크 생성", + "updateTitle": "공유 링크 업데이트", + "generateDescription": "파일을 공유할 링크를 생성합니다", + "updateDescription": "이 공유 링크의 별칭을 업데이트합니다", + "aliasPlaceholder": "별칭을 입력하세요", + "linkReady": "공유 링크가 준비되었습니다:", + "generateButton": "링크 생성", + "updateButton": "링크 업데이트", + "copyButton": "링크 복사", + "success": "링크가 성공적으로 생성되었습니다", + "error": "링크 생성에 실패했습니다", + "copied": "링크가 클립보드에 복사되었습니다" + }, + "shareActions": { + "deleteTitle": "공유 삭제", + "deleteConfirmation": "이 공유를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "editTitle": "공유 편집", + "nameLabel": "공유 이름", + "expirationLabel": "만료 날짜", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "최대 조회수", + "maxViewsPlaceholder": "무제한인 경우 비워두세요", + "passwordProtection": "비밀번호 보호", + "passwordLabel": "비밀번호", + "passwordPlaceholder": "비밀번호를 입력하세요", + "newPasswordLabel": "새 비밀번호 (현재 비밀번호 유지 시 비워두세요)", + "newPasswordPlaceholder": "새 비밀번호를 입력하세요", + "manageFilesTitle": "파일 관리", + "manageRecipientsTitle": "수신자 관리", + "editSuccess": "공유가 성공적으로 업데이트되었습니다", + "editError": "공유 업데이트에 실패했습니다" + }, + "shareDetails": { + "title": "공유 세부 정보", + "subtitle": "이 공유에 대한 자세한 정보", + "basicInfo": "기본 정보", + "name": "이름", + "untitled": "제목 없음", + "views": "조회수", + "dates": "날짜", + "created": "생성됨", + "expires": "만료됨", + "never": "없음", + "security": "보안", + "passwordProtected": "비밀번호 보호됨", + "publicAccess": "공개 접근", + "maxViews": "최대 조회수: {{count}}", + "files": "파일 ({{count}})", + "recipients": "수신자 ({{count}})", + "notAvailable": "해당 없음", + "invalidDate": "유효하지 않은 날짜입니다", + "loadError": "공유 세부 정보를 불러오는데 실패했습니다" + }, + "uploadFile": { + "title": "파일 업로드", + "selectFile": "파일 선택을 위해 클릭하세요", + "preview": "미리보기", + "uploadProgress": "업로드 진행", + "upload": "업로드", + "success": "파일이 성공적으로 업로드되었습니다", + "error": "파일 업로드에 실패했습니다" + }, + "filesTable": { + "ariaLabel": "파일 테이블", + "columns": { + "name": "이름", + "description": "설명", + "size": "크기", + "createdAt": "생성일", + "updatedAt": "수정일", + "actions": "작업" + }, + "actions": { + "menu": "파일 작업 메뉴", + "preview": "미리보기", + "edit": "편집", + "download": "다운로드", + "delete": "삭제" + } + }, + "sharesTable": { + "ariaLabel": "공유 테이블", + "never": "없음", + "columns": { + "name": "이름", + "createdAt": "생성일", + "expiresAt": "만료일", + "status": "상태", + "security": "보안", + "files": "파일", + "recipients": "수신자", + "actions": "작업" + }, + "status": { + "neverExpires": "만료되지 않음", + "active": "활성", + "expired": "만료됨" + }, + "security": { + "protected": "보호됨", + "public": "공개" + }, + "filesCount": "{{count}}개의 파일", + "recipientsCount": "{{count}}명의 수신자", + "actions": { + "menu": "공유 작업 메뉴", + "edit": "편집", + "manageFiles": "파일 관리", + "manageRecipients": "수신자 관리", + "viewDetails": "세부 정보 보기", + "generateLink": "링크 생성", + "editLink": "링크 편집", + "copyLink": "링크 복사", + "notifyRecipients": "수신자 알림", + "delete": "삭제" + } + }, + "footer": { + "poweredBy": "제공:", + "kyanHomepage": "Kyantech 홈페이지" + }, + "fileManager": { + "downloadError": "파일 다운로드에 실패했습니다", + "updateSuccess": "파일이 성공적으로 업데이트되었습니다", + "updateError": "파일 업데이트에 실패했습니다", + "deleteSuccess": "파일이 성공적으로 삭제되었습니다", + "deleteError": "파일 삭제에 실패했습니다" + }, + "shareManager": { + "deleteSuccess": "공유가 성공적으로 삭제되었습니다", + "deleteError": "공유 삭제에 실패했습니다", + "updateSuccess": "공유가 성공적으로 업데이트되었습니다", + "updateError": "공유 업데이트에 실패했습니다", + "filesUpdateSuccess": "파일이 성공적으로 업데이트되었습니다", + "filesUpdateError": "파일 업데이트에 실패했습니다", + "recipientsUpdateSuccess": "수신자가 성공적으로 업데이트되었습니다", + "recipientsUpdateError": "수신자 업데이트에 실패했습니다", + "linkGenerateSuccess": "공유 링크가 성공적으로 생성되었습니다", + "linkGenerateError": "공유 링크 생성에 실패했습니다", + "notifyLoading": "알림 전송 중...", + "notifySuccess": "수신자에게 성공적으로 알렸습니다", + "notifyError": "수신자 알림 전송에 실패했습니다" + }, + "quickAccess": { + "files": { + "title": "내 파일", + "description": "업로드된 파일에 접근하고 관리합니다" + }, + "shares": { + "title": "내 공유", + "description": "공유된 파일을 보고 관리합니다" + } + }, + "recentFiles": { + "title": "최근 업로드", + "viewAll": "전체 보기", + "uploadFile": "파일 업로드", + "noFiles": "아직 파일이 업로드되지 않았습니다" + }, + "recentShares": { + "title": "최근 공유", + "viewAll": "전체 보기", + "createShare": "공유 생성", + "noShares": "아직 공유가 생성되지 않았습니다", + "createFirst": "첫 번째 공유를 생성하세요" + }, + "storageUsage": { + "title": "스토리지 사용량", + "ariaLabel": "스토리지 사용량 진행 바", + "used": "{{size}} 사용됨", + "available": "{{size}} 사용 가능" + }, + "dashboard": { + "loadError": "대시보드 데이터를 불러오는데 실패했습니다", + "linkCopied": "링크가 클립보드에 복사되었습니다", + "pageTitle": "대시보드", + "breadcrumb": "대시보드" + }, + "emptyState": { + "noFiles": "아직 파일이 업로드되지 않았습니다", + "uploadFile": "파일 업로드" + }, + "files": { + "title": "모든 파일", + "uploadFile": "파일 업로드", + "loadError": "파일을 불러오는데 실패했습니다", + "pageTitle": "내 파일", + "breadcrumb": "내 파일" + }, + "searchBar": { + "placeholder": "파일 검색...", + "results": "전체 {{total}}개 중 {{filtered}}개 파일을 찾았습니다" + }, + "forgotPassword": { + "emailLabel": "이메일 주소", + "emailPlaceholder": "이메일을 입력하세요", + "sending": "전송 중...", + "submit": "비밀번호 재설정 지침 전송", + "backToLogin": "로그인으로 돌아가기", + "title": "비밀번호를 잊으셨나요?", + "description": "이메일 주소를 입력하면 비밀번호 재설정 지침을 보내드립니다.", + "resetInstructions": "비밀번호 재설정 지침이 이메일로 전송되었습니다", + "pageTitle": "비밀번호를 잊으셨나요?" + }, + "home": { + "description": "WeTransfer의 오픈소스 대안입니다. 추적이나 제한 없이 파일을 안전하게 공유하세요.", + "documentation": "문서", + "starOnGithub": "GitHub에서 별표 달기", + "privacyMessage": "개인정보 보호를 고려하여 제작되었습니다. 업로드 전 파일은 공유 링크가 있는 사람만 접근할 수 있습니다. 항상 무료이며 오픈소스입니다.", + "header": { + "fileSharing": "파일 공유", + "tagline": "심플하고 무료" + }, + "pageTitle": "홈" + }, + "profile": { + "password": { + "title": "비밀번호 변경", + "newPassword": "새 비밀번호", + "confirmPassword": "새 비밀번호 확인", + "updateButton": "비밀번호 업데이트" + }, + "form": { + "title": "프로필 정보", + "firstName": "이름", + "lastName": "성", + "username": "사용자 이름", + "email": "이메일", + "updateButton": "프로필 업데이트" + }, + "header": { + "title": "프로필", + "subtitle": "개인 정보와 비밀번호를 관리하세요" + }, + "picture": { + "title": "프로필 사진", + "description": "프로필 사진을 변경하려면 카메라 아이콘을 클릭하세요", + "uploadPhoto": "사진 업로드", + "removePhoto": "사진 삭제" + }, + "errors": { + "loadFailed": "사용자 데이터를 불러오는데 실패했습니다", + "updateFailed": "프로필 업데이트에 실패했습니다", + "passwordFailed": "비밀번호 업데이트에 실패했습니다", + "imageFailed": "프로필 이미지 업데이트에 실패했습니다", + "imageRemoveFailed": "프로필 이미지 삭제에 실패했습니다" + }, + "messages": { + "noChanges": "저장할 변경 사항이 없습니다", + "updateSuccess": "프로필이 성공적으로 업데이트되었습니다", + "fillPasswords": "두 비밀번호 필드를 모두 입력하세요", + "passwordSuccess": "비밀번호가 성공적으로 업데이트되었습니다", + "imageSuccess": "프로필 이미지가 성공적으로 업데이트되었습니다", + "imageRemoved": "프로필 이미지가 성공적으로 삭제되었습니다" + }, + "pageTitle": "프로필" + }, + "resetPassword": { + "pageTitle": "비밀번호 재설정", + "header": { + "title": "비밀번호 재설정", + "description": "아래에 새 비밀번호를 입력하세요" + }, + "form": { + "newPassword": "새 비밀번호", + "newPasswordPlaceholder": "새 비밀번호를 입력하세요", + "confirmPassword": "새 비밀번호 확인", + "confirmPasswordPlaceholder": "새 비밀번호를 다시 입력하세요", + "resetting": "비밀번호 재설정 중...", + "submit": "비밀번호 재설정", + "backToLogin": "로그인으로 돌아가기" + }, + "messages": { + "success": "비밀번호가 성공적으로 재설정되었습니다" + }, + "errors": { + "serverError": "비밀번호 재설정에 실패했습니다. 다시 시도해주세요.", + "invalidToken": "유효하지 않거나 누락된 재설정 토큰" + } + }, + "settings": { + "groups": { + "defaultDescription": "구성 옵션", + "general": { + "title": "일반", + "description": "기본 애플리케이션 설정" + }, + "email": { + "title": "이메일", + "description": "이메일 서버 구성" + }, + "security": { + "title": "보안", + "description": "보안 및 인증 설정" + }, + "storage": { + "title": "스토리지", + "description": "파일 스토리지 구성" + } + }, + "fields": { + "noDescription": "설명이 제공되지 않았습니다", + "appLogo": { + "title": "애플리케이션 로고", + "description": "애플리케이션 로고 이미지" + }, + "appName": { + "title": "애플리케이션 이름", + "description": "사용자에게 표시되는 애플리케이션 이름" + }, + "appDescription": { + "title": "애플리케이션 설명", + "description": "애플리케이션에 대한 간략한 설명" + }, + "showHomePage": { + "title": "홈페이지 표시", + "description": "설치 후 홈페이지를 표시합니다" + }, + "smtpEnabled": { + "title": "SMTP 사용", + "description": "SMTP 이메일 기능을 활성화 또는 비활성화합니다" + }, + "smtpHost": { + "title": "SMTP 서버", + "description": "SMTP 서버 주소" + }, + "smtpPort": { + "title": "SMTP 포트", + "description": "SMTP 서버 포트" + }, + "smtpUser": { + "title": "SMTP 사용자", + "description": "SMTP 인증을 위한 사용자 이름" + }, + "smtpPass": { + "title": "SMTP 비밀번호", + "description": "SMTP 인증을 위한 비밀번호" + }, + "smtpFromName": { + "title": "발신자 이름", + "description": "보내는 이메일에 표시될 이름" + }, + "smtpFromEmail": { + "title": "발신자 이메일", + "description": "발신자 이메일 주소" + }, + "maxLoginAttempts": { + "title": "최대 로그인 시도 횟수", + "description": "차단되기 전 최대 로그인 시도 횟수" + }, + "loginBlockDuration": { + "title": "로그인 차단 기간", + "description": "시도 초과 시 차단되는 시간(초 단위)" + }, + "passwordMinLength": { + "title": "최소 비밀번호 길이", + "description": "비밀번호에 필요한 최소 문자 수" + }, + "passwordResetTokenExpiration": { + "title": "비밀번호 재설정 토큰 만료", + "description": "비밀번호 재설정 토큰의 유효 기간(초 단위)" + }, + "maxFileSize": { + "title": "최대 파일 크기", + "description": "업로드 가능한 최대 파일 크기(바이트 단위)" + }, + "maxTotalStoragePerUser": { + "title": "사용자당 최대 스토리지", + "description": "사용자당 총 스토리지 제한(바이트 단위)" + } + }, + "buttons": { + "save": "{{group}} 저장" + }, + "errors": { + "loadFailed": "설정을 불러오는데 실패했습니다", + "updateFailed": "설정 업데이트에 실패했습니다" + }, + "messages": { + "noChanges": "저장할 변경 사항이 없습니다", + "updateSuccess": "{{group}} 설정이 성공적으로 업데이트되었습니다" + }, + "title": "설정", + "breadcrumb": "설정", + "pageTitle": "설정" + }, + "share": { + "errors": { + "invalidPassword": "잘못된 비밀번호입니다. 다시 시도해주세요.", + "loadFailed": "공유를 불러오는데 실패했습니다", + "downloadFailed": "파일 다운로드에 실패했습니다" + }, + "messages": { + "downloadStarted": "다운로드가 시작되었습니다" + }, + "password": { + "title": "비밀번호 보호 공유", + "protected": "이 공유는 비밀번호로 보호되어 있습니다", + "incorrect": "비밀번호가 올바르지 않습니다. 다시 시도해주세요.", + "label": "비밀번호", + "placeholder": "공유 비밀번호를 입력하세요", + "submit": "제출" + }, + "details": { + "untitled": "제목 없음", + "created": "생성됨: {{date}}", + "expires": "만료됨: {{date}}" + }, + "notFound": { + "title": "공유를 찾을 수 없습니다", + "description": "이 공유는 삭제되었거나 만료되었을 수 있습니다." + }, + "pageTitle": "공유" + }, + "shares": { + "errors": { + "loadFailed": "공유 목록을 불러오는데 실패했습니다", + "notifyFailed": "수신자 알림에 실패했습니다", + "smtpConfigFailed": "SMTP 설정을 불러오는데 실패했습니다" + }, + "messages": { + "linkCopied": "링크가 클립보드에 복사되었습니다", + "recipientsNotified": "수신자에게 성공적으로 알렸습니다" + }, + "empty": { + "message": "아직 공유가 생성되지 않았습니다", + "createButton": "공유 생성" + }, + "header": { + "title": "내 공유", + "myShares": "내 공유" + }, + "search": { + "title": "전체 공유", + "createButton": "공유 생성", + "placeholder": "공유 검색...", + "results": "전체 {{total}}개 중 {{filtered}}개가 검색되었습니다" + }, + "pageTitle": "공유" + }, + "users": { + "modes": { + "create": "생성", + "edit": "편집" + }, + "errors": { + "loadFailed": "사용자 목록을 불러오는데 실패했습니다", + "submitFailed": "사용자 {{mode}}에 실패했습니다", + "deleteFailed": "사용자 삭제에 실패했습니다", + "statusUpdateFailed": "사용자 상태 업데이트에 실패했습니다" + }, + "messages": { + "createSuccess": "사용자가 성공적으로 생성되었습니다", + "updateSuccess": "사용자가 성공적으로 업데이트되었습니다", + "deleteSuccess": "사용자가 성공적으로 삭제되었습니다", + "activateSuccess": "사용자가 성공적으로 활성화되었습니다", + "deactivateSuccess": "사용자가 성공적으로 비활성화되었습니다" + }, + "actions": { + "edit": "편집", + "activate": "활성화", + "deactivate": "비활성화", + "delete": "삭제" + }, + "delete": { + "title": "사용자 삭제 확인", + "confirmation": "{{firstName}} {{lastName}} 사용자를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.", + "confirm": "사용자 삭제" + }, + "form": { + "titleCreate": "새 사용자 추가", + "titleEdit": "사용자 편집", + "firstName": "이름", + "lastName": "성", + "username": "사용자 이름", + "email": "이메일", + "password": "비밀번호", + "newPassword": "새 비밀번호 (선택 사항)", + "passwordPlaceholder": "현재 비밀번호를 유지하려면 비워두세요", + "role": "역할", + "roleUser": "사용자", + "roleAdmin": "관리자", + "create": "생성", + "save": "저장" + }, + "status": { + "title": "상태 변경 확인", + "confirmation": "{{firstName}} {{lastName}} 사용자를 {{action}}하시겠습니까?", + "activate": "활성화", + "deactivate": "비활성화", + "user": "사용자" + }, + "header": { + "title": "사용자 관리", + "addUser": "사용자 추가", + "management": "사용자 관리" + }, + "table": { + "user": "사용자", + "email": "이메일", + "status": "상태", + "role": "역할", + "actions": "작업", + "active": "활성", + "inactive": "비활성", + "admin": "관리자", + "userr": "사용자" + } + }, + "logo": { + "labels": { + "appLogo": "애플리케이션 로고" + }, + "buttons": { + "upload": "로고 업로드", + "remove": "로고 삭제" + }, + "messages": { + "uploadSuccess": "로고가 성공적으로 업로드되었습니다", + "removeSuccess": "로고가 성공적으로 삭제되었습니다" + }, + "errors": { + "uploadFailed": "로고 업로드에 실패했습니다", + "removeFailed": "로고 삭제에 실패했습니다" + } + }, + "navbar": { + "logoAlt": "애플리케이션 로고", + "profileMenu": "프로필 메뉴", + "profile": "프로필", + "settings": "설정", + "usersManagement": "사용자 관리", + "logout": "로그아웃" + } +} \ No newline at end of file diff --git a/apps/app/messages/pt-BR.json b/apps/app/messages/pt-BR.json new file mode 100644 index 0000000..e491ecd --- /dev/null +++ b/apps/app/messages/pt-BR.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "Bem-vindo ao", + "signInToContinue": "Entre para continuar", + "emailLabel": "Endereço de E-mail", + "emailPlaceholder": "Digite seu e-mail", + "passwordLabel": "Senha", + "passwordPlaceholder": "Digite sua senha", + "signIn": "Entrar", + "signingIn": "Entrando...", + "forgotPassword": "Esqueceu a senha?", + "pageTitle": "Entrar" + }, + "errors": { + "invalidCredentials": "E-mail ou senha inválidos", + "userNotFound": "Usuário não encontrado", + "accountLocked": "Conta bloqueada. Tente novamente mais tarde", + "unexpectedError": "Ocorreu um erro inesperado. Por favor, tente novamente" + }, + "validation": { + "invalidEmail": "Endereço de email inválido", + "passwordMinLength": "A senha deve ter pelo menos 6 caracteres", + "firstNameRequired": "Nome é obrigatório", + "lastNameRequired": "Sobrenome é obrigatório", + "usernameLength": "Nome de usuário deve ter pelo menos 3 caracteres", + "usernameSpaces": "Nome de usuário não pode conter espaços", + "passwordLength": "A senha deve ter pelo menos 8 caracteres", + "passwordsMatch": "As senhas não coincidem", + "emailRequired": "Email é obrigatório", + "passwordRequired": "Senha é obrigatória" + }, + "fileSelector": { + "availableFiles": "Arquivos Disponíveis ({{count}})", + "shareFiles": "Arquivos Compartilhados ({{count}})", + "searchPlaceholder": "Buscar arquivos...", + "noMatchingFiles": "Nenhum arquivo encontrado", + "noAvailableFiles": "Nenhum arquivo disponível", + "noFilesInShare": "Nenhum arquivo compartilhado", + "saveChanges": "Salvar Alterações" + }, + "recipientSelector": { + "emailPlaceholder": "Digite o e-mail do destinatário", + "add": "Adicionar", + "recipients": "Destinatários ({{count}})", + "notifyAll": "Notificar Todos", + "noRecipients": "Nenhum destinatário adicionado", + "addSuccess": "Destinatário adicionado com sucesso", + "addError": "Falha ao adicionar destinatário", + "removeSuccess": "Destinatário removido com sucesso", + "removeError": "Falha ao remover destinatário", + "sendingNotifications": "Enviando notificações...", + "notifySuccess": "Destinatários notificados com sucesso", + "notifyError": "Falha ao notificar destinatários" + }, + "navigation": { + "dashboard": "Painel" + }, + "common": { + "loading": "Carregando, aguarde...", + "cancel": "Cancelar", + "save": "Salvar", + "delete": "Excluir", + "close": "Fechar", + "download": "Baixar", + "unexpectedError": "Ocorreu um erro inesperado. Por favor, tente novamente.", + "yes": "Sim", + "no": "Não", + "dashboard": "Painel" + }, + "createShare": { + "title": "Criar Compartilhamento", + "nameLabel": "Nome do Compartilhamento", + "expirationLabel": "Data de Expiração", + "expirationPlaceholder": "DD/MM/AAAA HH:MM", + "maxViewsLabel": "Máximo de Visualizações", + "maxViewsPlaceholder": "Deixe vazio para ilimitado", + "passwordProtection": "Protegido por Senha", + "passwordLabel": "Senha", + "create": "Criar Compartilhamento", + "success": "Compartilhamento criado com sucesso", + "error": "Falha ao criar compartilhamento" + }, + "fileActions": { + "editFile": "Editar Arquivo", + "nameLabel": "Nome", + "namePlaceholder": "Digite o novo nome", + "extension": "Extensão", + "descriptionLabel": "Descrição", + "descriptionPlaceholder": "Digite a descrição do arquivo", + "deleteFile": "Excluir Arquivo", + "deleteConfirmation": "Tem certeza que deseja excluir \"{{fileName}}\"?", + "deleteWarning": "Esta ação não pode ser desfeita." + }, + "filePreview": { + "loading": "Carregando visualização...", + "notAvailable": "Visualização não disponível", + "downloadToView": "Faça o download para visualizar o conteúdo", + "audioNotSupported": "Seu navegador não suporta o elemento de áudio", + "videoNotSupported": "Seu navegador não suporta o elemento de vídeo", + "loadError": "Falha ao carregar a visualização", + "downloadError": "Falha ao baixar o arquivo" + }, + "generateShareLink": { + "generateTitle": "Gerar Link de Compartilhamento", + "updateTitle": "Atualizar Link de Compartilhamento", + "generateDescription": "Gere um link para compartilhar seus arquivos", + "updateDescription": "Atualize o alias deste link de compartilhamento", + "aliasPlaceholder": "Digite o alias", + "linkReady": "Seu link de compartilhamento está pronto:", + "generateButton": "Gerar Link", + "updateButton": "Atualizar Link", + "copyButton": "Copiar Link", + "success": "Link gerado com sucesso", + "error": "Erro ao gerar link", + "copied": "Link copiado para a área de transferência" + }, + "shareActions": { + "deleteTitle": "Excluir Compartilhamento", + "deleteConfirmation": "Tem certeza que deseja excluir este compartilhamento? Esta ação não pode ser desfeita.", + "editTitle": "Editar Compartilhamento", + "nameLabel": "Nome do Compartilhamento", + "expirationLabel": "Data de Expiração", + "expirationPlaceholder": "DD/MM/AAAA HH:MM", + "maxViewsLabel": "Máximo de Visualizações", + "maxViewsPlaceholder": "Deixe vazio para ilimitado", + "passwordProtection": "Protegido por Senha", + "passwordLabel": "Senha", + "passwordPlaceholder": "Digite a senha", + "newPasswordLabel": "Nova Senha (deixe vazio para manter a atual)", + "newPasswordPlaceholder": "Digite a nova senha", + "manageFilesTitle": "Gerenciar Arquivos", + "manageRecipientsTitle": "Gerenciar Destinatários", + "editSuccess": "Compartilhamento atualizado com sucesso", + "editError": "Falha ao atualizar compartilhamento" + }, + "shareDetails": { + "title": "Detalhes do Compartilhamento", + "subtitle": "Informações detalhadas sobre este compartilhamento", + "basicInfo": "Informações Básicas", + "name": "Nome", + "untitled": "Compartilhamento sem título", + "views": "Visualizações", + "dates": "Datas", + "created": "Criado em: {{date}}", + "expires": "Expira em: {{date}}", + "never": "Nunca", + "security": "Segurança", + "passwordProtected": "Protegido por Senha", + "publicAccess": "Acesso Público", + "maxViews": "Máximo de Visualizações: {{count}}", + "files": "Arquivos ({{count}})", + "recipients": "Destinatários ({{count}})", + "notAvailable": "N/A", + "invalidDate": "Data inválida", + "loadError": "Falha ao carregar detalhes do compartilhamento" + }, + "uploadFile": { + "title": "Enviar Arquivo", + "selectFile": "Clique para selecionar um arquivo", + "preview": "Pré-visualização", + "uploadProgress": "Progresso do upload", + "upload": "Enviar", + "success": "Arquivo enviado com sucesso", + "error": "Falha ao enviar arquivo" + }, + "filesTable": { + "ariaLabel": "Tabela de arquivos", + "columns": { + "name": "NOME", + "description": "DESCRIÇÃO", + "size": "TAMANHO", + "createdAt": "CRIADO EM", + "updatedAt": "ATUALIZADO EM", + "actions": "AÇÕES" + }, + "actions": { + "menu": "Menu de ações do arquivo", + "preview": "Visualizar", + "edit": "Editar", + "download": "Baixar", + "delete": "Excluir" + } + }, + "sharesTable": { + "ariaLabel": "Tabela de compartilhamentos", + "never": "Nunca", + "columns": { + "name": "NOME", + "createdAt": "CRIADO EM", + "expiresAt": "EXPIRA EM", + "status": "STATUS", + "security": "SEGURANÇA", + "files": "ARQUIVOS", + "recipients": "DESTINATÁRIOS", + "actions": "AÇÕES" + }, + "status": { + "neverExpires": "Nunca Expira", + "active": "Ativo", + "expired": "Expirado" + }, + "security": { + "protected": "Protegido", + "public": "Público" + }, + "filesCount": "{{count}} arquivos", + "recipientsCount": "{{count}} destinatários", + "actions": { + "menu": "Menu de ações do compartilhamento", + "edit": "Editar", + "manageFiles": "Gerenciar Arquivos", + "manageRecipients": "Gerenciar Destinatários", + "viewDetails": "Ver Detalhes", + "generateLink": "Gerar Link", + "editLink": "Editar Link", + "copyLink": "Copiar Link", + "notifyRecipients": "Notificar Destinatários", + "delete": "Excluir" + } + }, + "footer": { + "poweredBy": "Desenvolvido por", + "kyanHomepage": "Página inicial da Kyantech" + }, + "fileManager": { + "downloadError": "Falha ao baixar arquivo", + "updateSuccess": "Arquivo atualizado com sucesso", + "updateError": "Falha ao atualizar arquivo", + "deleteSuccess": "Arquivo excluído com sucesso", + "deleteError": "Falha ao excluir arquivo" + }, + "shareManager": { + "deleteSuccess": "Compartilhamento excluído com sucesso", + "deleteError": "Falha ao excluir compartilhamento", + "updateSuccess": "Compartilhamento atualizado com sucesso", + "updateError": "Falha ao atualizar compartilhamento", + "filesUpdateSuccess": "Arquivos atualizados com sucesso", + "filesUpdateError": "Falha ao atualizar arquivos", + "recipientsUpdateSuccess": "Destinatários atualizados com sucesso", + "recipientsUpdateError": "Falha ao atualizar destinatários", + "linkGenerateSuccess": "Link de compartilhamento gerado com sucesso", + "linkGenerateError": "Falha ao gerar link de compartilhamento", + "notifyLoading": "Enviando notificações...", + "notifySuccess": "Destinatários notificados com sucesso", + "notifyError": "Falha ao notificar destinatários" + }, + "quickAccess": { + "files": { + "title": "Meus Arquivos", + "description": "Acesse e gerencie seus arquivos enviados" + }, + "shares": { + "title": "Meus Compartilhamentos", + "description": "Visualize e gerencie seus arquivos compartilhados" + } + }, + "recentFiles": { + "title": "Uploads Recentes", + "viewAll": "Ver Todos", + "uploadFile": "Enviar Arquivo", + "noFiles": "Nenhum arquivo enviado ainda" + }, + "recentShares": { + "title": "Compartilhamentos Recentes", + "viewAll": "Ver Todos", + "createShare": "Criar Compartilhamento", + "noShares": "Nenhum compartilhamento criado ainda", + "createFirst": "Criar seu primeiro compartilhamento" + }, + "storageUsage": { + "title": "Uso de Armazenamento", + "ariaLabel": "Barra de progresso do uso de armazenamento", + "used": "{{size}} usado", + "available": "{{size}} disponível" + }, + "dashboard": { + "loadError": "Falha ao carregar dados do painel", + "linkCopied": "Link copiado para a área de transferência", + "pageTitle": "Painel", + "breadcrumb": "Painel" + }, + "emptyState": { + "noFiles": "Nenhum arquivo enviado ainda", + "uploadFile": "Enviar Arquivo" + }, + "files": { + "title": "Todos os Arquivos", + "uploadFile": "Enviar Arquivo", + "loadError": "Falha ao carregar arquivos", + "pageTitle": "Meus Arquivos", + "breadcrumb": "Meus Arquivos" + }, + "searchBar": { + "placeholder": "Buscar arquivos...", + "results": "Encontrados {{filtered}} de {{total}} arquivos" + }, + "forgotPassword": { + "emailLabel": "Endereço de Email", + "emailPlaceholder": "Digite seu email", + "sending": "Enviando...", + "submit": "Enviar Instruções de Redefinição", + "backToLogin": "Voltar ao Login", + "title": "Esqueceu a Senha", + "description": "Digite seu endereço de email e enviaremos instruções para redefinir sua senha.", + "resetInstructions": "Instruções de redefinição enviadas para seu email", + "pageTitle": "Esqueceu a Senha" + }, + "home": { + "description": "A alternativa open-source ao WeTransfer. Compartilhe arquivos com segurança, sem rastreamento ou limitações.", + "documentation": "Documentação", + "starOnGithub": "Estrela no GitHub", + "privacyMessage": "Construído com privacidade em mente. Seus arquivos antes do upload são acessíveis apenas por aqueles com o link de compartilhamento. Para sempre gratuito e open source.", + "header": { + "fileSharing": "Compartilhamento de arquivos", + "tagline": "simples e gratuito" + }, + "pageTitle": "Início" + }, + "profile": { + "password": { + "title": "Alterar Senha", + "newPassword": "Nova Senha", + "confirmPassword": "Confirmar Nova Senha", + "updateButton": "Atualizar Senha" + }, + "form": { + "title": "Informações do Perfil", + "firstName": "Nome", + "lastName": "Sobrenome", + "username": "Nome de Usuário", + "email": "Email", + "updateButton": "Atualizar Perfil" + }, + "header": { + "title": "Perfil", + "subtitle": "Gerencie suas informações pessoais e senha" + }, + "picture": { + "title": "Foto do Perfil", + "description": "Clique no ícone da câmera para alterar sua foto de perfil", + "uploadPhoto": "Enviar Foto", + "removePhoto": "Remover Foto" + }, + "errors": { + "loadFailed": "Falha ao carregar dados do usuário", + "updateFailed": "Falha ao atualizar perfil", + "passwordFailed": "Falha ao atualizar senha", + "imageFailed": "Falha ao atualizar imagem", + "imageRemoveFailed": "Falha ao remover imagem" + }, + "messages": { + "noChanges": "Nenhuma alteração para salvar", + "updateSuccess": "Perfil atualizado com sucesso", + "fillPasswords": "Por favor, preencha ambos os campos de senha", + "passwordSuccess": "Senha atualizada com sucesso", + "imageSuccess": "Imagem de perfil atualizada com sucesso", + "imageRemoved": "Imagem de perfil removida com sucesso" + }, + "pageTitle": "Perfil" + }, + "resetPassword": { + "pageTitle": "Redefinir Senha", + "header": { + "title": "Redefinir Senha", + "description": "Digite sua nova senha abaixo" + }, + "form": { + "newPassword": "Nova Senha", + "newPasswordPlaceholder": "Digite sua nova senha", + "confirmPassword": "Confirmar Nova Senha", + "confirmPasswordPlaceholder": "Confirme sua nova senha", + "resetting": "Redefinindo Senha...", + "submit": "Redefinir Senha", + "backToLogin": "Voltar ao Login" + }, + "messages": { + "success": "Senha redefinida com sucesso" + }, + "errors": { + "serverError": "Falha ao redefinir senha. Tente novamente.", + "invalidToken": "Token de redefinição inválido ou ausente" + } + }, + "settings": { + "groups": { + "defaultDescription": "Opções de configuração", + "general": { + "title": "Geral", + "description": "Configurações básicas da aplicação" + }, + "email": { + "title": "Email", + "description": "Configuração do servidor de email" + }, + "security": { + "title": "Segurança", + "description": "Configurações de segurança e autenticação" + }, + "storage": { + "title": "Armazenamento", + "description": "Configuração de armazenamento de arquivos" + } + }, + "fields": { + "noDescription": "Sem descrição disponível", + "appLogo": { + "title": "Logo do Aplicativo", + "description": "Imagem do logo do aplicativo" + }, + "appName": { + "title": "Nome do Aplicativo", + "description": "Nome do aplicativo exibido para os usuários" + }, + "appDescription": { + "title": "Descrição do Aplicativo", + "description": "Descrição breve do aplicativo" + }, + "showHomePage": { + "title": "Exibir Página Inicial", + "description": "Exibe a página inicial após a instalação" + }, + "smtpEnabled": { + "title": "SMTP Habilitado", + "description": "Ativa ou desativa a funcionalidade de e-mail via SMTP" + }, + "smtpHost": { + "title": "Servidor SMTP", + "description": "Endereço do servidor SMTP" + }, + "smtpPort": { + "title": "Porta SMTP", + "description": "Porta do servidor SMTP" + }, + "smtpUser": { + "title": "Usuário SMTP", + "description": "Nome de usuário para autenticação SMTP" + }, + "smtpPass": { + "title": "Senha SMTP", + "description": "Senha para autenticação SMTP" + }, + "smtpFromName": { + "title": "Nome do Remetente", + "description": "Nome exibido para os e-mails enviados" + }, + "smtpFromEmail": { + "title": "E-mail do Remetente", + "description": "Endereço de e-mail do remetente" + }, + "maxLoginAttempts": { + "title": "Número Máximo de Tentativas de Login", + "description": "Número máximo de tentativas de login antes de bloquear" + }, + "loginBlockDuration": { + "title": "Duração do Bloqueio", + "description": "Duração (em segundos) do bloqueio após exceder o número de tentativas" + }, + "passwordMinLength": { + "title": "Comprimento Mínimo da Senha", + "description": "Número mínimo de caracteres para senhas" + }, + "passwordResetTokenExpiration": { + "title": "Expiração do Token de Redefinição", + "description": "Tempo de validade (em segundos) para o token de redefinição de senha" + }, + "maxFileSize": { + "title": "Tamanho Máximo do Arquivo", + "description": "Tamanho máximo permitido para uploads (em bytes)" + }, + "maxTotalStoragePerUser": { + "title": "Armazenamento Máximo por Usuário", + "description": "Limite total de armazenamento por usuário (em bytes)" + } + }, + "buttons": { + "save": "Salvar {{group}}" + }, + "errors": { + "loadFailed": "Falha ao carregar configurações", + "updateFailed": "Falha ao atualizar configurações" + }, + "messages": { + "noChanges": "Nenhuma alteração para salvar", + "updateSuccess": "Configurações de {{group}} atualizadas com sucesso" + }, + "title": "Configurações", + "breadcrumb": "Configurações", + "pageTitle": "Configurações" + }, + "share": { + "errors": { + "invalidPassword": "Senha inválida. Por favor, tente novamente.", + "loadFailed": "Falha ao carregar compartilhamento", + "downloadFailed": "Falha ao baixar arquivo" + }, + "messages": { + "downloadStarted": "Download iniciado", + "password": { + "title": "Compartilhamento Protegido por Senha", + "protected": "Este compartilhamento está protegido por senha", + "incorrect": "Senha incorreta. Por favor, tente novamente.", + "label": "Senha", + "placeholder": "Digite a senha do compartilhamento", + "submit": "Enviar" + }, + "details": { + "untitled": "Compartilhamento sem título", + "created": "Criado em: {{date}}", + "expires": "Expira em: {{date}}" + }, + "notFound": { + "title": "Compartilhamento não Encontrado", + "description": "Este compartilhamento pode ter sido excluído ou expirado." + } + }, + "pageTitle": "Compartilhamento" + }, + "shares": { + "errors": { + "loadFailed": "Falha ao carregar compartilhamentos", + "notifyFailed": "Falha ao notificar destinatários", + "smtpConfigFailed": "Falha ao carregar configuração SMTP" + }, + "messages": { + "linkCopied": "Link copiado para a área de transferência", + "recipientsNotified": "Destinatários notificados com sucesso" + }, + "empty": { + "message": "Nenhum compartilhamento criado ainda", + "createButton": "Criar Compartilhamento" + }, + "header": { + "title": "Meus Compartilhamentos", + "myShares": "Meus Compartilhamentos" + }, + "search": { + "title": "Todos os Compartilhamentos", + "createButton": "Criar Compartilhamento", + "placeholder": "Buscar compartilhamentos...", + "results": "Encontrados {{filtered}} de {{total}} compartilhamentos" + }, + "pageTitle": "Compartilhamentos" + }, + "users": { + "modes": { + "create": "criar", + "edit": "editar" + }, + "errors": { + "loadFailed": "Falha ao carregar usuários", + "submitFailed": "Falha ao {{mode}} usuário", + "deleteFailed": "Falha ao excluir usuário", + "statusUpdateFailed": "Falha ao atualizar status do usuário" + }, + "messages": { + "createSuccess": "Usuário criado com sucesso", + "updateSuccess": "Usuário atualizado com sucesso", + "deleteSuccess": "Usuário excluído com sucesso", + "activateSuccess": "Usuário ativado com sucesso", + "deactivateSuccess": "Usuário desativado com sucesso" + }, + "actions": { + "edit": "Editar", + "activate": "Ativar", + "deactivate": "Desativar", + "delete": "Excluir" + }, + "delete": { + "title": "Confirmar Exclusão de Usuário", + "confirmation": "Tem certeza que deseja excluir o usuário {{firstName}} {{lastName}}? Esta ação não pode ser desfeita.", + "confirm": "Excluir Usuário" + }, + "form": { + "titleCreate": "Adicionar Novo Usuário", + "titleEdit": "Editar Usuário", + "firstName": "Nome", + "lastName": "Sobrenome", + "username": "Nome de Usuário", + "email": "Email", + "password": "Senha", + "newPassword": "Nova Senha (opcional)", + "passwordPlaceholder": "Deixe em branco para manter a senha atual", + "role": "Função", + "roleUser": "Usuário", + "roleAdmin": "Administrador", + "create": "Criar", + "save": "Salvar" + }, + "status": { + "title": "Confirmar Alteração de Status", + "confirmation": "Tem certeza que deseja {{action}} o usuário {{firstName}} {{lastName}}?", + "activate": "ativar", + "deactivate": "desativar", + "user": "Usuário" + }, + "header": { + "title": "Gerenciamento de Usuários", + "addUser": "Adicionar Usuário", + "management": "Gerenciamento de Usuários" + }, + "table": { + "user": "USUÁRIO", + "email": "EMAIL", + "status": "STATUS", + "role": "FUNÇÃO", + "actions": "AÇÕES", + "active": "Ativo", + "inactive": "Inativo", + "admin": "Admin", + "userr": "Usuário" + } + }, + "logo": { + "labels": { + "appLogo": "Logo do Aplicativo" + }, + "buttons": { + "upload": "Enviar Logo", + "remove": "Remover Logo" + }, + "messages": { + "uploadSuccess": "Logo enviado com sucesso", + "removeSuccess": "Logo removido com sucesso" + }, + "errors": { + "uploadFailed": "Falha ao enviar logo", + "removeFailed": "Falha ao remover logo" + } + }, + "navbar": { + "logoAlt": "Logo do Aplicativo", + "profileMenu": "Menu do Perfil", + "profile": "Perfil", + "settings": "Configurações", + "usersManagement": "Gerenciar Usuários", + "logout": "Sair" + } +} \ No newline at end of file diff --git a/apps/app/messages/ru-RU.json b/apps/app/messages/ru-RU.json new file mode 100644 index 0000000..00895d9 --- /dev/null +++ b/apps/app/messages/ru-RU.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "Добро пожаловать в", + "signInToContinue": "Войдите, чтобы продолжить", + "emailLabel": "Адрес электронной почты", + "emailPlaceholder": "Введите вашу электронную почту", + "passwordLabel": "Пароль", + "passwordPlaceholder": "Введите ваш пароль", + "signIn": "Войти", + "signingIn": "Вход...", + "forgotPassword": "Забыли пароль?", + "pageTitle": "Вход" + }, + "errors": { + "invalidCredentials": "Неверный адрес электронной почты или пароль", + "userNotFound": "Пользователь не найден", + "accountLocked": "Аккаунт заблокирован. Пожалуйста, попробуйте позже", + "unexpectedError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз" + }, + "validation": { + "invalidEmail": "Неверный адрес электронной почты", + "passwordMinLength": "Пароль должен содержать не менее 6 символов", + "firstNameRequired": "Имя обязательно", + "lastNameRequired": "Фамилия обязательна", + "usernameLength": "Имя пользователя должно содержать не менее 3 символов", + "usernameSpaces": "Имя пользователя не может содержать пробелов", + "passwordLength": "Пароль должен содержать не менее 8 символов", + "passwordsMatch": "Пароли не совпадают", + "emailRequired": "Требуется электронная почта", + "passwordRequired": "Требуется пароль" + }, + "fileSelector": { + "availableFiles": "Доступные файлы ({{count}})", + "shareFiles": "Поделиться файлами ({{count}})", + "searchPlaceholder": "Поиск файлов...", + "noMatchingFiles": "Нет файлов, соответствующих запросу", + "noAvailableFiles": "Нет доступных файлов", + "noFilesInShare": "Нет файлов для совместного использования", + "saveChanges": "Сохранить изменения" + }, + "recipientSelector": { + "emailPlaceholder": "Введите электронную почту получателя", + "add": "Добавить", + "recipients": "Получатели ({{count}})", + "notifyAll": "Уведомить всех", + "noRecipients": "Пока нет добавленных получателей", + "addSuccess": "Получатель успешно добавлен", + "addError": "Не удалось добавить получателя", + "removeSuccess": "Получатель успешно удалён", + "removeError": "Не удалось удалить получателя", + "sendingNotifications": "Отправка уведомлений...", + "notifySuccess": "Получатели успешно уведомлены", + "notifyError": "Не удалось уведомить получателей" + }, + "navigation": { + "dashboard": "Панель управления" + }, + "common": { + "loading": "Загрузка, пожалуйста, подождите...", + "cancel": "Отмена", + "save": "Сохранить", + "delete": "Удалить", + "close": "Закрыть", + "download": "Скачать", + "unexpectedError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз.", + "yes": "Да", + "no": "Нет", + "dashboard": "Панель управления" + }, + "createShare": { + "title": "Создать общий доступ", + "nameLabel": "Название общего доступа", + "expirationLabel": "Дата истечения", + "expirationPlaceholder": "MM/DD/YYYY ЧЧ:ММ", + "maxViewsLabel": "Максимальное количество просмотров", + "maxViewsPlaceholder": "Оставьте пустым для неограниченного доступа", + "passwordProtection": "Защита паролем", + "passwordLabel": "Пароль", + "create": "Создать общий доступ", + "success": "Общий доступ успешно создан", + "error": "Не удалось создать общий доступ" + }, + "fileActions": { + "editFile": "Редактировать файл", + "nameLabel": "Имя", + "namePlaceholder": "Введите новое имя", + "extension": "Расширение", + "descriptionLabel": "Описание", + "descriptionPlaceholder": "Введите описание файла", + "deleteFile": "Удалить файл", + "deleteConfirmation": "Вы уверены, что хотите удалить \"{{fileName}}\"?", + "deleteWarning": "Это действие необратимо." + }, + "filePreview": { + "loading": "Загрузка предпросмотра...", + "notAvailable": "Предпросмотр недоступен", + "downloadToView": "Скачайте файл для просмотра содержимого", + "audioNotSupported": "Ваш браузер не поддерживает аудиоэлемент", + "videoNotSupported": "Ваш браузер не поддерживает видеоэлемент", + "loadError": "Ошибка загрузки предпросмотра", + "downloadError": "Ошибка скачивания файла" + }, + "generateShareLink": { + "generateTitle": "Создать ссылку для общего доступа", + "updateTitle": "Обновить ссылку для общего доступа", + "generateDescription": "Создайте ссылку для обмена файлами", + "updateDescription": "Обновите псевдоним для этой ссылки", + "aliasPlaceholder": "Введите псевдоним", + "linkReady": "Ваша ссылка готова:", + "generateButton": "Создать ссылку", + "updateButton": "Обновить ссылку", + "copyButton": "Скопировать ссылку", + "success": "Ссылка успешно создана", + "error": "Не удалось создать ссылку", + "copied": "Ссылка скопирована в буфер обмена" + }, + "shareActions": { + "deleteTitle": "Удалить общий доступ", + "deleteConfirmation": "Вы уверены, что хотите удалить этот общий доступ? Это действие необратимо.", + "editTitle": "Редактировать общий доступ", + "nameLabel": "Название общего доступа", + "expirationLabel": "Дата истечения", + "expirationPlaceholder": "MM/DD/YYYY ЧЧ:ММ", + "maxViewsLabel": "Максимальное количество просмотров", + "maxViewsPlaceholder": "Оставьте пустым для неограниченного доступа", + "passwordProtection": "Защищено паролем", + "passwordLabel": "Пароль", + "passwordPlaceholder": "Введите пароль", + "newPasswordLabel": "Новый пароль (оставьте пустым, чтобы сохранить текущий)", + "newPasswordPlaceholder": "Введите новый пароль", + "manageFilesTitle": "Управление файлами", + "manageRecipientsTitle": "Управление получателями", + "editSuccess": "Общий доступ успешно обновлён", + "editError": "Ошибка при обновлении общего доступа" + }, + "shareDetails": { + "title": "Детали общего доступа", + "subtitle": "Подробная информация об этом общем доступе", + "basicInfo": "Основная информация", + "name": "Название", + "untitled": "Без названия", + "views": "Просмотры", + "dates": "Даты", + "created": "Создано", + "expires": "Истекает", + "never": "Никогда", + "security": "Безопасность", + "passwordProtected": "Защищено паролем", + "publicAccess": "Публичный доступ", + "maxViews": "Максимум просмотров: {{count}}", + "files": "Файлы ({{count}})", + "recipients": "Получатели ({{count}})", + "notAvailable": "Н/Д", + "invalidDate": "Неверная дата", + "loadError": "Ошибка загрузки деталей общего доступа" + }, + "uploadFile": { + "title": "Загрузить файл", + "selectFile": "Нажмите, чтобы выбрать файл", + "preview": "Предпросмотр", + "uploadProgress": "Прогресс загрузки", + "upload": "Загрузить", + "success": "Файл успешно загружен", + "error": "Не удалось загрузить файл" + }, + "filesTable": { + "ariaLabel": "Таблица файлов", + "columns": { + "name": "ИМЯ", + "description": "ОПИСАНИЕ", + "size": "РАЗМЕР", + "createdAt": "СОЗДАНО", + "updatedAt": "ОБНОВЛЕНО", + "actions": "ДЕЙСТВИЯ" + }, + "actions": { + "menu": "Меню действий с файлом", + "preview": "Предпросмотр", + "edit": "Редактировать", + "download": "Скачать", + "delete": "Удалить" + } + }, + "sharesTable": { + "ariaLabel": "Таблица общего доступа", + "never": "Никогда", + "columns": { + "name": "ИМЯ", + "createdAt": "СОЗДАНО", + "expiresAt": "ИСТЕКАЕТ", + "status": "СТАТУС", + "security": "БЕЗОПАСНОСТЬ", + "files": "ФАЙЛЫ", + "recipients": "ПОЛУЧАТЕЛИ", + "actions": "ДЕЙСТВИЯ" + }, + "status": { + "neverExpires": "Не истекает", + "active": "Активно", + "expired": "Истекло" + }, + "security": { + "protected": "Защищено", + "public": "Публично" + }, + "filesCount": "{{count}} файлов", + "recipientsCount": "{{count}} получателей", + "actions": { + "menu": "Меню действий общего доступа", + "edit": "Редактировать", + "manageFiles": "Управление файлами", + "manageRecipients": "Управление получателями", + "viewDetails": "Просмотреть детали", + "generateLink": "Создать ссылку", + "editLink": "Редактировать ссылку", + "copyLink": "Скопировать ссылку", + "notifyRecipients": "Уведомить получателей", + "delete": "Удалить" + } + }, + "footer": { + "poweredBy": "При поддержке", + "kyanHomepage": "Домашняя страница Kyantech" + }, + "fileManager": { + "downloadError": "Ошибка скачивания файла", + "updateSuccess": "Файл успешно обновлен", + "updateError": "Ошибка при обновлении файла", + "deleteSuccess": "Файл успешно удален", + "deleteError": "Ошибка при удалении файла" + }, + "shareManager": { + "deleteSuccess": "Общий доступ успешно удален", + "deleteError": "Ошибка при удалении общего доступа", + "updateSuccess": "Общий доступ успешно обновлен", + "updateError": "Ошибка при обновлении общего доступа", + "filesUpdateSuccess": "Файлы успешно обновлены", + "filesUpdateError": "Ошибка при обновлении файлов", + "recipientsUpdateSuccess": "Получатели успешно обновлены", + "recipientsUpdateError": "Ошибка при обновлении получателей", + "linkGenerateSuccess": "Ссылка для общего доступа успешно создана", + "linkGenerateError": "Ошибка при создании ссылки для общего доступа", + "notifyLoading": "Отправка уведомлений...", + "notifySuccess": "Получатели успешно уведомлены", + "notifyError": "Ошибка при уведомлении получателей" + }, + "quickAccess": { + "files": { + "title": "Мои файлы", + "description": "Доступ и управление загруженными файлами" + }, + "shares": { + "title": "Мои общие доступы", + "description": "Просмотр и управление файлами для совместного использования" + } + }, + "recentFiles": { + "title": "Последние загрузки", + "viewAll": "Показать все", + "uploadFile": "Загрузить файл", + "noFiles": "Файлы еще не загружены" + }, + "recentShares": { + "title": "Последние общие доступы", + "viewAll": "Показать все", + "createShare": "Создать общий доступ", + "noShares": "Общие доступы еще не созданы", + "createFirst": "Создайте ваш первый общий доступ" + }, + "storageUsage": { + "title": "Использование хранилища", + "ariaLabel": "Индикатор использования хранилища", + "used": "Использовано: {{size}}", + "available": "Доступно: {{size}}" + }, + "dashboard": { + "loadError": "Ошибка загрузки данных панели управления", + "linkCopied": "Ссылка скопирована в буфер обмена", + "pageTitle": "Панель управления", + "breadcrumb": "Панель управления" + }, + "emptyState": { + "noFiles": "Файлы еще не загружены", + "uploadFile": "Загрузить файл" + }, + "files": { + "title": "Все файлы", + "uploadFile": "Загрузить файл", + "loadError": "Ошибка загрузки файлов", + "pageTitle": "Мои файлы", + "breadcrumb": "Мои файлы" + }, + "searchBar": { + "placeholder": "Поиск файлов...", + "results": "Найдено {{filtered}} из {{total}} файлов" + }, + "forgotPassword": { + "emailLabel": "Адрес электронной почты", + "emailPlaceholder": "Введите ваш адрес электронной почты", + "sending": "Отправка...", + "submit": "Отправить инструкции по сбросу", + "backToLogin": "Вернуться ко входу", + "title": "Забыли пароль", + "description": "Введите адрес электронной почты, и мы отправим вам инструкции по сбросу пароля.", + "resetInstructions": "Инструкции по сбросу отправлены на вашу электронную почту", + "pageTitle": "Забыли пароль" + }, + "home": { + "description": "Открытая альтернатива WeTransfer. Делитесь файлами безопасно, без отслеживания и ограничений.", + "documentation": "Документация", + "starOnGithub": "Оцените на GitHub", + "privacyMessage": "Создано с учетом конфиденциальности. Ваши файлы до загрузки доступны только тем, у кого есть ссылка для доступа. Всегда бесплатно и с открытым исходным кодом.", + "header": { + "fileSharing": "Обмен файлами", + "tagline": "просто и бесплатно" + }, + "pageTitle": "Главная" + }, + "profile": { + "password": { + "title": "Изменить пароль", + "newPassword": "Новый пароль", + "confirmPassword": "Подтвердите новый пароль", + "updateButton": "Обновить пароль" + }, + "form": { + "title": "Информация профиля", + "firstName": "Имя", + "lastName": "Фамилия", + "username": "Имя пользователя", + "email": "Электронная почта", + "updateButton": "Обновить профиль" + }, + "header": { + "title": "Профиль", + "subtitle": "Управляйте вашей личной информацией и паролем" + }, + "picture": { + "title": "Изображение профиля", + "description": "Нажмите на значок камеры, чтобы изменить изображение профиля", + "uploadPhoto": "Загрузить фото", + "removePhoto": "Удалить фото" + }, + "errors": { + "loadFailed": "Не удалось загрузить данные пользователя", + "updateFailed": "Ошибка при обновлении профиля", + "passwordFailed": "Ошибка при обновлении пароля", + "imageFailed": "Ошибка при обновлении изображения профиля", + "imageRemoveFailed": "Ошибка при удалении изображения профиля" + }, + "messages": { + "noChanges": "Изменений для сохранения нет", + "updateSuccess": "Профиль успешно обновлен", + "fillPasswords": "Пожалуйста, заполните оба поля пароля", + "passwordSuccess": "Пароль успешно обновлен", + "imageSuccess": "Изображение профиля успешно обновлено", + "imageRemoved": "Изображение профиля успешно удалено" + }, + "pageTitle": "Профиль" + }, + "resetPassword": { + "pageTitle": "Сбросить пароль", + "header": { + "title": "Сбросить пароль", + "description": "Введите ваш новый пароль ниже" + }, + "form": { + "newPassword": "Новый пароль", + "newPasswordPlaceholder": "Введите новый пароль", + "confirmPassword": "Подтвердите новый пароль", + "confirmPasswordPlaceholder": "Подтвердите новый пароль", + "resetting": "Сброс пароля...", + "submit": "Сбросить пароль", + "backToLogin": "Вернуться ко входу" + }, + "messages": { + "success": "Пароль успешно сброшен" + }, + "errors": { + "serverError": "Не удалось сбросить пароль. Пожалуйста, попробуйте еще раз.", + "invalidToken": "Неверный или отсутствующий токен сброса" + } + }, + "settings": { + "groups": { + "defaultDescription": "Настройки конфигурации", + "general": { + "title": "Общие", + "description": "Основные настройки приложения" + }, + "email": { + "title": "Электронная почта", + "description": "Настройки почтового сервера" + }, + "security": { + "title": "Безопасность", + "description": "Настройки безопасности и аутентификации" + }, + "storage": { + "title": "Хранилище", + "description": "Настройки хранения файлов" + } + }, + "fields": { + "noDescription": "Описание отсутствует", + "appLogo": { + "title": "Логотип приложения", + "description": "Изображение логотипа приложения" + }, + "appName": { + "title": "Название приложения", + "description": "Название приложения, отображаемое пользователям" + }, + "appDescription": { + "title": "Описание приложения", + "description": "Краткое описание приложения" + }, + "showHomePage": { + "title": "Показывать главную страницу", + "description": "Показывать главную страницу после установки" + }, + "smtpEnabled": { + "title": "Включить SMTP", + "description": "Включить или отключить функцию SMTP для отправки электронной почты" + }, + "smtpHost": { + "title": "SMTP-сервер", + "description": "Адрес SMTP-сервера" + }, + "smtpPort": { + "title": "SMTP-порт", + "description": "Порт SMTP-сервера" + }, + "smtpUser": { + "title": "SMTP-пользователь", + "description": "Имя пользователя для SMTP-аутентификации" + }, + "smtpPass": { + "title": "SMTP-пароль", + "description": "Пароль для SMTP-аутентификации" + }, + "smtpFromName": { + "title": "Имя отправителя", + "description": "Имя, отображаемое в отправляемых письмах" + }, + "smtpFromEmail": { + "title": "Электронная почта отправителя", + "description": "Адрес электронной почты отправителя" + }, + "maxLoginAttempts": { + "title": "Максимальное количество попыток входа", + "description": "Максимальное количество попыток входа до блокировки" + }, + "loginBlockDuration": { + "title": "Время блокировки", + "description": "Продолжительность блокировки (в секундах) после превышения лимита попыток" + }, + "passwordMinLength": { + "title": "Минимальная длина пароля", + "description": "Минимальное количество символов в пароле" + }, + "passwordResetTokenExpiration": { + "title": "Время истечения токена сброса пароля", + "description": "Время действия токена сброса пароля (в секундах)" + }, + "maxFileSize": { + "title": "Максимальный размер файла", + "description": "Максимальный размер файла для загрузки (в байтах)" + }, + "maxTotalStoragePerUser": { + "title": "Максимальное хранилище для пользователя", + "description": "Общий лимит хранилища для каждого пользователя (в байтах)" + } + }, + "buttons": { + "save": "Сохранить {{group}}" + }, + "errors": { + "loadFailed": "Ошибка загрузки настроек", + "updateFailed": "Ошибка обновления настроек" + }, + "messages": { + "noChanges": "Изменений для сохранения нет", + "updateSuccess": "Настройки {{group}} успешно обновлены" + }, + "title": "Настройки", + "breadcrumb": "Настройки", + "pageTitle": "Настройки" + }, + "share": { + "errors": { + "invalidPassword": "Неверный пароль. Пожалуйста, попробуйте еще раз.", + "loadFailed": "Ошибка загрузки общего доступа", + "downloadFailed": "Ошибка скачивания файла" + }, + "messages": { + "downloadStarted": "Скачивание начато" + }, + "password": { + "title": "Общий доступ, защищенный паролем", + "protected": "Этот общий доступ защищен паролем", + "incorrect": "Неверный пароль. Пожалуйста, попробуйте снова.", + "label": "Пароль", + "placeholder": "Введите пароль для общего доступа", + "submit": "Отправить" + }, + "details": { + "untitled": "Без названия", + "created": "Создано: {{date}}", + "expires": "Истекает: {{date}}" + }, + "notFound": { + "title": "Общий доступ не найден", + "description": "Этот общий доступ может быть удален или истек." + }, + "pageTitle": "Общий доступ" + }, + "shares": { + "errors": { + "loadFailed": "Ошибка загрузки общих доступов", + "notifyFailed": "Ошибка уведомления получателей", + "smtpConfigFailed": "Ошибка загрузки SMTP-настроек" + }, + "messages": { + "linkCopied": "Ссылка скопирована в буфер обмена", + "recipientsNotified": "Получатели успешно уведомлены" + }, + "empty": { + "message": "Общие доступы еще не созданы", + "createButton": "Создать общий доступ" + }, + "header": { + "title": "Мои общие доступы", + "myShares": "Мои общие доступы" + }, + "search": { + "title": "Все общие доступы", + "createButton": "Создать общий доступ", + "placeholder": "Поиск общих доступов...", + "results": "Найдено {{filtered}} из {{total}} общих доступов" + }, + "pageTitle": "Общие доступы" + }, + "users": { + "modes": { + "create": "создать", + "edit": "редактировать" + }, + "errors": { + "loadFailed": "Ошибка загрузки пользователей", + "submitFailed": "Ошибка при {{mode}} пользователя", + "deleteFailed": "Ошибка при удалении пользователя", + "statusUpdateFailed": "Ошибка обновления статуса пользователя" + }, + "messages": { + "createSuccess": "Пользователь успешно создан", + "updateSuccess": "Пользователь успешно обновлен", + "deleteSuccess": "Пользователь успешно удален", + "activateSuccess": "Пользователь успешно активирован", + "deactivateSuccess": "Пользователь успешно деактивирован" + }, + "actions": { + "edit": "Редактировать", + "activate": "Активировать", + "deactivate": "Деактивировать", + "delete": "Удалить" + }, + "delete": { + "title": "Подтверждение удаления пользователя", + "confirmation": "Вы уверены, что хотите удалить пользователя {{firstName}} {{lastName}}? Это действие нельзя отменить.", + "confirm": "Удалить пользователя" + }, + "form": { + "titleCreate": "Добавить нового пользователя", + "titleEdit": "Редактировать пользователя", + "firstName": "Имя", + "lastName": "Фамилия", + "username": "Имя пользователя", + "email": "Электронная почта", + "password": "Пароль", + "newPassword": "Новый пароль (необязательно)", + "passwordPlaceholder": "Оставьте пустым, чтобы сохранить текущий пароль", + "role": "Роль", + "roleUser": "Пользователь", + "roleAdmin": "Администратор", + "create": "Создать", + "save": "Сохранить" + }, + "status": { + "title": "Подтверждение изменения статуса", + "confirmation": "Вы уверены, что хотите {{action}} пользователя {{firstName}} {{lastName}}?", + "activate": "активировать", + "deactivate": "деактивировать", + "user": "Пользователь" + }, + "header": { + "title": "Управление пользователями", + "addUser": "Добавить пользователя", + "management": "Управление пользователями" + }, + "table": { + "user": "ПОЛЬЗОВАТЕЛЬ", + "email": "ЭЛЕКТРОННАЯ ПОЧТА", + "status": "СТАТУС", + "role": "РОЛЬ", + "actions": "ДЕЙСТВИЯ", + "active": "Активен", + "inactive": "Неактивен", + "admin": "Администратор", + "userr": "Пользователь" + } + }, + "logo": { + "labels": { + "appLogo": "Логотип приложения" + }, + "buttons": { + "upload": "Загрузить логотип", + "remove": "Удалить логотип" + }, + "messages": { + "uploadSuccess": "Логотип успешно загружен", + "removeSuccess": "Логотип успешно удален" + }, + "errors": { + "uploadFailed": "Ошибка загрузки логотипа", + "removeFailed": "Ошибка удаления логотипа" + } + }, + "navbar": { + "logoAlt": "Логотип приложения", + "profileMenu": "Меню профиля", + "profile": "Профиль", + "settings": "Настройки", + "usersManagement": "Управление пользователями", + "logout": "Выйти" + } +} \ No newline at end of file diff --git a/apps/app/messages/tr-TR.json b/apps/app/messages/tr-TR.json new file mode 100644 index 0000000..b4f81aa --- /dev/null +++ b/apps/app/messages/tr-TR.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "Hoş geldiniz'e", + "signInToContinue": "Devam etmek için oturum açın", + "emailLabel": "E-posta Adresi", + "emailPlaceholder": "E-posta adresinizi girin", + "passwordLabel": "Şifre", + "passwordPlaceholder": "Şifrenizi girin", + "signIn": "Oturum Aç", + "signingIn": "Oturum açılıyor...", + "forgotPassword": "Şifrenizi mi unuttunuz?", + "pageTitle": "Giriş" + }, + "errors": { + "invalidCredentials": "Geçersiz e-posta veya şifre", + "userNotFound": "Kullanıcı bulunamadı", + "accountLocked": "Hesap kilitlendi. Lütfen daha sonra tekrar deneyin", + "unexpectedError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin" + }, + "validation": { + "invalidEmail": "Geçersiz e-posta adresi", + "passwordMinLength": "Şifre en az 6 karakter olmalıdır", + "firstNameRequired": "Ad gerekli", + "lastNameRequired": "Soyad gerekli", + "usernameLength": "Kullanıcı adı en az 3 karakter olmalıdır", + "usernameSpaces": "Kullanıcı adında boşluk olamaz", + "passwordLength": "Şifre en az 8 karakter olmalıdır", + "passwordsMatch": "Şifreler eşleşmiyor", + "emailRequired": "E-posta gerekli", + "passwordRequired": "Şifre gerekli" + }, + "fileSelector": { + "availableFiles": "Kullanılabilir Dosyalar ({{count}})", + "shareFiles": "Dosyaları Paylaş ({{count}})", + "searchPlaceholder": "Dosya ara...", + "noMatchingFiles": "Eşleşen dosya bulunamadı", + "noAvailableFiles": "Kullanılabilir dosya yok", + "noFilesInShare": "Paylaşımda dosya yok", + "saveChanges": "Değişiklikleri Kaydet" + }, + "recipientSelector": { + "emailPlaceholder": "Alıcının e-postasını girin", + "add": "Ekle", + "recipients": "Alıcılar ({{count}})", + "notifyAll": "Hepsini Bildir", + "noRecipients": "Henüz alıcı eklenmedi", + "addSuccess": "Alıcı başarıyla eklendi", + "addError": "Alıcı eklenemedi", + "removeSuccess": "Alıcı başarıyla kaldırıldı", + "removeError": "Alıcı kaldırılamadı", + "sendingNotifications": "Bildirimler gönderiliyor...", + "notifySuccess": "Alıcılar başarıyla bildirildi", + "notifyError": "Alıcılara bildirim gönderilemedi" + }, + "navigation": { + "dashboard": "Gösterge Paneli" + }, + "common": { + "loading": "Yükleniyor, lütfen bekleyin...", + "cancel": "İptal", + "save": "Kaydet", + "delete": "Sil", + "close": "Kapat", + "download": "İndir", + "unexpectedError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin.", + "yes": "Evet", + "no": "Hayır", + "dashboard": "Gösterge Paneli" + }, + "createShare": { + "title": "Paylaşım Oluştur", + "nameLabel": "Paylaşım Adı", + "expirationLabel": "Son Kullanma Tarihi", + "expirationPlaceholder": "MM/GG/YYYY SS:DD", + "maxViewsLabel": "Maksimum Görüntüleme", + "maxViewsPlaceholder": "Sınırsız için boş bırakın", + "passwordProtection": "Şifre Koruması", + "passwordLabel": "Şifre", + "create": "Paylaşım Oluştur", + "success": "Paylaşım başarıyla oluşturuldu", + "error": "Paylaşım oluşturulamadı" + }, + "fileActions": { + "editFile": "Dosyayı Düzenle", + "nameLabel": "Ad", + "namePlaceholder": "Yeni ad girin", + "extension": "Uzantı", + "descriptionLabel": "Açıklama", + "descriptionPlaceholder": "Dosya açıklamasını girin", + "deleteFile": "Dosyayı Sil", + "deleteConfirmation": "\"{{fileName}}\" dosyasını silmek istediğinize emin misiniz?", + "deleteWarning": "Bu işlem geri alınamaz." + }, + "filePreview": { + "loading": "Önizleme yükleniyor...", + "notAvailable": "Önizleme mevcut değil", + "downloadToView": "İçeriği görüntülemek için dosyayı indirin", + "audioNotSupported": "Tarayıcınız ses öğesini desteklemiyor", + "videoNotSupported": "Tarayıcınız video öğesini desteklemiyor", + "loadError": "Önizleme yüklenemedi", + "downloadError": "Dosya indirilemedi" + }, + "generateShareLink": { + "generateTitle": "Paylaşım Bağlantısı Oluştur", + "updateTitle": "Paylaşım Bağlantısını Güncelle", + "generateDescription": "Dosyalarınızı paylaşmak için bir bağlantı oluşturun", + "updateDescription": "Bu paylaşım bağlantısı için takma ad güncelleyin", + "aliasPlaceholder": "Takma ad girin", + "linkReady": "Paylaşım bağlantınız hazır:", + "generateButton": "Bağlantıyı Oluştur", + "updateButton": "Bağlantıyı Güncelle", + "copyButton": "Bağlantıyı Kopyala", + "success": "Bağlantı başarıyla oluşturuldu", + "error": "Bağlantı oluşturulamadı", + "copied": "Bağlantı panoya kopyalandı" + }, + "shareActions": { + "deleteTitle": "Paylaşımı Sil", + "deleteConfirmation": "Bu paylaşımı silmek istediğinize emin misiniz? Bu işlem geri alınamaz.", + "editTitle": "Paylaşımı Düzenle", + "nameLabel": "Paylaşım Adı", + "expirationLabel": "Son Kullanma Tarihi", + "expirationPlaceholder": "MM/GG/YYYY SS:DD", + "maxViewsLabel": "Maksimum Görüntüleme", + "maxViewsPlaceholder": "Sınırsız için boş bırakın", + "passwordProtection": "Şifre Korumalı", + "passwordLabel": "Şifre", + "passwordPlaceholder": "Şifreyi girin", + "newPasswordLabel": "Yeni Şifre (mevcut şifreyi korumak için boş bırakın)", + "newPasswordPlaceholder": "Yeni şifreyi girin", + "manageFilesTitle": "Dosyaları Yönet", + "manageRecipientsTitle": "Alıcıları Yönet", + "editSuccess": "Paylaşım başarıyla güncellendi", + "editError": "Paylaşım güncellenemedi" + }, + "shareDetails": { + "title": "Paylaşım Detayları", + "subtitle": "Bu paylaşım hakkında ayrıntılı bilgi", + "basicInfo": "Temel Bilgiler", + "name": "Ad", + "untitled": "Adsız", + "views": "Görüntüleme", + "dates": "Tarihler", + "created": "Oluşturuldu", + "expires": "Sona Eriyor", + "never": "Asla", + "security": "Güvenlik", + "passwordProtected": "Şifre ile Korunuyor", + "publicAccess": "Genel Erişim", + "maxViews": "Maksimum Görüntüleme: {{count}}", + "files": "Dosyalar ({{count}})", + "recipients": "Alıcılar ({{count}})", + "notAvailable": "Mevcut Değil", + "invalidDate": "Geçersiz tarih", + "loadError": "Paylaşım detayları yüklenemedi" + }, + "uploadFile": { + "title": "Dosya Yükle", + "selectFile": "Dosya seçmek için tıklayın", + "preview": "Önizleme", + "uploadProgress": "Yükleme İlerlemesi", + "upload": "Yükle", + "success": "Dosya başarıyla yüklendi", + "error": "Dosya yüklenemedi" + }, + "filesTable": { + "ariaLabel": "Dosya Tablosu", + "columns": { + "name": "Ad", + "description": "Açıklama", + "size": "Boyut", + "createdAt": "Oluşturulma Tarihi", + "updatedAt": "Güncellenme Tarihi", + "actions": "İşlemler" + }, + "actions": { + "menu": "Dosya İşlem Menüsü", + "preview": "Önizleme", + "edit": "Düzenle", + "download": "İndir", + "delete": "Sil" + } + }, + "sharesTable": { + "ariaLabel": "Paylaşım Tablosu", + "never": "Asla", + "columns": { + "name": "Ad", + "createdAt": "Oluşturulma Tarihi", + "expiresAt": "Son Kullanma Tarihi", + "status": "Durum", + "security": "Güvenlik", + "files": "Dosyalar", + "recipients": "Alıcılar", + "actions": "İşlemler" + }, + "status": { + "neverExpires": "Sona Ermez", + "active": "Aktif", + "expired": "Sona Erdi" + }, + "security": { + "protected": "Korunuyor", + "public": "Genel" + }, + "filesCount": "{{count}} dosya", + "recipientsCount": "{{count}} alıcı", + "actions": { + "menu": "Paylaşım İşlem Menüsü", + "edit": "Düzenle", + "manageFiles": "Dosyaları Yönet", + "manageRecipients": "Alıcıları Yönet", + "viewDetails": "Detayları Görüntüle", + "generateLink": "Bağlantı Oluştur", + "editLink": "Bağlantıyı Düzenle", + "copyLink": "Bağlantıyı Kopyala", + "notifyRecipients": "Alıcıları Bildir", + "delete": "Sil" + } + }, + "footer": { + "poweredBy": "Tarafından destekleniyor:", + "kyanHomepage": "Kyantech Ana Sayfası" + }, + "fileManager": { + "downloadError": "Dosya indirilemedi", + "updateSuccess": "Dosya başarıyla güncellendi", + "updateError": "Dosya güncellenemedi", + "deleteSuccess": "Dosya başarıyla silindi", + "deleteError": "Dosya silinemedi" + }, + "shareManager": { + "deleteSuccess": "Paylaşım başarıyla silindi", + "deleteError": "Paylaşım silinemedi", + "updateSuccess": "Paylaşım başarıyla güncellendi", + "updateError": "Paylaşım güncellenemedi", + "filesUpdateSuccess": "Dosyalar başarıyla güncellendi", + "filesUpdateError": "Dosyalar güncellenemedi", + "recipientsUpdateSuccess": "Alıcılar başarıyla güncellendi", + "recipientsUpdateError": "Alıcılar güncellenemedi", + "linkGenerateSuccess": "Paylaşım bağlantısı başarıyla oluşturuldu", + "linkGenerateError": "Paylaşım bağlantısı oluşturulamadı", + "notifyLoading": "Bildirimler gönderiliyor...", + "notifySuccess": "Alıcılara başarıyla bildirildi", + "notifyError": "Alıcılara bildirim gönderilemedi" + }, + "quickAccess": { + "files": { + "title": "Benim Dosyalarım", + "description": "Yüklenen dosyalara erişin ve yönetin" + }, + "shares": { + "title": "Benim Paylaşımlarım", + "description": "Paylaşılan dosyaları görüntüleyin ve yönetin" + } + }, + "recentFiles": { + "title": "Son Yüklemeler", + "viewAll": "Tümünü Görüntüle", + "uploadFile": "Dosya Yükle", + "noFiles": "Henüz dosya yüklenmedi" + }, + "recentShares": { + "title": "Son Paylaşımlar", + "viewAll": "Tümünü Görüntüle", + "createShare": "Paylaşım Oluştur", + "noShares": "Henüz paylaşım oluşturulmadı", + "createFirst": "İlk paylaşımınızı oluşturun" + }, + "storageUsage": { + "title": "Depolama Kullanımı", + "ariaLabel": "Depolama kullanım ilerleme çubuğu", + "used": "{{size}} kullanıldı", + "available": "{{size}} kullanılabilir" + }, + "dashboard": { + "loadError": "Gösterge paneli verileri yüklenemedi", + "linkCopied": "Bağlantı panoya kopyalandı", + "pageTitle": "Gösterge Paneli", + "breadcrumb": "Gösterge Paneli" + }, + "emptyState": { + "noFiles": "Henüz dosya yüklenmedi", + "uploadFile": "Dosya Yükle" + }, + "files": { + "title": "Tüm Dosyalar", + "uploadFile": "Dosya Yükle", + "loadError": "Dosyalar yüklenemedi", + "pageTitle": "Benim Dosyalarım", + "breadcrumb": "Benim Dosyalarım" + }, + "searchBar": { + "placeholder": "Dosya ara...", + "results": "Toplam {{total}} dosya içinde {{filtered}} dosya bulundu" + }, + "forgotPassword": { + "emailLabel": "E-posta Adresi", + "emailPlaceholder": "E-posta adresinizi girin", + "sending": "Gönderiliyor...", + "submit": "Şifre Sıfırlama Talimatlarını Gönder", + "backToLogin": "Girişe Geri Dön", + "title": "Şifrenizi mi Unuttunuz?", + "description": "E-posta adresinizi girin, şifre sıfırlama talimatlarını göndereceğiz.", + "resetInstructions": "Şifre sıfırlama talimatları e-posta adresinize gönderildi", + "pageTitle": "Şifrenizi mi Unuttunuz?" + }, + "home": { + "description": "WeTransfer'e açık kaynaklı alternatif. Takip veya kısıtlama olmadan dosyalarınızı güvenle paylaşın.", + "documentation": "Belgelendirme", + "starOnGithub": "GitHub'da Yıldız Verin", + "privacyMessage": "Gizlilik göz önünde bulundurularak tasarlanmıştır. Yüklemeden önceki dosyalar, yalnızca paylaşım bağlantısına sahip olanlar tarafından erişilebilir. Her zaman ücretsiz ve açık kaynaktır.", + "header": { + "fileSharing": "Dosya Paylaşımı", + "tagline": "Basit ve Ücretsiz" + }, + "pageTitle": "Ana Sayfa" + }, + "profile": { + "password": { + "title": "Şifreyi Değiştir", + "newPassword": "Yeni Şifre", + "confirmPassword": "Yeni Şifreyi Onayla", + "updateButton": "Şifreyi Güncelle" + }, + "form": { + "title": "Profil Bilgileri", + "firstName": "Ad", + "lastName": "Soyad", + "username": "Kullanıcı Adı", + "email": "E-posta", + "updateButton": "Profili Güncelle" + }, + "header": { + "title": "Profil", + "subtitle": "Kişisel bilgilerinizi ve şifrenizi yönetin" + }, + "picture": { + "title": "Profil Resmi", + "description": "Profil resmini değiştirmek için kamera simgesine tıklayın", + "uploadPhoto": "Fotoğraf Yükle", + "removePhoto": "Fotoğrafı Kaldır" + }, + "errors": { + "loadFailed": "Kullanıcı verileri yüklenemedi", + "updateFailed": "Profil güncellenemedi", + "passwordFailed": "Şifre güncellenemedi", + "imageFailed": "Profil resmi güncellenemedi", + "imageRemoveFailed": "Profil resmi kaldırılamadı" + }, + "messages": { + "noChanges": "Kaydedilecek değişiklik yok", + "updateSuccess": "Profil başarıyla güncellendi", + "fillPasswords": "Lütfen her iki şifre alanını da doldurun", + "passwordSuccess": "Şifre başarıyla güncellendi", + "imageSuccess": "Profil resmi başarıyla güncellendi", + "imageRemoved": "Profil resmi başarıyla kaldırıldı" + }, + "pageTitle": "Profil" + }, + "resetPassword": { + "pageTitle": "Şifreyi Sıfırla", + "header": { + "title": "Şifreyi Sıfırla", + "description": "Aşağıya yeni şifrenizi girin" + }, + "form": { + "newPassword": "Yeni Şifre", + "newPasswordPlaceholder": "Yeni şifrenizi girin", + "confirmPassword": "Yeni Şifreyi Onayla", + "confirmPasswordPlaceholder": "Yeni şifrenizi tekrar girin", + "resetting": "Şifre sıfırlanıyor...", + "submit": "Şifreyi Sıfırla", + "backToLogin": "Girişe Geri Dön" + }, + "messages": { + "success": "Şifre başarıyla sıfırlandı" + }, + "errors": { + "serverError": "Şifre sıfırlama başarısız. Lütfen tekrar deneyin.", + "invalidToken": "Geçersiz veya eksik sıfırlama belirteci" + } + }, + "settings": { + "groups": { + "defaultDescription": "Yapılandırma seçenekleri", + "general": { + "title": "Genel", + "description": "Uygulamanın temel ayarları" + }, + "email": { + "title": "E-posta", + "description": "E-posta sunucusu yapılandırması" + }, + "security": { + "title": "Güvenlik", + "description": "Güvenlik ve kimlik doğrulama ayarları" + }, + "storage": { + "title": "Depolama", + "description": "Dosya depolama yapılandırması" + } + }, + "fields": { + "noDescription": "Açıklama mevcut değil", + "appLogo": { + "title": "Uygulama Logosu", + "description": "Uygulama logosu resmi" + }, + "appName": { + "title": "Uygulama Adı", + "description": "Kullanıcılara gösterilen uygulama adı" + }, + "appDescription": { + "title": "Uygulama Açıklaması", + "description": "Uygulama hakkında kısa açıklama" + }, + "showHomePage": { + "title": "Ana Sayfayı Göster", + "description": "Kurulumdan sonra ana sayfayı göster" + }, + "smtpEnabled": { + "title": "SMTP Etkin", + "description": "SMTP e-posta işlevini etkinleştir veya devre dışı bırak" + }, + "smtpHost": { + "title": "SMTP Sunucusu", + "description": "SMTP sunucusunun adresi" + }, + "smtpPort": { + "title": "SMTP Portu", + "description": "SMTP sunucu portu" + }, + "smtpUser": { + "title": "SMTP Kullanıcısı", + "description": "SMTP kimlik doğrulaması için kullanıcı adı" + }, + "smtpPass": { + "title": "SMTP Şifresi", + "description": "SMTP kimlik doğrulaması için şifre" + }, + "smtpFromName": { + "title": "Gönderen Adı", + "description": "Gönderilen e-postalarda görüntülenecek isim" + }, + "smtpFromEmail": { + "title": "Gönderen E-postası", + "description": "Gönderenin e-posta adresi" + }, + "maxLoginAttempts": { + "title": "Maksimum Giriş Denemesi", + "description": "Engelleme öncesi maksimum giriş denemesi sayısı" + }, + "loginBlockDuration": { + "title": "Giriş Engelleme Süresi", + "description": "Deneme sayısı aşıldıktan sonra engelleme süresi (saniye cinsinden)" + }, + "passwordMinLength": { + "title": "Minimum Şifre Uzunluğu", + "description": "Şifre için gereken minimum karakter sayısı" + }, + "passwordResetTokenExpiration": { + "title": "Şifre Sıfırlama Belirtecinin Süresi", + "description": "Şifre sıfırlama belirtecinin geçerlilik süresi (saniye cinsinden)" + }, + "maxFileSize": { + "title": "Maksimum Dosya Boyutu", + "description": "Yüklemeye izin verilen maksimum dosya boyutu (bayt cinsinden)" + }, + "maxTotalStoragePerUser": { + "title": "Kullanıcı Başına Maksimum Depolama", + "description": "Kullanıcı başına toplam depolama sınırı (bayt cinsinden)" + } + }, + "buttons": { + "save": "{{group}} Kaydet" + }, + "errors": { + "loadFailed": "Ayarlar yüklenemedi", + "updateFailed": "Ayarlar güncellenemedi" + }, + "messages": { + "noChanges": "Kaydedilecek değişiklik yok", + "updateSuccess": "{{group}} ayarları başarıyla güncellendi" + }, + "title": "Ayarlar", + "breadcrumb": "Ayarlar", + "pageTitle": "Ayarlar" + }, + "share": { + "errors": { + "invalidPassword": "Geçersiz şifre. Lütfen tekrar deneyin.", + "loadFailed": "Paylaşım yüklenemedi", + "downloadFailed": "Dosya indirilemedi" + }, + "messages": { + "downloadStarted": "İndirme başladı" + }, + "password": { + "title": "Şifre Korumalı Paylaşım", + "protected": "Bu paylaşım şifre ile korunuyor", + "incorrect": "Şifre yanlış. Lütfen tekrar deneyin.", + "label": "Şifre", + "placeholder": "Paylaşım şifresini girin", + "submit": "Gönder" + }, + "details": { + "untitled": "Adsız", + "created": "Oluşturulma: {{date}}", + "expires": "Son Kullanma: {{date}}" + }, + "notFound": { + "title": "Paylaşım Bulunamadı", + "description": "Bu paylaşım silinmiş veya süresi dolmuş olabilir." + }, + "pageTitle": "Paylaşım" + }, + "shares": { + "errors": { + "loadFailed": "Paylaşımlar yüklenemedi", + "notifyFailed": "Alıcılara bildirim gönderilemedi", + "smtpConfigFailed": "SMTP ayarları yüklenemedi" + }, + "messages": { + "linkCopied": "Bağlantı panoya kopyalandı", + "recipientsNotified": "Alıcılar başarıyla bildirildi" + }, + "empty": { + "message": "Henüz paylaşım oluşturulmadı", + "createButton": "Paylaşım Oluştur" + }, + "header": { + "title": "Benim Paylaşımlarım", + "myShares": "Benim Paylaşımlarım" + }, + "search": { + "title": "Tüm Paylaşımlar", + "createButton": "Paylaşım Oluştur", + "placeholder": "Paylaşım ara...", + "results": "Toplam {{total}} paylaşım arasında {{filtered}} paylaşım bulundu" + }, + "pageTitle": "Paylaşımlar" + }, + "users": { + "modes": { + "create": "Oluştur", + "edit": "Düzenle" + }, + "errors": { + "loadFailed": "Kullanıcılar yüklenemedi", + "submitFailed": "Kullanıcı {{mode}} edilemedi", + "deleteFailed": "Kullanıcı silinemedi", + "statusUpdateFailed": "Kullanıcı durumu güncellenemedi" + }, + "messages": { + "createSuccess": "Kullanıcı başarıyla oluşturuldu", + "updateSuccess": "Kullanıcı başarıyla güncellendi", + "deleteSuccess": "Kullanıcı başarıyla silindi", + "activateSuccess": "Kullanıcı başarıyla etkinleştirildi", + "deactivateSuccess": "Kullanıcı başarıyla devre dışı bırakıldı" + }, + "actions": { + "edit": "Düzenle", + "activate": "Etkinleştir", + "deactivate": "Devre Dışı Bırak", + "delete": "Sil" + }, + "delete": { + "title": "Kullanıcı Silmeyi Onayla", + "confirmation": "{{firstName}} {{lastName}} adlı kullanıcıyı silmek istediğinize emin misiniz? Bu işlem geri alınamaz.", + "confirm": "Kullanıcıyı Sil" + }, + "form": { + "titleCreate": "Yeni Kullanıcı Ekle", + "titleEdit": "Kullanıcıyı Düzenle", + "firstName": "Ad", + "lastName": "Soyad", + "username": "Kullanıcı Adı", + "email": "E-posta", + "password": "Şifre", + "newPassword": "Yeni Şifre (Opsiyonel)", + "passwordPlaceholder": "Mevcut şifreyi korumak için boş bırakın", + "role": "Rol", + "roleUser": "Kullanıcı", + "roleAdmin": "Yönetici", + "create": "Oluştur", + "save": "Kaydet" + }, + "status": { + "title": "Durum Değişikliğini Onayla", + "confirmation": "{{firstName}} {{lastName}} adlı kullanıcıyı {{action}} etmek istediğinize emin misiniz?", + "activate": "Etkinleştir", + "deactivate": "Devre Dışı Bırak", + "user": "Kullanıcı" + }, + "header": { + "title": "Kullanıcı Yönetimi", + "addUser": "Kullanıcı Ekle", + "management": "Kullanıcı Yönetimi" + }, + "table": { + "user": "Kullanıcı", + "email": "E-posta", + "status": "Durum", + "role": "Rol", + "actions": "İşlemler", + "active": "Etkin", + "inactive": "Devre Dışı", + "admin": "Yönetici", + "userr": "Kullanıcı" + } + }, + "logo": { + "labels": { + "appLogo": "Uygulama Logosu" + }, + "buttons": { + "upload": "Logoyu Yükle", + "remove": "Logoyu Kaldır" + }, + "messages": { + "uploadSuccess": "Logo başarıyla yüklendi", + "removeSuccess": "Logo başarıyla kaldırıldı" + }, + "errors": { + "uploadFailed": "Logo yüklenemedi", + "removeFailed": "Logo kaldırılamadı" + } + }, + "navbar": { + "logoAlt": "Uygulama Logosu", + "profileMenu": "Profil Menüsü", + "profile": "Profil", + "settings": "Ayarlar", + "usersManagement": "Kullanıcı Yönetimi", + "logout": "Oturumu Kapat" + } +} \ No newline at end of file diff --git a/apps/app/messages/zh-CN.json b/apps/app/messages/zh-CN.json new file mode 100644 index 0000000..38e6c5a --- /dev/null +++ b/apps/app/messages/zh-CN.json @@ -0,0 +1,638 @@ +{ + "login": { + "welcome": "欢迎您", + "signInToContinue": "请登录以继续", + "emailLabel": "电子邮件地址", + "emailPlaceholder": "请输入您的电子邮件", + "passwordLabel": "密码", + "passwordPlaceholder": "请输入您的密码", + "signIn": "登录", + "signingIn": "正在登录...", + "forgotPassword": "忘记密码?", + "pageTitle": "登录" + }, + "errors": { + "invalidCredentials": "电子邮件或密码错误", + "userNotFound": "未找到用户", + "accountLocked": "账户已锁定。请稍后再试", + "unexpectedError": "发生意外错误。请重试" + }, + "validation": { + "invalidEmail": "无效的电子邮件地址", + "passwordMinLength": "密码至少需要6个字符", + "firstNameRequired": "名字为必填项", + "lastNameRequired": "姓氏为必填项", + "usernameLength": "用户名至少需要3个字符", + "usernameSpaces": "用户名不能包含空格", + "passwordLength": "密码至少需要8个字符", + "passwordsMatch": "密码不匹配", + "emailRequired": "电子邮件为必填项", + "passwordRequired": "密码为必填项" + }, + "fileSelector": { + "availableFiles": "可用文件 ({{count}})", + "shareFiles": "共享文件 ({{count}})", + "searchPlaceholder": "搜索文件...", + "noMatchingFiles": "没有匹配的文件", + "noAvailableFiles": "没有可用的文件", + "noFilesInShare": "共享中没有文件", + "saveChanges": "保存更改" + }, + "recipientSelector": { + "emailPlaceholder": "请输入收件人电子邮件", + "add": "添加", + "recipients": "收件人 ({{count}})", + "notifyAll": "通知所有人", + "noRecipients": "还没有添加收件人", + "addSuccess": "收件人添加成功", + "addError": "添加收件人失败", + "removeSuccess": "收件人删除成功", + "removeError": "删除收件人失败", + "sendingNotifications": "正在发送通知...", + "notifySuccess": "收件人通知成功", + "notifyError": "通知收件人失败" + }, + "navigation": { + "dashboard": "仪表盘" + }, + "common": { + "loading": "加载中,请稍候...", + "cancel": "取消", + "save": "保存", + "delete": "删除", + "close": "关闭", + "download": "下载", + "unexpectedError": "发生意外错误。请重试。", + "yes": "是", + "no": "否", + "dashboard": "仪表盘" + }, + "createShare": { + "title": "创建共享", + "nameLabel": "共享名称", + "expirationLabel": "过期日期", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "最大查看次数", + "maxViewsPlaceholder": "留空表示无限", + "passwordProtection": "密码保护", + "passwordLabel": "密码", + "create": "创建共享", + "success": "共享创建成功", + "error": "创建共享失败" + }, + "fileActions": { + "editFile": "编辑文件", + "nameLabel": "名称", + "namePlaceholder": "请输入新名称", + "extension": "扩展名", + "descriptionLabel": "描述", + "descriptionPlaceholder": "请输入文件描述", + "deleteFile": "删除文件", + "deleteConfirmation": "您确定要删除“{{fileName}}”吗?", + "deleteWarning": "此操作不可撤销。" + }, + "filePreview": { + "loading": "正在加载预览...", + "notAvailable": "预览不可用", + "downloadToView": "下载文件以查看内容", + "audioNotSupported": "您的浏览器不支持音频元素", + "videoNotSupported": "您的浏览器不支持视频元素", + "loadError": "加载预览失败", + "downloadError": "下载文件失败" + }, + "generateShareLink": { + "generateTitle": "生成共享链接", + "updateTitle": "更新共享链接", + "generateDescription": "生成用于共享文件的链接", + "updateDescription": "更新此共享链接的别名", + "aliasPlaceholder": "请输入别名", + "linkReady": "您的共享链接已准备好:", + "generateButton": "生成链接", + "updateButton": "更新链接", + "copyButton": "复制链接", + "success": "链接生成成功", + "error": "生成链接失败", + "copied": "链接已复制到剪贴板" + }, + "shareActions": { + "deleteTitle": "删除共享", + "deleteConfirmation": "您确定要删除此共享吗?此操作不可撤销。", + "editTitle": "编辑共享", + "nameLabel": "共享名称", + "expirationLabel": "过期日期", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "最大查看次数", + "maxViewsPlaceholder": "留空表示无限", + "passwordProtection": "密码保护", + "passwordLabel": "密码", + "passwordPlaceholder": "请输入密码", + "newPasswordLabel": "新密码(留空表示保持当前密码)", + "newPasswordPlaceholder": "请输入新密码", + "manageFilesTitle": "管理文件", + "manageRecipientsTitle": "管理收件人", + "editSuccess": "共享更新成功", + "editError": "更新共享失败" + }, + "shareDetails": { + "title": "共享详情", + "subtitle": "关于此共享的详细信息", + "basicInfo": "基本信息", + "name": "名称", + "untitled": "未命名", + "views": "查看次数", + "dates": "日期", + "created": "创建于", + "expires": "过期于", + "never": "从不", + "security": "安全性", + "passwordProtected": "受密码保护", + "publicAccess": "公开访问", + "maxViews": "最大查看次数:{{count}}", + "files": "文件 ({{count}})", + "recipients": "收件人 ({{count}})", + "notAvailable": "不适用", + "invalidDate": "无效的日期", + "loadError": "加载共享详情失败" + }, + "uploadFile": { + "title": "上传文件", + "selectFile": "点击选择文件", + "preview": "预览", + "uploadProgress": "上传进度", + "upload": "上传", + "success": "文件上传成功", + "error": "文件上传失败" + }, + "filesTable": { + "ariaLabel": "文件表格", + "columns": { + "name": "名称", + "description": "描述", + "size": "大小", + "createdAt": "创建时间", + "updatedAt": "更新时间", + "actions": "操作" + }, + "actions": { + "menu": "文件操作菜单", + "preview": "预览", + "edit": "编辑", + "download": "下载", + "delete": "删除" + } + }, + "sharesTable": { + "ariaLabel": "共享表格", + "never": "从不", + "columns": { + "name": "名称", + "createdAt": "创建时间", + "expiresAt": "过期时间", + "status": "状态", + "security": "安全性", + "files": "文件", + "recipients": "收件人", + "actions": "操作" + }, + "status": { + "neverExpires": "永不过期", + "active": "活跃", + "expired": "已过期" + }, + "security": { + "protected": "受保护", + "public": "公开" + }, + "filesCount": "{{count}} 个文件", + "recipientsCount": "{{count}} 个收件人", + "actions": { + "menu": "共享操作菜单", + "edit": "编辑", + "manageFiles": "管理文件", + "manageRecipients": "管理收件人", + "viewDetails": "查看详情", + "generateLink": "生成链接", + "editLink": "编辑链接", + "copyLink": "复制链接", + "notifyRecipients": "通知收件人", + "delete": "删除" + } + }, + "footer": { + "poweredBy": "技术支持:", + "kyanHomepage": "Kyantech 主页" + }, + "fileManager": { + "downloadError": "文件下载失败", + "updateSuccess": "文件更新成功", + "updateError": "文件更新失败", + "deleteSuccess": "文件删除成功", + "deleteError": "文件删除失败" + }, + "shareManager": { + "deleteSuccess": "共享删除成功", + "deleteError": "共享删除失败", + "updateSuccess": "共享更新成功", + "updateError": "共享更新失败", + "filesUpdateSuccess": "文件更新成功", + "filesUpdateError": "文件更新失败", + "recipientsUpdateSuccess": "收件人更新成功", + "recipientsUpdateError": "收件人更新失败", + "linkGenerateSuccess": "共享链接生成成功", + "linkGenerateError": "共享链接生成失败", + "notifyLoading": "正在发送通知...", + "notifySuccess": "通知收件人成功", + "notifyError": "通知收件人失败" + }, + "quickAccess": { + "files": { + "title": "我的文件", + "description": "访问和管理您上传的文件" + }, + "shares": { + "title": "我的共享", + "description": "查看和管理您共享的文件" + } + }, + "recentFiles": { + "title": "最近上传", + "viewAll": "查看全部", + "uploadFile": "上传文件", + "noFiles": "尚未上传文件" + }, + "recentShares": { + "title": "最近共享", + "viewAll": "查看全部", + "createShare": "创建共享", + "noShares": "尚未创建共享", + "createFirst": "请创建您的第一个共享" + }, + "storageUsage": { + "title": "存储使用情况", + "ariaLabel": "存储使用进度条", + "used": "已使用:{{size}}", + "available": "可用:{{size}}" + }, + "dashboard": { + "loadError": "加载仪表盘数据失败", + "linkCopied": "链接已复制到剪贴板", + "pageTitle": "仪表盘", + "breadcrumb": "仪表盘" + }, + "emptyState": { + "noFiles": "尚未上传任何文件", + "uploadFile": "上传文件" + }, + "files": { + "title": "所有文件", + "uploadFile": "上传文件", + "loadError": "加载文件失败", + "pageTitle": "我的文件", + "breadcrumb": "我的文件" + }, + "searchBar": { + "placeholder": "搜索文件...", + "results": "共{{total}}个文件,找到{{filtered}}个" + }, + "forgotPassword": { + "emailLabel": "电子邮件地址", + "emailPlaceholder": "请输入您的电子邮件", + "sending": "正在发送...", + "submit": "发送密码重置指令", + "backToLogin": "返回登录", + "title": "忘记密码?", + "description": "请输入您的电子邮件,我们将发送密码重置指令给您。", + "resetInstructions": "密码重置指令已发送到您的电子邮件", + "pageTitle": "忘记密码?" + }, + "home": { + "description": "WeTransfer的开源替代方案。安全分享文件,无需跟踪或限制。", + "documentation": "文档", + "starOnGithub": "在GitHub上点赞", + "privacyMessage": "本应用注重隐私。在上传前,您的文件仅对拥有共享链接的人可见。永远免费且开源。", + "header": { + "fileSharing": "文件共享", + "tagline": "简单且免费" + }, + "pageTitle": "首页" + }, + "profile": { + "password": { + "title": "修改密码", + "newPassword": "新密码", + "confirmPassword": "确认新密码", + "updateButton": "更新密码" + }, + "form": { + "title": "个人资料信息", + "firstName": "名字", + "lastName": "姓氏", + "username": "用户名", + "email": "电子邮件", + "updateButton": "更新资料" + }, + "header": { + "title": "个人资料", + "subtitle": "管理您的个人信息和密码" + }, + "picture": { + "title": "个人头像", + "description": "点击相机图标以更换头像", + "uploadPhoto": "上传照片", + "removePhoto": "移除照片" + }, + "errors": { + "loadFailed": "加载用户数据失败", + "updateFailed": "更新个人资料失败", + "passwordFailed": "更新密码失败", + "imageFailed": "更新头像失败", + "imageRemoveFailed": "移除头像失败" + }, + "messages": { + "noChanges": "没有可保存的更改", + "updateSuccess": "个人资料更新成功", + "fillPasswords": "请填写两个密码字段", + "passwordSuccess": "密码更新成功", + "imageSuccess": "头像更新成功", + "imageRemoved": "头像移除成功" + }, + "pageTitle": "个人资料" + }, + "resetPassword": { + "pageTitle": "重置密码", + "header": { + "title": "重置密码", + "description": "在下方输入您的新密码" + }, + "form": { + "newPassword": "新密码", + "newPasswordPlaceholder": "请输入新密码", + "confirmPassword": "确认新密码", + "confirmPasswordPlaceholder": "请再次输入新密码", + "resetting": "正在重置密码...", + "submit": "重置密码", + "backToLogin": "返回登录" + }, + "messages": { + "success": "密码重置成功" + }, + "errors": { + "serverError": "密码重置失败,请重试。", + "invalidToken": "无效或缺失重置令牌" + } + }, + "settings": { + "groups": { + "defaultDescription": "配置选项", + "general": { + "title": "通用", + "description": "基本的应用设置" + }, + "email": { + "title": "电子邮件", + "description": "电子邮件服务器配置" + }, + "security": { + "title": "安全性", + "description": "安全与认证设置" + }, + "storage": { + "title": "存储", + "description": "文件存储配置" + } + }, + "fields": { + "noDescription": "暂无描述", + "appLogo": { + "title": "应用Logo", + "description": "应用的Logo图片" + }, + "appName": { + "title": "应用名称", + "description": "显示给用户的应用名称" + }, + "appDescription": { + "title": "应用描述", + "description": "对应用的简短描述" + }, + "showHomePage": { + "title": "显示首页", + "description": "安装后显示首页" + }, + "smtpEnabled": { + "title": "启用SMTP", + "description": "启用或禁用SMTP邮件功能" + }, + "smtpHost": { + "title": "SMTP服务器", + "description": "SMTP服务器地址" + }, + "smtpPort": { + "title": "SMTP端口", + "description": "SMTP服务器端口" + }, + "smtpUser": { + "title": "SMTP用户名", + "description": "用于SMTP认证的用户名" + }, + "smtpPass": { + "title": "SMTP密码", + "description": "用于SMTP认证的密码" + }, + "smtpFromName": { + "title": "发件人姓名", + "description": "发送邮件时显示的名称" + }, + "smtpFromEmail": { + "title": "发件人电子邮件", + "description": "发件人的电子邮件地址" + }, + "maxLoginAttempts": { + "title": "最大登录尝试次数", + "description": "达到限制前允许的最大登录尝试次数" + }, + "loginBlockDuration": { + "title": "登录阻止时长", + "description": "超过尝试次数后的阻止时长(以秒为单位)" + }, + "passwordMinLength": { + "title": "最小密码长度", + "description": "密码所需的最小字符数" + }, + "passwordResetTokenExpiration": { + "title": "密码重置令牌有效期", + "description": "密码重置令牌的有效时长(以秒为单位)" + }, + "maxFileSize": { + "title": "最大文件大小", + "description": "允许上传的最大文件大小(以字节为单位)" + }, + "maxTotalStoragePerUser": { + "title": "每个用户的最大存储量", + "description": "每个用户的总存储限制(以字节为单位)" + } + }, + "buttons": { + "save": "保存 {{group}}" + }, + "errors": { + "loadFailed": "加载设置失败", + "updateFailed": "更新设置失败" + }, + "messages": { + "noChanges": "没有需要保存的更改", + "updateSuccess": "{{group}}设置更新成功" + }, + "title": "设置", + "breadcrumb": "设置", + "pageTitle": "设置" + }, + "share": { + "errors": { + "invalidPassword": "无效的密码。请重试。", + "loadFailed": "加载共享失败", + "downloadFailed": "下载文件失败" + }, + "messages": { + "downloadStarted": "下载已开始" + }, + "password": { + "title": "密码保护的共享", + "protected": "此共享受密码保护", + "incorrect": "密码不正确。请重试。", + "label": "密码", + "placeholder": "请输入共享密码", + "submit": "提交" + }, + "details": { + "untitled": "未命名", + "created": "创建于:{{date}}", + "expires": "过期于:{{date}}" + }, + "notFound": { + "title": "未找到共享", + "description": "该共享可能已被删除或已过期。" + }, + "pageTitle": "共享" + }, + "shares": { + "errors": { + "loadFailed": "加载共享失败", + "notifyFailed": "通知收件人失败", + "smtpConfigFailed": "加载SMTP配置失败" + }, + "messages": { + "linkCopied": "链接已复制到剪贴板", + "recipientsNotified": "收件人已成功通知" + }, + "empty": { + "message": "尚未创建共享", + "createButton": "创建共享" + }, + "header": { + "title": "我的共享", + "myShares": "我的共享" + }, + "search": { + "title": "所有共享", + "createButton": "创建共享", + "placeholder": "搜索共享...", + "results": "在总共{{total}}个共享中找到了{{filtered}}个" + }, + "pageTitle": "共享" + }, + "users": { + "modes": { + "create": "创建", + "edit": "编辑" + }, + "errors": { + "loadFailed": "加载用户失败", + "submitFailed": "用户{{mode}}失败", + "deleteFailed": "删除用户失败", + "statusUpdateFailed": "更新用户状态失败" + }, + "messages": { + "createSuccess": "用户创建成功", + "updateSuccess": "用户更新成功", + "deleteSuccess": "用户删除成功", + "activateSuccess": "用户已成功激活", + "deactivateSuccess": "用户已成功停用" + }, + "actions": { + "edit": "编辑", + "activate": "激活", + "deactivate": "停用", + "delete": "删除" + }, + "delete": { + "title": "确认删除用户", + "confirmation": "您确定要删除{{firstName}} {{lastName}}吗?此操作不可撤销。", + "confirm": "删除用户" + }, + "form": { + "titleCreate": "添加新用户", + "titleEdit": "编辑用户", + "firstName": "名字", + "lastName": "姓氏", + "username": "用户名", + "email": "电子邮件", + "password": "密码", + "newPassword": "新密码(可选)", + "passwordPlaceholder": "留空以保留当前密码", + "role": "角色", + "roleUser": "用户", + "roleAdmin": "管理员", + "create": "创建", + "save": "保存" + }, + "status": { + "title": "确认状态更改", + "confirmation": "您确定要{{action}}{{firstName}} {{lastName}}吗?", + "activate": "激活", + "deactivate": "停用", + "user": "用户" + }, + "header": { + "title": "用户管理", + "addUser": "添加用户", + "management": "用户管理" + }, + "table": { + "user": "用户", + "email": "电子邮件", + "status": "状态", + "role": "角色", + "actions": "操作", + "active": "激活", + "inactive": "停用", + "admin": "管理员", + "userr": "用户" + } + }, + "logo": { + "labels": { + "appLogo": "应用Logo" + }, + "buttons": { + "upload": "上传Logo", + "remove": "删除Logo" + }, + "messages": { + "uploadSuccess": "Logo上传成功", + "removeSuccess": "Logo删除成功" + }, + "errors": { + "uploadFailed": "Logo上传失败", + "removeFailed": "Logo删除失败" + } + }, + "navbar": { + "logoAlt": "应用Logo", + "profileMenu": "个人菜单", + "profile": "个人资料", + "settings": "设置", + "usersManagement": "用户管理", + "logout": "退出登录" + } +} \ No newline at end of file diff --git a/apps/app/next.config.ts b/apps/app/next.config.ts new file mode 100644 index 0000000..ff77283 --- /dev/null +++ b/apps/app/next.config.ts @@ -0,0 +1,7 @@ +import { NextConfig } from "next"; +import createNextIntlPlugin from "next-intl/plugin"; + +const nextConfig: NextConfig = {}; + +const withNextIntl = createNextIntlPlugin(); +export default withNextIntl(nextConfig); diff --git a/apps/app/package.json b/apps/app/package.json new file mode 100644 index 0000000..d98cb42 --- /dev/null +++ b/apps/app/package.json @@ -0,0 +1,58 @@ +{ + "name": "palmr-app-v2", + "version": "2.0.0", + "private": true, + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "eslint \"src/**/*.+(ts|tsx)\"", + "lint:fix": "eslint \"src/**/*.+(ts|tsx)\" --fix", + "format": "prettier . --write", + "format:check": "prettier . --check" + }, + "dependencies": { + "@hookform/resolvers": "^5.0.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-slot": "^1.1.2", + "@tabler/icons-react": "^3.31.0", + "axios": "^1.8.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "framer-motion": "^12.6.3", + "lucide-react": "^0.487.0", + "next": "15.2.4", + "next-intl": "^4.0.2", + "next-themes": "^0.4.6", + "nookies": "^2.5.2", + "react": "^19.1.0", + "react-country-flag": "^3.1.0", + "react-dom": "^19.1.0", + "react-hook-form": "^7.55.0", + "tailwind-merge": "^3.1.0", + "tw-animate-css": "^1.2.5", + "zod": "^3.24.2", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@eslint/eslintrc": "3.3.1", + "@eslint/js": "9.23.0", + "@ianvs/prettier-plugin-sort-imports": "4.4.1", + "@tailwindcss/postcss": "4.1.2", + "@types/node": "22.14.0", + "@types/react": "19.1.0", + "@types/react-dom": "19.1.1", + "@typescript-eslint/eslint-plugin": "8.29.0", + "@typescript-eslint/parser": "8.29.0", + "eslint": "9.23.0", + "eslint-config-next": "15.2.4", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-prettier": "5.2.6", + "prettier": "3.5.3", + "prettier-plugin-sort-json": "4.1.1", + "tailwindcss": "4.1.2", + "typescript": "5.8.2" + } +} \ No newline at end of file diff --git a/apps/app/pnpm-lock.yaml b/apps/app/pnpm-lock.yaml new file mode 100644 index 0000000..74ce7f7 --- /dev/null +++ b/apps/app/pnpm-lock.yaml @@ -0,0 +1,4902 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@hookform/resolvers': + specifier: ^5.0.1 + version: 5.0.1(react-hook-form@7.55.0(react@19.1.0)) + '@radix-ui/react-dialog': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@tabler/icons-react': + specifier: ^3.31.0 + version: 3.31.0(react@19.1.0) + axios: + specifier: ^1.8.4 + version: 1.8.4 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + framer-motion: + specifier: ^12.6.3 + version: 12.6.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + lucide-react: + specifier: ^0.487.0 + version: 0.487.0(react@19.1.0) + next: + specifier: 15.2.4 + version: 15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-intl: + specifier: ^4.0.2 + version: 4.0.2(next@15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.2) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + nookies: + specifier: ^2.5.2 + version: 2.5.2 + react: + specifier: ^19.1.0 + version: 19.1.0 + react-country-flag: + specifier: ^3.1.0 + version: 3.1.0(react@19.1.0) + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + react-hook-form: + specifier: ^7.55.0 + version: 7.55.0(react@19.1.0) + tailwind-merge: + specifier: ^3.1.0 + version: 3.1.0 + tw-animate-css: + specifier: ^1.2.5 + version: 1.2.5 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@19.1.0)(react@19.1.0) + devDependencies: + '@eslint/eslintrc': + specifier: 3.3.1 + version: 3.3.1 + '@eslint/js': + specifier: 9.23.0 + version: 9.23.0 + '@ianvs/prettier-plugin-sort-imports': + specifier: 4.4.1 + version: 4.4.1(prettier@3.5.3) + '@tailwindcss/postcss': + specifier: 4.1.2 + version: 4.1.2 + '@types/node': + specifier: 22.14.0 + version: 22.14.0 + '@types/react': + specifier: 19.1.0 + version: 19.1.0 + '@types/react-dom': + specifier: 19.1.1 + version: 19.1.1(@types/react@19.1.0) + '@typescript-eslint/eslint-plugin': + specifier: 8.29.0 + version: 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/parser': + specifier: 8.29.0 + version: 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: + specifier: 9.23.0 + version: 9.23.0(jiti@2.4.2) + eslint-config-next: + specifier: 15.2.4 + version: 15.2.4(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint-config-prettier: + specifier: 9.1.0 + version: 9.1.0(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-prettier: + specifier: 5.2.6 + version: 5.2.6(eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)))(eslint@9.23.0(jiti@2.4.2))(prettier@3.5.3) + prettier: + specifier: 3.5.3 + version: 3.5.3 + prettier-plugin-sort-json: + specifier: 4.1.1 + version: 4.1.1(prettier@3.5.3) + tailwindcss: + specifier: 4.1.2 + version: 4.1.2 + typescript: + specifier: 5.8.2 + version: 5.8.2 + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.0': + resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.0': + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.27.0': + resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.0': + resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.0': + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + engines: {node: '>=6.9.0'} + + '@emnapi/core@1.4.0': + resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} + + '@emnapi/runtime@1.4.0': + resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} + + '@emnapi/wasi-threads@1.0.1': + resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + + '@eslint-community/eslint-utils@4.5.1': + resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.19.2': + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.1': + resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.23.0': + resolution: {integrity: sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + + '@floating-ui/react-dom@2.1.2': + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@formatjs/ecma402-abstract@2.3.4': + resolution: {integrity: sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==} + + '@formatjs/fast-memoize@2.2.7': + resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==} + + '@formatjs/icu-messageformat-parser@2.11.2': + resolution: {integrity: sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==} + + '@formatjs/icu-skeleton-parser@1.8.14': + resolution: {integrity: sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==} + + '@formatjs/intl-localematcher@0.5.10': + resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==} + + '@formatjs/intl-localematcher@0.6.1': + resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==} + + '@hookform/resolvers@5.0.1': + resolution: {integrity: sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA==} + peerDependencies: + react-hook-form: ^7.55.0 + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + + '@ianvs/prettier-plugin-sort-imports@4.4.1': + resolution: {integrity: sha512-F0/Hrcfpy8WuxlQyAWJTEren/uxKhYonOGY4OyWmwRdeTvkh9mMSCxowZLjNkhwi/2ipqCgtXwwOk7tW0mWXkA==} + peerDependencies: + '@vue/compiler-sfc': 2.7.x || 3.x + prettier: 2 || 3 + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@napi-rs/wasm-runtime@0.2.8': + resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} + + '@next/env@15.2.4': + resolution: {integrity: sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==} + + '@next/eslint-plugin-next@15.2.4': + resolution: {integrity: sha512-O8ScvKtnxkp8kL9TpJTTKnMqlkZnS+QxwoQnJwPGBxjBbzd6OVVPEJ5/pMNrktSyXQD/chEfzfFzYLM6JANOOQ==} + + '@next/swc-darwin-arm64@15.2.4': + resolution: {integrity: sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.2.4': + resolution: {integrity: sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.2.4': + resolution: {integrity: sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.2.4': + resolution: {integrity: sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.2.4': + resolution: {integrity: sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.2.4': + resolution: {integrity: sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.2.4': + resolution: {integrity: sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.2.4': + resolution: {integrity: sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@pkgr/core@0.2.0': + resolution: {integrity: sha512-vsJDAkYR6qCPu+ioGScGiMYR7LvZYIXh/dlQeviqoTWNCVfKTLYD/LkNWH4Mxsv2a5vpIRc77FN5DnmK1eBggQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@radix-ui/primitive@1.1.1': + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + + '@radix-ui/react-arrow@1.1.2': + resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.2': + resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.1': + resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.6': + resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.0': + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.5': + resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.6': + resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.1': + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.2': + resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-label@2.1.2': + resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menu@2.1.6': + resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.2': + resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.4': + resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.2': + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.2': + resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.2': + resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.2': + resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.0': + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.0': + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/rect@1.1.0': + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + + '@schummar/icu-type-parser@1.21.5': + resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==} + + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tabler/icons-react@3.31.0': + resolution: {integrity: sha512-2rrCM5y/VnaVKnORpDdAua9SEGuJKVqPtWxeQ/vUVsgaUx30LDgBZph7/lterXxDY1IKR6NO//HDhWiifXTi3w==} + peerDependencies: + react: '>= 16' + + '@tabler/icons@3.31.0': + resolution: {integrity: sha512-dblAdeKY3+GA1U+Q9eziZ0ooVlZMHsE8dqP0RkwvRtEsAULoKOYaCUOcJ4oW1DjWegdxk++UAt2SlQVnmeHv+g==} + + '@tailwindcss/node@4.1.2': + resolution: {integrity: sha512-ZwFnxH+1z8Ehh8bNTMX3YFrYdzAv7JLY5X5X7XSFY+G9QGJVce/P9xb2mh+j5hKt8NceuHmdtllJvAHWKtsNrQ==} + + '@tailwindcss/oxide-android-arm64@4.1.2': + resolution: {integrity: sha512-IxkXbntHX8lwGmwURUj4xTr6nezHhLYqeiJeqa179eihGv99pRlKV1W69WByPJDQgSf4qfmwx904H6MkQqTA8w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.2': + resolution: {integrity: sha512-ZRtiHSnFYHb4jHKIdzxlFm6EDfijTCOT4qwUhJ3GWxfDoW2yT3z/y8xg0nE7e72unsmSj6dtfZ9Y5r75FIrlpA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.2': + resolution: {integrity: sha512-BiKUNZf1A0pBNzndBvnPnBxonCY49mgbOsPfILhcCE5RM7pQlRoOgN7QnwNhY284bDbfQSEOWnFR0zbPo6IDTw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.2': + resolution: {integrity: sha512-Z30VcpUfRGkiddj4l5NRCpzbSGjhmmklVoqkVQdkEC0MOelpY+fJrVhzSaXHmWrmSvnX8yiaEqAbdDScjVujYQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.2': + resolution: {integrity: sha512-w3wsK1ChOLeQ3gFOiwabtWU5e8fY3P1Ss8jR3IFIn/V0va3ir//hZ8AwURveS4oK1Pu6b8i+yxesT4qWnLVUow==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.2': + resolution: {integrity: sha512-oY/u+xJHpndTj7B5XwtmXGk8mQ1KALMfhjWMMpE8pdVAznjJsF5KkCceJ4Fmn5lS1nHMCwZum5M3/KzdmwDMdw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.2': + resolution: {integrity: sha512-k7G6vcRK/D+JOWqnKzKN/yQq1q4dCkI49fMoLcfs2pVcaUAXEqCP9NmA8Jv+XahBv5DtDjSAY3HJbjosEdKczg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.2': + resolution: {integrity: sha512-fLL+c678TkYKgkDLLNxSjPPK/SzTec7q/E5pTwvpTqrth867dftV4ezRyhPM5PaiCqX651Y8Yk0wRQMcWUGnmQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.2': + resolution: {integrity: sha512-0tU1Vjd1WucZ2ooq6y4nI9xyTSaH2g338bhrqk+2yzkMHskBm+pMsOCfY7nEIvALkA1PKPOycR4YVdlV7Czo+A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.2': + resolution: {integrity: sha512-r8QaMo3QKiHqUcn+vXYCypCEha+R0sfYxmaZSgZshx9NfkY+CHz91aS2xwNV/E4dmUDkTPUag7sSdiCHPzFVTg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.2': + resolution: {integrity: sha512-lYCdkPxh9JRHXoBsPE8Pu/mppUsC2xihYArNAESub41PKhHTnvn6++5RpmFM+GLSt3ewyS8fwCVvht7ulWm6cw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.2': + resolution: {integrity: sha512-Zwz//1QKo6+KqnCKMT7lA4bspGfwEgcPAHlSthmahtgrpKDfwRGk8PKQrW8Zg/ofCDIlg6EtjSTKSxxSufC+CQ==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.2': + resolution: {integrity: sha512-vgkMo6QRhG6uv97im6Y4ExDdq71y9v2IGZc+0wn7lauQFYJM/1KdUVhrOkexbUso8tUsMOWALxyHVkQEbsM7gw==} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} + + '@types/react-dom@19.1.1': + resolution: {integrity: sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w==} + peerDependencies: + '@types/react': ^19.0.0 + + '@types/react@19.1.0': + resolution: {integrity: sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==} + + '@typescript-eslint/eslint-plugin@8.29.0': + resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/parser@8.29.0': + resolution: {integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/scope-manager@8.29.0': + resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.29.0': + resolution: {integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/types@8.29.0': + resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.29.0': + resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/utils@8.29.0': + resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/visitor-keys@8.29.0': + resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-darwin-arm64@1.3.3': + resolution: {integrity: sha512-EpRILdWr3/xDa/7MoyfO7JuBIJqpBMphtu4+80BK1bRfFcniVT74h3Z7q1+WOc92FuIAYatB1vn9TJR67sORGw==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.3.3': + resolution: {integrity: sha512-ntj/g7lPyqwinMJWZ+DKHBse8HhVxswGTmNgFKJtdgGub3M3zp5BSZ3bvMP+kBT6dnYJLSVlDqdwOq1P8i0+/g==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.3.3': + resolution: {integrity: sha512-l6BT8f2CU821EW7U8hSUK8XPq4bmyTlt9Mn4ERrfjJNoCw0/JoHAh9amZZtV3cwC3bwwIat+GUnrcHTG9+qixw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.3.3': + resolution: {integrity: sha512-8ScEc5a4y7oE2BonRvzJ+2GSkBaYWyh0/Ko4Q25e/ix6ANpJNhwEPZvCR6GVRmsQAYMIfQvYLdM6YEN+qRjnAQ==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.3.3': + resolution: {integrity: sha512-8qQ6l1VTzLNd3xb2IEXISOKwMGXDCzY/UNy/7SovFW2Sp0K3YbL7Ao7R18v6SQkLqQlhhqSBIFRk+u6+qu5R5A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.3.3': + resolution: {integrity: sha512-v81R2wjqcWXJlQY23byqYHt9221h4anQ6wwN64oMD/WAE+FmxPHFZee5bhRkNVtzqO/q7wki33VFWlhiADwUeQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.3.3': + resolution: {integrity: sha512-cAOx/j0u5coMg4oct/BwMzvWJdVciVauUvsd+GQB/1FZYKQZmqPy0EjJzJGbVzFc6gbnfEcSqvQE6gvbGf2N8Q==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.3.3': + resolution: {integrity: sha512-mq2blqwErgDJD4gtFDlTX/HZ7lNP8YCHYFij2gkXPtMzrXxPW1hOtxL6xg4NWxvnj4bppppb0W3s/buvM55yfg==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.3.3': + resolution: {integrity: sha512-u0VRzfFYysarYHnztj2k2xr+eu9rmgoTUUgCCIT37Nr+j0A05Xk2c3RY8Mh5+DhCl2aYibihnaAEJHeR0UOFIQ==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.3.3': + resolution: {integrity: sha512-OrVo5ZsG29kBF0Ug95a2KidS16PqAMmQNozM6InbquOfW/udouk063e25JVLqIBhHLB2WyBnixOQ19tmeC/hIg==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.3.3': + resolution: {integrity: sha512-PYnmrwZ4HMp9SkrOhqPghY/aoL+Rtd4CQbr93GlrRTjK6kDzfMfgz3UH3jt6elrQAfupa1qyr1uXzeVmoEAxUA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.3.3': + resolution: {integrity: sha512-81AnQY6fShmktQw4hWDUIilsKSdvr/acdJ5azAreu2IWNlaJOKphJSsUVWE+yCk6kBMoQyG9ZHCb/krb5K0PEA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.3.3': + resolution: {integrity: sha512-X/42BMNw7cW6xrB9syuP5RusRnWGoq+IqvJO8IDpp/BZg64J1uuIW6qA/1Cl13Y4LyLXbJVYbYNSKwR/FiHEng==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.3.3': + resolution: {integrity: sha512-EGNnNGQxMU5aTN7js3ETYvuw882zcO+dsVjs+DwO2j/fRVKth87C8e2GzxW1L3+iWAXMyJhvFBKRavk9Og1Z6A==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.3.3': + resolution: {integrity: sha512-GraLbYqOJcmW1qY3osB+2YIiD62nVf2/bVLHZmrb4t/YSUwE03l7TwcDJl08T/Tm3SVhepX8RQkpzWbag/Sb4w==} + cpu: [x64] + os: [win32] + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.10.3: + resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + engines: {node: '>=4'} + + axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001710: + resolution: {integrity: sha512-B5C0I0UmaGqHgo5FuqJ7hBd4L57A4dDD+Xi+XX1nXOoxGeDdY4Ko38qJYOyqznBVJEqON5p8P1x5zRR3+rsnxA==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@15.2.4: + resolution: {integrity: sha512-v4gYjd4eYIme8qzaJItpR5MMBXJ0/YV07u7eb50kEnlEmX7yhOjdUdzz70v4fiINYRjLf8X8TbogF0k7wlz6sA==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.0: + resolution: {integrity: sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-prettier@5.2.6: + resolution: {integrity: sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.23.0: + resolution: {integrity: sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + framer-motion@12.6.3: + resolution: {integrity: sha512-2hsqknz23aloK85bzMc9nSR2/JP+fValQ459ZTVElFQ0xgwR2YqNjYSuDZdFBPOwVCt4Q9jgyTt6hg6sVOALzw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + intl-messageformat@10.7.16: + resolution: {integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-darwin-arm64@1.29.2: + resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.29.2: + resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.29.2: + resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.29.2: + resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.29.2: + resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.29.2: + resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.29.2: + resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.29.2: + resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.29.2: + resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.29.2: + resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.29.2: + resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lucide-react@0.487.0: + resolution: {integrity: sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + motion-dom@12.6.3: + resolution: {integrity: sha512-gRY08RjcnzgFYLemUZ1lo/e9RkBxR+6d4BRvoeZDSeArG4XQXERSPapKl3LNQRu22Sndjf1h+iavgY0O4NrYqA==} + + motion-utils@12.6.3: + resolution: {integrity: sha512-R/b3Ia2VxtTNZ4LTEO5pKYau1OUNHOuUfxuP0WFCTDYdHkeTBR9UtxR1cc8mDmKr8PEhmmfnTKGz3rSMjNRoRg==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + next-intl@4.0.2: + resolution: {integrity: sha512-3cKVflwdrqxCOvAL+DtGN68qR802i0PEj0dttkAD5IK5XxOjugQs4yU8aSakvPMbkOrhEJ+89z5lG2EAqi7Gkw==} + peerDependencies: + next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + next@15.2.4: + resolution: {integrity: sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + nookies@2.5.2: + resolution: {integrity: sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier-plugin-sort-json@4.1.1: + resolution: {integrity: sha512-uJ49wCzwJ/foKKV4tIPxqi4jFFvwUzw4oACMRG2dcmDhBKrxBv0L2wSKkAqHCmxKCvj0xcCZS4jO2kSJO/tRJw==} + engines: {node: '>=18.0.0'} + peerDependencies: + prettier: ^3.0.0 + + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-country-flag@3.1.0: + resolution: {integrity: sha512-JWQFw1efdv9sTC+TGQvTKXQg1NKbDU2mBiAiRWcKM9F1sK+/zjhP2yGmm8YDddWyZdXVkR8Md47rPMJmo4YO5g==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16' + + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 + + react-hook-form@7.55.0: + resolution: {integrity: sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.6.3: + resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + synckit@0.11.2: + resolution: {integrity: sha512-1IUffI8zZ8qUMB3NUJIjk0RpLroG/8NkQDAWH1NbB2iJ0/5pn3M8rxfNzMz4GH9OnYaGYn31LEDSXJp/qIlxgA==} + engines: {node: ^14.18.0 || >=16.0.0} + + tailwind-merge@3.1.0: + resolution: {integrity: sha512-aV27Oj8B7U/tAOMhJsSGdWqelfmudnGMdXIlMnk1JfsjwSjts6o8HyfN7SFH3EztzH4YH8kk6GbLTHzITJO39Q==} + + tailwindcss@4.1.2: + resolution: {integrity: sha512-VCsK+fitIbQF7JlxXaibFhxrPq4E2hDcG8apzHUdWFMCQWD8uLdlHg4iSkZ53cgLCCcZ+FZK7vG8VjvLcnBgKw==} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tw-animate-css@1.2.5: + resolution: {integrity: sha512-ABzjfgVo+fDbhRREGL4KQZUqqdPgvc5zVrLyeW9/6mVqvaDepXc7EvedA+pYmMnIOsUAQMwcWzNvom26J2qYvQ==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unrs-resolver@1.3.3: + resolution: {integrity: sha512-PFLAGQzYlyjniXdbmQ3dnGMZJXX5yrl2YS4DLRfR3BhgUsE1zpRIrccp9XMOGRfIHpdFvCn/nr5N1KMVda4x3A==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-intl@4.0.2: + resolution: {integrity: sha512-6RAP/5KJMRzLMLS25/BVh2u09cRK8S6HRGc1RnZvqR547qAKZCpjYylOqMPU9eNIirAiKoGmsoUPa7JrlaA/yg==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + + zustand@5.0.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/generator@7.27.0': + dependencies: + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.27.0': + dependencies: + '@babel/types': 7.27.0 + + '@babel/template@7.27.0': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + + '@babel/traverse@7.27.0': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.27.0 + '@babel/parser': 7.27.0 + '@babel/template': 7.27.0 + '@babel/types': 7.27.0 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.27.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@emnapi/core@1.4.0': + dependencies: + '@emnapi/wasi-threads': 1.0.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.5.1(eslint@9.23.0(jiti@2.4.2))': + dependencies: + eslint: 9.23.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.2': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.2.1': {} + + '@eslint/core@0.12.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/core@0.13.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.23.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.2.8': + dependencies: + '@eslint/core': 0.13.0 + levn: 0.4.1 + + '@floating-ui/core@1.6.9': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.6.13': + dependencies: + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/react-dom@2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/dom': 1.6.13 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + '@floating-ui/utils@0.2.9': {} + + '@formatjs/ecma402-abstract@2.3.4': + dependencies: + '@formatjs/fast-memoize': 2.2.7 + '@formatjs/intl-localematcher': 0.6.1 + decimal.js: 10.5.0 + tslib: 2.8.1 + + '@formatjs/fast-memoize@2.2.7': + dependencies: + tslib: 2.8.1 + + '@formatjs/icu-messageformat-parser@2.11.2': + dependencies: + '@formatjs/ecma402-abstract': 2.3.4 + '@formatjs/icu-skeleton-parser': 1.8.14 + tslib: 2.8.1 + + '@formatjs/icu-skeleton-parser@1.8.14': + dependencies: + '@formatjs/ecma402-abstract': 2.3.4 + tslib: 2.8.1 + + '@formatjs/intl-localematcher@0.5.10': + dependencies: + tslib: 2.8.1 + + '@formatjs/intl-localematcher@0.6.1': + dependencies: + tslib: 2.8.1 + + '@hookform/resolvers@5.0.1(react-hook-form@7.55.0(react@19.1.0))': + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.55.0(react@19.1.0) + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.2': {} + + '@ianvs/prettier-plugin-sort-imports@4.4.1(prettier@3.5.3)': + dependencies: + '@babel/generator': 7.27.0 + '@babel/parser': 7.27.0 + '@babel/traverse': 7.27.0 + '@babel/types': 7.27.0 + prettier: 3.5.3 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.4.0 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@napi-rs/wasm-runtime@0.2.8': + dependencies: + '@emnapi/core': 1.4.0 + '@emnapi/runtime': 1.4.0 + '@tybys/wasm-util': 0.9.0 + optional: true + + '@next/env@15.2.4': {} + + '@next/eslint-plugin-next@15.2.4': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@15.2.4': + optional: true + + '@next/swc-darwin-x64@15.2.4': + optional: true + + '@next/swc-linux-arm64-gnu@15.2.4': + optional: true + + '@next/swc-linux-arm64-musl@15.2.4': + optional: true + + '@next/swc-linux-x64-gnu@15.2.4': + optional: true + + '@next/swc-linux-x64-musl@15.2.4': + optional: true + + '@next/swc-win32-arm64-msvc@15.2.4': + optional: true + + '@next/swc-win32-x64-msvc@15.2.4': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@pkgr/core@0.2.0': {} + + '@radix-ui/primitive@1.1.1': {} + + '@radix-ui/react-arrow@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-collection@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-compose-refs@1.1.1(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-context@1.1.1(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-dialog@1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-direction@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-menu': 2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-focus-guards@1.1.1(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-id@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-label@2.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-menu@2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-popper@1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-rect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/rect': 1.1.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-portal@1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-presence@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-primitive@2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-slot@1.1.2(@types/react@19.1.0)(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-use-rect@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + '@radix-ui/rect': 1.1.0 + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-use-size@1.1.0(@types/react@19.1.0)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/rect@1.1.0': {} + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.11.0': {} + + '@schummar/icu-type-parser@1.21.5': {} + + '@standard-schema/utils@0.3.0': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tabler/icons-react@3.31.0(react@19.1.0)': + dependencies: + '@tabler/icons': 3.31.0 + react: 19.1.0 + + '@tabler/icons@3.31.0': {} + + '@tailwindcss/node@4.1.2': + dependencies: + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.29.2 + tailwindcss: 4.1.2 + + '@tailwindcss/oxide-android-arm64@4.1.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.2': + optional: true + + '@tailwindcss/oxide@4.1.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.2 + '@tailwindcss/oxide-darwin-arm64': 4.1.2 + '@tailwindcss/oxide-darwin-x64': 4.1.2 + '@tailwindcss/oxide-freebsd-x64': 4.1.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.2 + '@tailwindcss/oxide-linux-x64-musl': 4.1.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.2 + + '@tailwindcss/postcss@4.1.2': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.2 + '@tailwindcss/oxide': 4.1.2 + postcss: 8.5.3 + tailwindcss: 4.1.2 + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/estree@1.0.7': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node@22.14.0': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.1.1(@types/react@19.1.0)': + dependencies: + '@types/react': 19.1.0 + + '@types/react@19.1.0': + dependencies: + csstype: 3.1.3 + + '@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/type-utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.29.0 + eslint: 9.23.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.29.0 + debug: 4.4.0 + eslint: 9.23.0(jiti@2.4.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.29.0': + dependencies: + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 + + '@typescript-eslint/type-utils@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2) + '@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + debug: 4.4.0 + eslint: 9.23.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.29.0': {} + + '@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.2)': + dependencies: + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.29.0': + dependencies: + '@typescript-eslint/types': 8.29.0 + eslint-visitor-keys: 4.2.0 + + '@unrs/resolver-binding-darwin-arm64@1.3.3': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.3.3': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.3.3': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.3.3': + dependencies: + '@napi-rs/wasm-runtime': 0.2.8 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.3.3': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.3.3': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.3.3': + optional: true + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-hidden@1.2.4: + dependencies: + tslib: 2.8.1 + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} + + async-function@1.0.0: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.10.3: {} + + axios@1.8.4: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001710: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + client-only@0.0.1: {} + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + cookie@0.4.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decimal.js@10.5.0: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + detect-libc@2.0.3: {} + + detect-node-es@1.1.0: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + emoji-regex@9.2.2: {} + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + es-abstract@1.23.9: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escape-string-regexp@4.0.0: {} + + eslint-config-next@15.2.4(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2): + dependencies: + '@next/eslint-plugin-next': 15.2.4 + '@rushstack/eslint-patch': 1.11.0 + '@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.23.0(jiti@2.4.2)) + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)): + dependencies: + eslint: 9.23.0(jiti@2.4.2) + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.0 + eslint: 9.23.0(jiti@2.4.2) + get-tsconfig: 4.10.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.12 + unrs-resolver: 1.3.3 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.23.0(jiti@2.4.2)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.23.0(jiti@2.4.2) + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-prettier@5.2.6(eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)))(eslint@9.23.0(jiti@2.4.2))(prettier@3.5.3): + dependencies: + eslint: 9.23.0(jiti@2.4.2) + prettier: 3.5.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.2 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@9.23.0(jiti@2.4.2)) + + eslint-plugin-react-hooks@5.2.0(eslint@9.23.0(jiti@2.4.2)): + dependencies: + eslint: 9.23.0(jiti@2.4.2) + + eslint-plugin-react@7.37.5(eslint@9.23.0(jiti@2.4.2)): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.23.0(jiti@2.4.2) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.3.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.23.0(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/config-helpers': 0.2.1 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.23.0 + '@eslint/plugin-kit': 0.2.8 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + follow-redirects@1.15.9: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + framer-motion@12.6.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + motion-dom: 12.6.3 + motion-utils: 12.6.3 + tslib: 2.8.1 + optionalDependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + intl-messageformat@10.7.16: + dependencies: + '@formatjs/ecma402-abstract': 2.3.4 + '@formatjs/fast-memoize': 2.2.7 + '@formatjs/icu-messageformat-parser': 2.11.2 + tslib: 2.8.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.3.2: + optional: true + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.1 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jiti@2.4.2: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.29.2: + optional: true + + lightningcss-darwin-x64@1.29.2: + optional: true + + lightningcss-freebsd-x64@1.29.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.29.2: + optional: true + + lightningcss-linux-arm64-gnu@1.29.2: + optional: true + + lightningcss-linux-arm64-musl@1.29.2: + optional: true + + lightningcss-linux-x64-gnu@1.29.2: + optional: true + + lightningcss-linux-x64-musl@1.29.2: + optional: true + + lightningcss-win32-arm64-msvc@1.29.2: + optional: true + + lightningcss-win32-x64-msvc@1.29.2: + optional: true + + lightningcss@1.29.2: + dependencies: + detect-libc: 2.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.2 + lightningcss-darwin-x64: 1.29.2 + lightningcss-freebsd-x64: 1.29.2 + lightningcss-linux-arm-gnueabihf: 1.29.2 + lightningcss-linux-arm64-gnu: 1.29.2 + lightningcss-linux-arm64-musl: 1.29.2 + lightningcss-linux-x64-gnu: 1.29.2 + lightningcss-linux-x64-musl: 1.29.2 + lightningcss-win32-arm64-msvc: 1.29.2 + lightningcss-win32-x64-msvc: 1.29.2 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lucide-react@0.487.0(react@19.1.0): + dependencies: + react: 19.1.0 + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + motion-dom@12.6.3: + dependencies: + motion-utils: 12.6.3 + + motion-utils@12.6.3: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + negotiator@1.0.0: {} + + next-intl@4.0.2(next@15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.2): + dependencies: + '@formatjs/intl-localematcher': 0.5.10 + negotiator: 1.0.0 + next: 15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + use-intl: 4.0.2(react@19.1.0) + optionalDependencies: + typescript: 5.8.2 + + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + next@15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@next/env': 15.2.4 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001710 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.2.4 + '@next/swc-darwin-x64': 15.2.4 + '@next/swc-linux-arm64-gnu': 15.2.4 + '@next/swc-linux-arm64-musl': 15.2.4 + '@next/swc-linux-x64-gnu': 15.2.4 + '@next/swc-linux-x64-musl': 15.2.4 + '@next/swc-win32-arm64-msvc': 15.2.4 + '@next/swc-win32-x64-msvc': 15.2.4 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + nookies@2.5.2: + dependencies: + cookie: 0.4.2 + set-cookie-parser: 2.7.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-sort-json@4.1.1(prettier@3.5.3): + dependencies: + prettier: 3.5.3 + + prettier@3.5.3: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-country-flag@3.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-hook-form@7.55.0(react@19.1.0): + dependencies: + react: 19.1.0 + + react-is@16.13.1: {} + + react-remove-scroll-bar@2.3.8(@types/react@19.1.0)(react@19.1.0): + dependencies: + react: 19.1.0 + react-style-singleton: 2.2.3(@types/react@19.1.0)(react@19.1.0) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.0 + + react-remove-scroll@2.6.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + react: 19.1.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.0)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.0)(react@19.1.0) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.0)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + + react-style-singleton@2.2.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + get-nonce: 1.0.1 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.0 + + react@19.1.0: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + scheduler@0.26.0: {} + + semver@6.3.1: {} + + semver@7.7.1: {} + + set-cookie-parser@2.7.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + + source-map-js@1.2.1: {} + + stable-hash@0.0.5: {} + + streamsearch@1.1.0: {} + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.6(react@19.1.0): + dependencies: + client-only: 0.0.1 + react: 19.1.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.11.2: + dependencies: + '@pkgr/core': 0.2.0 + tslib: 2.8.1 + + tailwind-merge@3.1.0: {} + + tailwindcss@4.1.2: {} + + tapable@2.2.1: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.1.0(typescript@5.8.2): + dependencies: + typescript: 5.8.2 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + tw-animate-css@1.2.5: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@5.8.2: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + + unrs-resolver@1.3.3: + optionalDependencies: + '@unrs/resolver-binding-darwin-arm64': 1.3.3 + '@unrs/resolver-binding-darwin-x64': 1.3.3 + '@unrs/resolver-binding-freebsd-x64': 1.3.3 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.3.3 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.3.3 + '@unrs/resolver-binding-linux-arm64-gnu': 1.3.3 + '@unrs/resolver-binding-linux-arm64-musl': 1.3.3 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.3.3 + '@unrs/resolver-binding-linux-s390x-gnu': 1.3.3 + '@unrs/resolver-binding-linux-x64-gnu': 1.3.3 + '@unrs/resolver-binding-linux-x64-musl': 1.3.3 + '@unrs/resolver-binding-wasm32-wasi': 1.3.3 + '@unrs/resolver-binding-win32-arm64-msvc': 1.3.3 + '@unrs/resolver-binding-win32-ia32-msvc': 1.3.3 + '@unrs/resolver-binding-win32-x64-msvc': 1.3.3 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.0 + + use-intl@4.0.2(react@19.1.0): + dependencies: + '@formatjs/fast-memoize': 2.2.7 + '@schummar/icu-type-parser': 1.21.5 + intl-messageformat: 10.7.16 + react: 19.1.0 + + use-sidecar@1.1.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.0 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yocto-queue@0.1.0: {} + + zod@3.24.2: {} + + zustand@5.0.3(@types/react@19.1.0)(react@19.1.0): + optionalDependencies: + '@types/react': 19.1.0 + react: 19.1.0 diff --git a/apps/app/postcss.config.mjs b/apps/app/postcss.config.mjs new file mode 100644 index 0000000..c7bcb4b --- /dev/null +++ b/apps/app/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/apps/app/public/file.svg b/apps/app/public/file.svg new file mode 100644 index 0000000..004145c --- /dev/null +++ b/apps/app/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/app/public/globe.svg b/apps/app/public/globe.svg new file mode 100644 index 0000000..567f17b --- /dev/null +++ b/apps/app/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/app/public/next.svg b/apps/app/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/apps/app/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/app/public/vercel.svg b/apps/app/public/vercel.svg new file mode 100644 index 0000000..7705396 --- /dev/null +++ b/apps/app/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/app/public/window.svg b/apps/app/public/window.svg new file mode 100644 index 0000000..b2b2a44 --- /dev/null +++ b/apps/app/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/app/src/app/(home)/components/home-content.tsx b/apps/app/src/app/(home)/components/home-content.tsx new file mode 100644 index 0000000..7cb3745 --- /dev/null +++ b/apps/app/src/app/(home)/components/home-content.tsx @@ -0,0 +1,75 @@ +import Link from "next/link"; +import { IconBrandGithubFilled } from "@tabler/icons-react"; +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { siteConfig } from "@/config/site"; +import { HomeContentProps } from "../types"; +import { BackgroundLights } from "../../../components/ui/background-lights"; +import { HomeHeader } from "./home-header"; + +const fadeInAnimation = { + animate: { opacity: 1 }, + initial: { opacity: 0 }, + transition: { duration: 0.5 } +}; + +const fadeInUpAnimation = { + animate: { opacity: 1, y: 0 }, + initial: { opacity: 0, y: 20 }, + transition: { duration: 0.5 } +}; + +function ActionButtons({ t }: { t: (key: string) => string }) { + return ( +
+ + +
+ ); +} + +export function HomeContent({ isLoading }: HomeContentProps) { + const t = useTranslations(); + + if (isLoading) { + return null; + } + + return ( +
+ +
+ + + {t("home.description")} + + + + +

+ {t("home.privacyMessage")} +

+
+
+
+ ); +} diff --git a/apps/app/src/app/(home)/components/home-header.tsx b/apps/app/src/app/(home)/components/home-header.tsx new file mode 100644 index 0000000..80bb234 --- /dev/null +++ b/apps/app/src/app/(home)/components/home-header.tsx @@ -0,0 +1,56 @@ +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; + +import { HomeHeaderProps } from "../types"; + +const fadeInUpAnimation = { + animate: { opacity: 1, y: 0 }, + initial: { opacity: 0, y: 20 }, + transition: { duration: 0.5 } +}; + +const titleAnimation = { + animate: { scale: 1 }, + initial: { scale: 0.9 }, + transition: { duration: 0.3 } +}; + +const slideInAnimation = (delay: number, direction: -1 | 1) => ({ + animate: { opacity: 1, x: 0 }, + initial: { opacity: 0, x: 20 * direction }, + transition: { delay, duration: 0.5 } +}); + +export function HomeHeader({ title }: HomeHeaderProps) { + const t = useTranslations(); + + return ( + +
+ + {title} + +
+ + {t("home.header.fileSharing")} + + + {t("home.header.tagline")} + +
+
+
+ ); +} diff --git a/apps/app/src/app/(home)/components/navbar.tsx b/apps/app/src/app/(home)/components/navbar.tsx new file mode 100644 index 0000000..6eba342 --- /dev/null +++ b/apps/app/src/app/(home)/components/navbar.tsx @@ -0,0 +1,92 @@ +"use client"; + +import { useEffect } from "react"; +import { useState } from "react"; +import Link from "next/link"; +import { IconHeart, IconMenu2 } from "@tabler/icons-react"; + +import { LanguageSwitcher } from "@/components/general/language-switcher"; +import { ModeToggle } from "@/components/mode-toggle"; +import { Button } from "@/components/ui/button"; +import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"; +import { siteConfig } from "@/config/site"; +import { useAppInfo } from "@/contexts/app-info-context"; +import { cn } from "@/lib/utils"; + +export function Navbar() { + const { appName, appLogo, refreshAppInfo } = useAppInfo(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + + useEffect(() => { + refreshAppInfo(); + }, [refreshAppInfo]); + + return ( +
+
+
+
+ + {appLogo && App Logo} +

{appName}

+ + +
+
+ + + + +
+ +
+ + + + + + + +
+
+ {siteConfig.navMenuItems.map((item, index) => ( + setIsMenuOpen(false)} + > + {item.label} + + ))} +
+
+
+
+
+
+
+
+ ); +} diff --git a/apps/app/src/app/(home)/hooks/use-home.ts b/apps/app/src/app/(home)/hooks/use-home.ts new file mode 100644 index 0000000..466d80e --- /dev/null +++ b/apps/app/src/app/(home)/hooks/use-home.ts @@ -0,0 +1,52 @@ +"use client"; + +import { useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { create } from 'zustand'; +import { getAllConfigs } from "@/http/endpoints"; + +interface Config { + key: string; + value: string; +} + +interface HomeStore { + isLoading: boolean; + checkHomePageAccess: () => Promise; +} + +const useHomeStore = create((set) => ({ + isLoading: true, + checkHomePageAccess: async () => { + try { + const response = await getAllConfigs(); + const showHomePage = response.data.configs.find( + (config: Config) => config.key === "showHomePage" + )?.value === "true"; + + set({ isLoading: false }); + return showHomePage; + } catch (error) { + console.error("Failed to check homepage access:", error); + set({ isLoading: false }); + return false; + } + } +})); + +export function useHome() { + const router = useRouter(); + const { isLoading, checkHomePageAccess } = useHomeStore(); + + useEffect(() => { + checkHomePageAccess().then(hasAccess => { + if (!hasAccess) { + router.push("/login"); + } + }); + }, [router, checkHomePageAccess]); + + return { + isLoading, + }; +} diff --git a/apps/app/src/app/(home)/layout.tsx b/apps/app/src/app/(home)/layout.tsx new file mode 100644 index 0000000..de78e02 --- /dev/null +++ b/apps/app/src/app/(home)/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from 'next' +import { getTranslations } from 'next-intl/server' + +export async function generateMetadata(): Promise { + const t = await getTranslations() + + return { + title: t('home.pageTitle'), + } +} + +export default function HomeLayout({ + children, +}: { + children: React.ReactNode +}) { + return <>{children} +} \ No newline at end of file diff --git a/apps/app/src/app/(home)/page.tsx b/apps/app/src/app/(home)/page.tsx new file mode 100644 index 0000000..32f0a1c --- /dev/null +++ b/apps/app/src/app/(home)/page.tsx @@ -0,0 +1,23 @@ +"use client"; + +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { HomeContent } from "./components/home-content"; +import { Navbar } from "./components/navbar"; +import { useHome } from "./hooks/use-home"; + +export default function HomePage() { + const { isLoading } = useHome(); + + if (isLoading) { + return ; + } + + return ( +
+ + + +
+ ); +} diff --git a/apps/app/src/app/(home)/types/index.ts b/apps/app/src/app/(home)/types/index.ts new file mode 100644 index 0000000..9c7f811 --- /dev/null +++ b/apps/app/src/app/(home)/types/index.ts @@ -0,0 +1,7 @@ +export interface HomeContentProps { + isLoading: boolean; +} + +export interface HomeHeaderProps { + title: string; +} diff --git a/apps/app/src/app/favicon.ico b/apps/app/src/app/favicon.ico new file mode 100644 index 0000000..1dffba3 Binary files /dev/null and b/apps/app/src/app/favicon.ico differ diff --git a/apps/app/src/app/globals.css b/apps/app/src/app/globals.css new file mode 100644 index 0000000..1b20c10 --- /dev/null +++ b/apps/app/src/app/globals.css @@ -0,0 +1,122 @@ +@import "tailwindcss"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); +} + +:root { + --radius: 0.75rem; + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.723 0.219 149.579); + --primary-foreground: oklch(0.982 0.018 155.826); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.723 0.219 149.579); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: oklch(0.723 0.219 149.579); + --sidebar-primary-foreground: oklch(0.982 0.018 155.826); + --sidebar-accent: oklch(0.967 0.001 286.375); + --sidebar-accent-foreground: oklch(0.21 0.006 285.885); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: oklch(0.723 0.219 149.579); +} + +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.696 0.17 162.48); + --primary-foreground: oklch(0.393 0.095 152.535); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.527 0.154 150.069); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.696 0.17 162.48); + --sidebar-primary-foreground: oklch(0.393 0.095 152.535); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.527 0.154 150.069); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/apps/app/src/app/layout.tsx b/apps/app/src/app/layout.tsx new file mode 100644 index 0000000..9b9c1ec --- /dev/null +++ b/apps/app/src/app/layout.tsx @@ -0,0 +1,52 @@ +import type { Metadata } from "next"; +import { Geist, Geist_Mono } from "next/font/google"; +import { NextIntlClientProvider } from "next-intl"; +import { getLocale } from "next-intl/server"; + +import "./globals.css"; + +import { useAppInfo } from "@/contexts/app-info-context"; +import { ThemeProvider } from "../providers/theme-provider"; +import { AuthProvider } from "@/contexts/auth-context"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +// !TODO: CHANGE METADATA BASED ON API RESPONSE +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default async function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + const locale = await getLocale(); + + if (typeof window !== 'undefined') { + useAppInfo.getState().refreshAppInfo(); + } + + return ( + + + + + + {children} + + + + + + ); +} diff --git a/apps/app/src/app/login/components/login-form.tsx b/apps/app/src/app/login/components/login-form.tsx new file mode 100644 index 0000000..f5b5417 --- /dev/null +++ b/apps/app/src/app/login/components/login-form.tsx @@ -0,0 +1,112 @@ +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import Link from "next/link"; +import { useTranslations } from "next-intl"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { createLoginSchema, type LoginFormValues } from "../schemas/schema"; +import { PasswordVisibilityToggle } from "./password-visibility-toggle"; + +interface LoginFormProps { + error?: string; + isVisible: boolean; + onToggleVisibility: () => void; + onSubmit: (data: LoginFormValues) => Promise; +} + +export function LoginForm({ error, isVisible, onToggleVisibility, onSubmit }: LoginFormProps) { + const t = useTranslations(); + const loginSchema = createLoginSchema(t); + const form = useForm({ + resolver: zodResolver(loginSchema), + defaultValues: { + email: "", + password: "", + }, + }); + + const isSubmitting = form.formState.isSubmitting; + + const renderErrorMessage = () => ( + error && ( +

+ {error.replace('errors.', '')} +

+ ) + ); + + const renderEmailField = () => ( + ( + + {t("login.emailLabel")} + + + + + + )} + /> + ); + + const renderPasswordField = () => ( + ( + + {t("login.passwordLabel")} + +
+ + +
+
+ +
+ )} + /> + ); + + return ( + <> + {renderErrorMessage()} +
+ + {renderEmailField()} + {renderPasswordField()} + +
+ + +
+ + {t("login.forgotPassword")} + +
+ + ); +} diff --git a/apps/app/src/app/login/components/login-header.tsx b/apps/app/src/app/login/components/login-header.tsx new file mode 100644 index 0000000..6cd3dac --- /dev/null +++ b/apps/app/src/app/login/components/login-header.tsx @@ -0,0 +1,26 @@ +import { useAppInfo } from "@/contexts/app-info-context"; +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; +import { useEffect } from "react"; + + +export function LoginHeader() { + const t = useTranslations(); + const { appName, refreshAppInfo } = useAppInfo(); + + useEffect(() => { + refreshAppInfo(); + }, [refreshAppInfo]); + + return ( + +

{t("login.welcome")} {appName}

+

{t("login.signInToContinue")}

+
+ ); +} diff --git a/apps/app/src/app/login/components/password-visibility-toggle.tsx b/apps/app/src/app/login/components/password-visibility-toggle.tsx new file mode 100644 index 0000000..19a95eb --- /dev/null +++ b/apps/app/src/app/login/components/password-visibility-toggle.tsx @@ -0,0 +1,24 @@ +import { Button } from "@/components/ui/button"; +import { IconEye, IconEyeClosed } from "@tabler/icons-react"; + +interface PasswordVisibilityToggleProps { + isVisible: boolean; + onToggle: () => void; +} + +export function PasswordVisibilityToggle({ isVisible, onToggle }: PasswordVisibilityToggleProps) { + return ( + + ); +} \ No newline at end of file diff --git a/apps/app/src/app/login/components/static-background-lights.tsx b/apps/app/src/app/login/components/static-background-lights.tsx new file mode 100644 index 0000000..5454892 --- /dev/null +++ b/apps/app/src/app/login/components/static-background-lights.tsx @@ -0,0 +1,8 @@ +export const StaticBackgroundLights = () => { + return ( +
+
+
+
+ ); +}; diff --git a/apps/app/src/app/login/hooks/use-login.ts b/apps/app/src/app/login/hooks/use-login.ts new file mode 100644 index 0000000..ce514b1 --- /dev/null +++ b/apps/app/src/app/login/hooks/use-login.ts @@ -0,0 +1,77 @@ +"use client" + +import { useAuth } from "@/contexts/auth-context"; +import { login, getCurrentUser } from "@/http/endpoints"; +import { useRouter } from "next/navigation"; +import { useState, useEffect } from "react"; +import axios from "axios"; +import { useTranslations } from "next-intl"; +import { LoginFormValues } from "../schemas/schema"; + +export function useLogin() { + const router = useRouter(); + const t = useTranslations(); + const { isAuthenticated, setUser, setIsAdmin, setIsAuthenticated } = useAuth(); + const [isVisible, setIsVisible] = useState(false); + const [error, setError] = useState(); + const [isInitialized, setIsInitialized] = useState(false); + + useEffect(() => { + const checkAuth = async () => { + try { + const userResponse = await getCurrentUser(); + if (!userResponse?.data?.user) { + throw new Error("No user data"); + } + + const { isAdmin, ...userData } = userResponse.data.user; + setUser(userData); + setIsAdmin(isAdmin); + setIsAuthenticated(true); + router.push("/dashboard"); + } catch (err) { + setUser(null); + setIsAdmin(false); + setIsAuthenticated(false); + } finally { + setIsInitialized(true); + } + }; + + checkAuth(); + }, [router, setUser, setIsAdmin, setIsAuthenticated]); + + const toggleVisibility = () => setIsVisible(!isVisible); + + const onSubmit = async (data: LoginFormValues) => { + setError(undefined); + + try { + await login(data); + const userResponse = await getCurrentUser(); + const { isAdmin, ...userData } = userResponse.data.user; + + setUser(userData); + setIsAdmin(isAdmin); + setIsAuthenticated(true); + router.replace("/dashboard"); + } catch (err) { + if (axios.isAxiosError(err) && err.response?.data?.error) { + setError(t(`errors.${err.response.data.error}`)); + } else { + setError(t("errors.unexpectedError")); + } + setIsAuthenticated(false); + setUser(null); + setIsAdmin(false); + } + }; + + return { + isAuthenticated: !isInitialized ? null : isAuthenticated, + error, + isVisible, + toggleVisibility, + onSubmit, + }; +} diff --git a/apps/app/src/app/login/layout.tsx b/apps/app/src/app/login/layout.tsx new file mode 100644 index 0000000..3aca780 --- /dev/null +++ b/apps/app/src/app/login/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from 'next' +import { getTranslations } from 'next-intl/server' + +interface LayoutProps { + children: React.ReactNode +} + +export async function generateMetadata(): Promise { + const translate = await getTranslations() + + return { + title: translate('login.pageTitle'), + } +} + +export default function LoginLayout({ children }: LayoutProps) { + return <>{children} +} \ No newline at end of file diff --git a/apps/app/src/app/login/page.tsx b/apps/app/src/app/login/page.tsx new file mode 100644 index 0000000..7a01178 --- /dev/null +++ b/apps/app/src/app/login/page.tsx @@ -0,0 +1,47 @@ +"use client" + +import { LoginForm } from "./components/login-form"; +import { LoginHeader } from "./components/login-header"; +import { StaticBackgroundLights } from "./components/static-background-lights"; +import { useLogin } from "./hooks/use-login"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { motion } from "framer-motion"; +import { LanguageSwitcher } from "@/components/general/language-switcher"; + +export default function LoginPage() { + const login = useLogin(); + + if (login.isAuthenticated === null) { + return ; + } + + return ( +
+
+ +
+ +
+ +
+ + + + +
+
+ +
+ ); +} diff --git a/apps/app/src/app/login/schemas/schema.ts b/apps/app/src/app/login/schemas/schema.ts new file mode 100644 index 0000000..310b0a5 --- /dev/null +++ b/apps/app/src/app/login/schemas/schema.ts @@ -0,0 +1,17 @@ +import * as z from "zod"; +import { useTranslations } from "next-intl"; + +type TFunction = ReturnType; + +export const createLoginSchema = (t: TFunction) => + z.object({ + email: z + .string() + .min(1, t("validation.emailRequired")) + .email(t("validation.invalidEmail")), + password: z + .string() + .min(1, t("validation.passwordRequired")) + }); + +export type LoginFormValues = z.infer>; \ No newline at end of file diff --git a/apps/app/src/app/login/types/index.ts b/apps/app/src/app/login/types/index.ts new file mode 100644 index 0000000..d98fa6f --- /dev/null +++ b/apps/app/src/app/login/types/index.ts @@ -0,0 +1,10 @@ +import { LoginFormData } from "../hooks/use-login"; +import { UseFormReturn } from "react-hook-form"; + +export interface LoginFormProps { + form: UseFormReturn; + error: string | null; + isVisible: boolean; + onToggleVisibility: () => void; + onSubmit: (data: LoginFormData) => Promise; +} diff --git a/apps/app/src/components/general/language-switcher.tsx b/apps/app/src/components/general/language-switcher.tsx new file mode 100644 index 0000000..8e29db0 --- /dev/null +++ b/apps/app/src/components/general/language-switcher.tsx @@ -0,0 +1,82 @@ +import { useRouter } from "next/navigation"; +import { IconLanguage } from "@tabler/icons-react"; +import { useLocale } from "next-intl"; +import { setCookie } from "nookies"; +import ReactCountryFlag from "react-country-flag"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +const languages = { + "en-US": "English", + "pt-BR": "Português", + "fr-FR": "Français", + "es-ES": "Español", + "de-DE": "Deutsch", + "tr-TR": "Türkçe (Turkish)", + "ru-RU": "Русский (Russian)", + "hi-IN": "हिन्दी (Hindi)", + "ar-SA": "العربية (Arabic)", + "zh-CN": "中文 (Chinese)", + "ja-JP": "日本語 (Japanese)", + "ko-KR": "한국어 (Korean)", +}; + +const COOKIE_LANG_KEY = "NEXT_LOCALE"; +const COOKIE_MAX_AGE = 365 * 24 * 60 * 60; + +export function LanguageSwitcher() { + const locale = useLocale(); + const router = useRouter(); + + const changeLanguage = (fullLocale: string) => { + setCookie(null, COOKIE_LANG_KEY, fullLocale, { + maxAge: COOKIE_MAX_AGE, + path: "/", + sameSite: "lax", + secure: process.env.NODE_ENV === "production", + }); + + router.refresh(); + }; + + return ( + + + + + + {Object.entries(languages).map(([code, name]) => { + const isCurrentLocale = locale === code.split("-")[0]; + + return ( + changeLanguage(code)} + className={isCurrentLocale ? "bg-accent" : ""} + > + + {name} + + ); + })} + + + ); +} diff --git a/apps/app/src/components/layout/loading-screen.tsx b/apps/app/src/components/layout/loading-screen.tsx new file mode 100644 index 0000000..cc8cf32 --- /dev/null +++ b/apps/app/src/components/layout/loading-screen.tsx @@ -0,0 +1,27 @@ +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; + +import { BackgroundLights } from "@/components/ui/background-lights"; + +export function LoadingScreen() { + const t = useTranslations(); + + return ( +
+ +
+ + {t("common.loading")} + +
+
+ ); +} diff --git a/apps/app/src/components/mode-toggle.tsx b/apps/app/src/components/mode-toggle.tsx new file mode 100644 index 0000000..7742e26 --- /dev/null +++ b/apps/app/src/components/mode-toggle.tsx @@ -0,0 +1,35 @@ +// !!TODO: ADD TRANSLATION SUPPORT FOR THESE BUTTONS +"use client"; + +import * as React from "react"; +import { IconMoon, IconSun } from "@tabler/icons-react"; +import { useTheme } from "next-themes"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +export function ModeToggle() { + const { setTheme } = useTheme(); + + return ( + + + + + + setTheme("light")}>Light + setTheme("dark")}>Dark + setTheme("system")}>System + + + ); +} diff --git a/apps/app/src/components/ui/background-lights.tsx b/apps/app/src/components/ui/background-lights.tsx new file mode 100644 index 0000000..c4fdae0 --- /dev/null +++ b/apps/app/src/components/ui/background-lights.tsx @@ -0,0 +1,33 @@ +import { motion } from "framer-motion"; + +export function BackgroundLights() { + return ( +
+ + +
+ ); +} diff --git a/apps/app/src/components/ui/button.tsx b/apps/app/src/components/ui/button.tsx new file mode 100644 index 0000000..a2df8dc --- /dev/null +++ b/apps/app/src/components/ui/button.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", + destructive: + "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean + }) { + const Comp = asChild ? Slot : "button" + + return ( + + ) +} + +export { Button, buttonVariants } diff --git a/apps/app/src/components/ui/default-footer.tsx b/apps/app/src/components/ui/default-footer.tsx new file mode 100644 index 0000000..bbbff7a --- /dev/null +++ b/apps/app/src/components/ui/default-footer.tsx @@ -0,0 +1,25 @@ +import Link from "next/link"; +import { useTranslations } from "next-intl"; + +import { version } from "../../../package.json"; + +export function DefaultFooter() { + const t = useTranslations(); + + return ( +
+
+ + {t("footer.poweredBy")} +

Kyantech Solutions

+ + v{version}-beta +
+
+ ); +} diff --git a/apps/app/src/components/ui/dropdown-menu.tsx b/apps/app/src/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..ec51e9c --- /dev/null +++ b/apps/app/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,257 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function DropdownMenu({ + ...props +}: React.ComponentProps) { + return +} + +function DropdownMenuPortal({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuContent({ + className, + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +function DropdownMenuGroup({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuItem({ + className, + inset, + variant = "default", + ...props +}: React.ComponentProps & { + inset?: boolean + variant?: "default" | "destructive" +}) { + return ( + + ) +} + +function DropdownMenuCheckboxItem({ + className, + children, + checked, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuRadioGroup({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuRadioItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuLabel({ + className, + inset, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + ) +} + +function DropdownMenuSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +function DropdownMenuSub({ + ...props +}: React.ComponentProps) { + return +} + +function DropdownMenuSubTrigger({ + className, + inset, + children, + ...props +}: React.ComponentProps & { + inset?: boolean +}) { + return ( + + {children} + + + ) +} + +function DropdownMenuSubContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + DropdownMenu, + DropdownMenuPortal, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuLabel, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, +} diff --git a/apps/app/src/components/ui/form.tsx b/apps/app/src/components/ui/form.tsx new file mode 100644 index 0000000..cf27f75 --- /dev/null +++ b/apps/app/src/components/ui/form.tsx @@ -0,0 +1,167 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { Slot } from "@radix-ui/react-slot" +import { + Controller, + FormProvider, + useFormContext, + useFormState, + type ControllerProps, + type FieldPath, + type FieldValues, +} from "react-hook-form" + +import { cn } from "@/lib/utils" +import { Label } from "@/components/ui/label" + +const Form = FormProvider + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +> = { + name: TName +} + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +) + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +>({ + ...props +}: ControllerProps) => { + return ( + + + + ) +} + +const useFormField = () => { + const fieldContext = React.useContext(FormFieldContext) + const itemContext = React.useContext(FormItemContext) + const { getFieldState } = useFormContext() + const formState = useFormState({ name: fieldContext.name }) + const fieldState = getFieldState(fieldContext.name, formState) + + if (!fieldContext) { + throw new Error("useFormField should be used within ") + } + + const { id } = itemContext + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} + +type FormItemContextValue = { + id: string +} + +const FormItemContext = React.createContext( + {} as FormItemContextValue +) + +function FormItem({ className, ...props }: React.ComponentProps<"div">) { + const id = React.useId() + + return ( + +
+ + ) +} + +function FormLabel({ + className, + ...props +}: React.ComponentProps) { + const { error, formItemId } = useFormField() + + return ( +